/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * 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 3 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, see http://www.gnu.org/licenses/ */ package com.bc.ceres.swing.selection.support; import com.bc.ceres.swing.selection.AbstractSelectionContext; import com.bc.ceres.swing.selection.Selection; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; /** * A selection provider that wraps a {@link JTable}. * Elements contained in {@link Selection}s handled by this provider * represent currently selected table row index as an {@link Integer} value. */ public class TableSelectionContext extends AbstractSelectionContext { private final ListSelectionListener tableSelectionListener; private final TableSelectionModelChangeListener selectionModelChangeListener; private JTable table; public TableSelectionContext(final JTable table) { selectionModelChangeListener = new TableSelectionModelChangeListener(); tableSelectionListener = new TableSelectionListener(); this.table = table; installTableListeners(); } /** * Gets the current selection. * The default implementation returns the selected row indices of the table. * If overridden, make sure also {@link #setSelection(Selection)} and {@link #handleTableSelectionChanged(javax.swing.event.ListSelectionEvent)} * are appropriately overridden. * * @return The current selection. */ @Override public Selection getSelection() { int[] indexes = table.getSelectedRows(); if (indexes.length == 0) { return DefaultSelection.EMPTY; } Integer[] elements = new Integer[indexes.length]; for (int i = 0; i < indexes.length; i++) { elements[i] = indexes[i]; } return new DefaultSelection<Integer>(elements); } /** * Sets the current selection. * The default implementation expects the selected row indices of the table in the given selection. * If overridden, make sure also {@link #getSelection()} and {@link #handleTableSelectionChanged(javax.swing.event.ListSelectionEvent)} * are appropriately overridden. * * @param selection The current selection. */ @Override public void setSelection(Selection selection) { if (selection.isEmpty()) { table.getSelectionModel().clearSelection(); return; } final Object[] elements = selection.getSelectedValues(); table.getSelectionModel().setValueIsAdjusting(true); table.getSelectionModel().clearSelection(); for (Object element : elements) { final int index = (Integer) element; table.addRowSelectionInterval(index, index); } table.getSelectionModel().setValueIsAdjusting(false); } public JTable getTable() { return table; } public void setTable(JTable table) { if (table != this.table) { uninstallTableListeners(); this.table = table; installTableListeners(); fireSelectionChange(getSelection()); } } protected void handleTableSelectionChanged(ListSelectionEvent event) { if (!event.getValueIsAdjusting()) { fireSelectionChange(getSelection()); } } private void installTableListeners() { table.getSelectionModel().addListSelectionListener(tableSelectionListener); table.addPropertyChangeListener("selectionModel", selectionModelChangeListener); } private void uninstallTableListeners() { table.getSelectionModel().removeListSelectionListener(tableSelectionListener); table.removePropertyChangeListener("selectionModel", selectionModelChangeListener); } private class TableSelectionModelChangeListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { final ListSelectionModel oldSelectionModel = (ListSelectionModel) evt.getOldValue(); if (oldSelectionModel != null) { oldSelectionModel.removeListSelectionListener(tableSelectionListener); } final ListSelectionModel newSelectionModel = (ListSelectionModel) evt.getNewValue(); if (newSelectionModel != null) { newSelectionModel.addListSelectionListener(tableSelectionListener); } } } private class TableSelectionListener implements ListSelectionListener { @Override public void valueChanged(ListSelectionEvent e) { handleTableSelectionChanged(e); } } }