/******************************************************************************* * Breakout Cave Survey Visualizer * * Copyright (C) 2014 James Edwards * * jedwards8 at fastmail dot fm * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program 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 GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *******************************************************************************/ package org.andork.swing.table.old; import java.awt.Adjustable; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Paint; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.TableModel; import org.andork.swing.table.old.FilteringTableModel.HighlightingFilterResult; @SuppressWarnings("serial") public class HighlightingTableScroller extends JScrollPane { protected class HighlightingScrollbar extends ScrollBar { /** * */ private static final long serialVersionUID = -337180854527625492L; public HighlightingScrollbar() { super(Adjustable.VERTICAL); } private Color getDarkerColor(Color c, float darkness, int alpha) { float[] hsb = new float[4]; Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), hsb); hsb[2] = Math.max(0, hsb[2] - darkness); Color result = Color.getHSBColor(hsb[0], hsb[1], hsb[2]); return new Color(result.getRed(), result.getGreen(), result.getBlue(), alpha); } private Color getRowColor(int row) { if (table.isRowSelected(row)) { return table.getSelectionBackground(); } else if (filteringModel != null) { Object filterResult = filteringModel.getFilterResultForRow(row); if (filterResult instanceof HighlightingFilterResult) { HighlightingFilterResult hfr = (HighlightingFilterResult) filterResult; if (hfr.highlightingFilter != null) { return table.getHighlightColor(hfr.highlightingFilter); } } } return null; } @Override public void paint(Graphics g) { super.paint(g); TableModel model = table.getModel(); if (model instanceof FilteringTableModel) { filteringModel = (FilteringTableModel) model; } else { filteringModel = null; } Graphics2D g2 = (Graphics2D) g; Paint prevPaint = g2.getPaint(); Insets insets = getInsets(); int buttonSize = 20; int xPadding = 4; int scrollArea = getHeight() - insets.top - insets.bottom - buttonSize * 2; int markerWidth = getWidth() - insets.left - insets.right - xPadding * 2; for (int row = 0; row < table.getRowCount(); row++) { Color rowColor = getRowColor(row); if (rowColor != null) { int startY = buttonSize - 1 + row * scrollArea / table.getRowCount(); while (row < table.getRowCount() - 1 && rowColor.equals(getRowColor(row + 1))) { row++; } int endY = buttonSize - 1 + (row + 1) * scrollArea / table.getRowCount(); endY = Math.max(endY, startY + 3); g2.setColor(new Color(rowColor.getRed(), rowColor.getGreen(), rowColor.getBlue(), 64)); g2.fillRect(insets.left + xPadding, startY, markerWidth, endY - startY); g2.setColor(getDarkerColor(rowColor, 0.3f, 128)); g2.drawRect(insets.left + xPadding, startY, markerWidth, endY - startY); } } g2.setPaint(prevPaint); } } private class RepaintHandler implements PropertyChangeListener, TableModelListener, ListSelectionListener { private TableModel model; private ListSelectionModel selectionModel; @Override public void propertyChange(PropertyChangeEvent evt) { if ("model".equals(evt.getPropertyName())) { setModel((TableModel) evt.getNewValue()); } else if ("selectionModel".equals(evt.getPropertyName())) { setSelectionModel((ListSelectionModel) evt.getNewValue()); } } public void setModel(TableModel model) { if (this.model != model) { if (this.model != null) { this.model.removeTableModelListener(this); } this.model = model; if (model != null) { model.addTableModelListener(this); } getVerticalScrollBar().repaint(); } } public void setSelectionModel(ListSelectionModel selectionModel) { if (this.selectionModel != selectionModel) { if (this.selectionModel != null) { this.selectionModel.removeListSelectionListener(this); } this.selectionModel = selectionModel; if (selectionModel != null) { selectionModel.addListSelectionListener(this); } getVerticalScrollBar().repaint(); } } @Override public void tableChanged(TableModelEvent e) { getVerticalScrollBar().repaint(); } @Override public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { getVerticalScrollBar().repaint(); } } } /** * */ private static final long serialVersionUID = 8743638445712360337L; private HighlightingTable table; private FilteringTableModel filteringModel; private RepaintHandler repaintHandler; public HighlightingTableScroller(HighlightingTable table) { super(table); this.table = table; repaintHandler = new RepaintHandler(); repaintHandler.setModel(table.getModel()); repaintHandler.setSelectionModel(table.getSelectionModel()); table.addPropertyChangeListener("model", repaintHandler); table.addPropertyChangeListener("selectionModel", repaintHandler); } @Override public JScrollBar createVerticalScrollBar() { return new HighlightingScrollbar(); } }