All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.odell.glazedlists.swing.TreeTableUtilities Maven / Gradle / Ivy

/* Glazed Lists                                                 (c) 2003-2006 */
/* http://publicobject.com/glazedlists/                      publicobject.com,*/
/*                                                     O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.swing;

import ca.odell.glazedlists.TreeList;

import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;

import javax.swing.JTable;
import javax.swing.ListSelectionModel;

/**
 * A collection of static utility methods to ease the burdens of implementing
 * correct TreeTable behaviour in Swing.
 *
 * @author James Lemieux
 */
public class TreeTableUtilities {

    /**
     * Assuming the mouseEvent occurred over a {@link JTable},
     * retrieve the row over which the event occurred.
     *
     * @param mouseEvent a MouseEvent whose source is a {@link JTable}
     * @return the index of the table row over which the event occurred
     */
    static int rowAtPoint(MouseEvent mouseEvent) {
        final JTable table = (JTable) mouseEvent.getSource();
        final Point clickPoint = mouseEvent.getPoint();
        return table.rowAtPoint(clickPoint);
    }

    /**
     * Given a mouseEvent which occurred over a {@link JTable},
     * and further assuming that the column is a hierarchical column that
     *
     * @param mouseEvent a MouseEvent whose source is a {@link JTable}
     * @return the TreeTableCellPanel returned by the renderer, or
     *      null if the click was outside the table or the
     *      renderer does not return a TreeTableCellPanel
     */
    public static TreeTableCellPanel prepareRenderer(MouseEvent mouseEvent) {
        // extract information about the location of the click
        final JTable table = (JTable) mouseEvent.getSource();
        final Point clickPoint = mouseEvent.getPoint();
        final int row = table.rowAtPoint(clickPoint);
        final int column = table.columnAtPoint(clickPoint);

        // if the coordinates are not within the table, bail early
        if (row == -1 || column == -1)
            return null;

        // translate the click to be relative to the cellRect (and thus its rendered component)
        final Rectangle cellRect = table.getCellRect(row, column, true);

        // get the component rendered for the cell
        final Component renderedComponent = table.prepareRenderer(table.getCellRenderer(row, column), row, column);

        // if the component is not a TreeTableCellPanel, bail early
        if (!(renderedComponent instanceof TreeTableCellPanel))
            return null;

        // layout the panel within its bounds
        final TreeTableCellPanel renderedPanel = (TreeTableCellPanel) renderedComponent;
        renderedPanel.setBounds(cellRect);
        renderedPanel.doLayout();

        return renderedPanel;
    }

    /**
     * This method toggles the expanded/collapsed state of the given
     * row in the given treeList without altering the
     * row selections within the given table, if possible. In
     * practice, this can only be achieved if the table uses an
     * {@link AdvancedListSelectionModel} as its selection model.
     *
     * 

This method also turns off JTable's JTable.autoStartsEdit * client property during the toggling to stop any attempts at beginning a * cell edit. This behaviour is only relevant when the toggling action is * triggered by the keyboard. We do this to avoid invoking two behaviours * with only a single keystroke: toggling the expand/collapse state AND * starting a cell edit. * * A Runnable is returned which, when executed, restores the settings in * the EventSelectionModel and the JTable's client property. It is up to * the caller to decide when the appropriate time to re-enable those * settings may be and execute the Runnable. */ static Runnable toggleExpansion(JTable table, TreeList treeList, int row) { final RestoreStateRunnable restoreStateRunnable = new RestoreStateRunnable(table); final AdvancedListSelectionModel selectionModel = restoreStateRunnable.getEventSelectionModel(); // disable the EventSelectionModel so it does not respect our attempted change to row selection (due to treeList.toggleExpanded(row);) if (selectionModel != null) selectionModel.setEnabled(false); // disable attempts to start an edit because of a keystroke table.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE); treeList.toggleExpanded(row); // return a Runnable that restores the state of the table and selection model return restoreStateRunnable; } /** * Instances of this Runnable restore a captured state of a JTable and its * EventSelectionModel at some point in the future (when it is executed) */ private static class RestoreStateRunnable implements Runnable { private final JTable table; private final Boolean autoStartsEdit; private final AdvancedListSelectionModel eventSelectionModel; private final boolean eventSelectionModelEnabled; public RestoreStateRunnable(JTable table) { this.table = table; final ListSelectionModel selectionModel = table.getSelectionModel(); eventSelectionModel = selectionModel instanceof AdvancedListSelectionModel ? (AdvancedListSelectionModel) selectionModel : null; eventSelectionModelEnabled = eventSelectionModel != null && eventSelectionModel.getEnabled(); autoStartsEdit = (Boolean) table.getClientProperty("JTable.autoStartsEdit"); } public AdvancedListSelectionModel getEventSelectionModel() { return eventSelectionModel; } public void run() { table.putClientProperty("JTable.autoStartsEdit", autoStartsEdit); if (eventSelectionModel != null) eventSelectionModel.setEnabled(eventSelectionModelEnabled); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy