/* * Copyright (C) 2011 Andrea Schweer * * This file is part of the Digital Parrot. * * The Digital Parrot is free software; you can redistribute it and/or modify * it under the terms of the Eclipse Public License as published by the Eclipse * Foundation or its Agreement Steward, either version 1.0 of the License, or * (at your option) any later version. * * The Digital Parrot is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License for * more details. * * You should have received a copy of the Eclipse Public License along with the * Digital Parrot. If not, see http://www.eclipse.org/legal/epl-v10.html. * */ package net.schweerelos.parrot.ui; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.RowSorter.SortKey; import javax.swing.table.DefaultTableCellRenderer; import net.schweerelos.parrot.model.NodeWrapper; import net.schweerelos.parrot.model.ParrotModel; public class NodeWrapperRenderer extends DefaultTableCellRenderer { private static final Color COLOR_HERE_TOO_SELECTED_BORDER = UIConstants.ACCENT_MEDIUM; private static final Color COLOR_HIGHLIGHTED_BORDER = UIConstants.ENVIRONMENT_SHADOW_DARK; private static final Color COLOR_ODD_ROW_UNSELECTED_BG = UIConstants.ENVIRONMENT_LIGHTEST; private static final Color COLOR_EVEN_ROW_UNSELECTED_BG = Color.WHITE; private static final Color COLOR_SELECTED_BG = UIConstants.ACCENT_LIGHT; private static final Color COLOR_TEXT_DEEMPHASIZED = UIConstants.ENVIRONMENT_LIGHT; private static final Color COLOR_TEXT_NORMAL = Color.BLACK; /** * */ private static final long serialVersionUID = 1L; private ParrotModel model; public NodeWrapperRenderer(ParrotModel model) { this.model = model; } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (value instanceof NodeWrapper) { NodeWrapper node = (NodeWrapper) value; setToolTipText(node.getToolTipText(model)); if (renderer instanceof JLabel) { JLabel label = (JLabel) renderer; label.setVerticalAlignment(JLabel.BOTTOM); } if (deemphasizeText(table, value, isSelected, hasFocus, row, column)) { renderer.setForeground(COLOR_TEXT_DEEMPHASIZED); } else { renderer.setForeground(COLOR_TEXT_NORMAL); } if (node.isHighlighted()) { Font renderFont = renderer.getFont(); renderer.setFont(renderFont.deriveFont(Font.BOLD)); setBorderColour(renderer, COLOR_HIGHLIGHTED_BORDER); } if (node.isHereTooSelected()) { Color borderColour = COLOR_HERE_TOO_SELECTED_BORDER; setBorderColour(renderer, borderColour); } if (isSelected || hasFocus) { renderer.setBackground(COLOR_SELECTED_BG); } else { if (row % 2 == 0) { renderer.setBackground(COLOR_EVEN_ROW_UNSELECTED_BG); } else { renderer.setBackground(COLOR_ODD_ROW_UNSELECTED_BG); } } } return renderer; } private boolean deemphasizeText(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected || hasFocus) { return false; } List<? extends SortKey> sortKeys = table.getRowSorter().getSortKeys(); if (sortKeys.size() > 0) { int checkColumn = sortKeys.get(0).getColumn(); if (!valueRepeatedFromRowAbove(table, row, checkColumn)) { return false; } else { // we can stop here if the value is from the major sort column if (checkColumn == column) { return true; } } } if (sortKeys.size() > 1) { int checkColumn = sortKeys.get(1).getColumn(); if (!valueRepeatedFromRowAbove(table, row, checkColumn)) { return false; } else { // they are the same and we've already found out that the major // ones match too // so if this is the column we're looking at, we don't need to // go further if (checkColumn == column) { return true; } } } return valueRepeatedFromRowAbove(table, row, column); } private boolean valueRepeatedFromRowAbove(JTable table, int row, int column) { if (row < 1) { // we're looking at the first row return false; } Object valueInRowAbove, valueInThisRow; valueInRowAbove = table.getValueAt(row - 1, column); valueInThisRow = table.getValueAt(row, column); if (valueInRowAbove instanceof NodeWrapper && valueInThisRow instanceof NodeWrapper) { NodeWrapper wrapperInRowAbove = (NodeWrapper) valueInRowAbove; NodeWrapper wrapperInThisRow = (NodeWrapper) valueInThisRow; if (wrapperInRowAbove.isLiteral() && wrapperInThisRow.isLiteral()) { return wrapperInRowAbove.getLiteral().equals(wrapperInThisRow.getLiteral()); } else if (wrapperInRowAbove.isOntResource() && wrapperInThisRow.isOntResource()) { return wrapperInRowAbove.getOntResource().equals(wrapperInThisRow.getOntResource()); } } // last resort: compare strings return valueInThisRow.toString().equals(valueInRowAbove.toString()); } private void setBorderColour(Component renderer, Color borderColour) { if (renderer instanceof JComponent) { JComponent jRenderer = (JComponent) renderer; jRenderer .setBorder(BorderFactory.createLineBorder(borderColour, 2)); } } // The following methods override the defaults for performance reasons @Override public void validate() { } @Override public void revalidate() { } @Override protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { } @Override public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { } }