alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.openide.explorer.view;

import java.awt.*;
import java.beans.*;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;

import org.openide.explorer.propertysheet.*;
import org.openide.nodes.Node;
import org.openide.nodes.Node.Property;

/** Table view of node properties. Table header displays property display names and each cell
* contains (PropertyPanel) for displaying/editting of properties. Each property
* row belongs to one node.
*
* @author Jan Rojcek
*/
class TableSheet extends JScrollPane {
    
    /** table */
    transient protected JTable table;
    
    /** model */
    transient private NodeTableModel tableModel;

    /** Create table view with default table model.
     */
    public TableSheet() {
        tableModel = new NodeTableModel();
        initializeView();
    }

    /** Create table view with users table model.
     */
    public TableSheet(NodeTableModel tableModel) {
        this.tableModel = tableModel;
        initializeView();
    }

    private void initializeView() {
        table = createTable();
        initializeTable();
        
        setViewportView(table);

        // do not care about focus
        setRequestFocusEnabled (false);
        
        table.getAccessibleContext().setAccessibleName(
            org.openide.util.NbBundle.getBundle(TableSheet.class).getString("ACS_TableSheet"));
        table.getAccessibleContext().setAccessibleDescription(
            org.openide.util.NbBundle.getBundle(TableSheet.class).getString("ACSD_TableSheet"));
    }

    /** Set rows.
     * @param props rows
     */
    public void setNodes(Node[] nodes) {
        tableModel.setNodes(nodes);
    }
    
    /** Set columns.
     * @param nodes columns
     */
    public void setProperties(Property[] props) {
        tableModel.setProperties(props);
    }
    
    /** Sets resize mode of table.
     * 
     * @param mode - One of 5 legal values: 
JTable.AUTO_RESIZE_OFF,
     *                                           JTable.AUTO_RESIZE_NEXT_COLUMN,
     *                                           JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS, 
     *                                           JTable.AUTO_RESIZE_LAST_COLUMN, 
     *                                           JTable.AUTO_RESIZE_ALL_COLUMNS
*/ public final void setAutoResizeMode(int mode) { table.setAutoResizeMode(mode); } /** Sets resize mode of table. * * @param mode - One of 5 legal values:
JTable.AUTO_RESIZE_OFF,
     *                                           JTable.AUTO_RESIZE_NEXT_COLUMN,
     *                                           JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS, 
     *                                           JTable.AUTO_RESIZE_LAST_COLUMN, 
     *                                           JTable.AUTO_RESIZE_ALL_COLUMNS
*/ public final int getAutoResizeMode() { return table.getAutoResizeMode(); } /** Sets preferred width of table column * @param index column index * @param width preferred column width */ public final void setColumnPreferredWidth(int index, int width) { table.getColumnModel().getColumn(index).setPreferredWidth(width); table.setPreferredScrollableViewportSize(table.getPreferredSize()); } /** Gets preferred width of table column * @param index column index * @param width preferred column width */ public final int getColumnPreferredWidth(int index) { return table.getColumnModel().getColumn(index).getPreferredWidth(); } /** Allows to subclasses provide its own table. * @param tm node table model * @return table which will be placed into scroll pane */ JTable createTable() { return new JTable(); } /** Allows to subclasses initialize table * @param t */ private void initializeTable() { table.setModel(tableModel); TableSheetCell tableCell = new TableSheetCell(tableModel); table.setDefaultRenderer(Node.Property.class, tableCell); table.setDefaultEditor(Node.Property.class, tableCell); table.getTableHeader().setDefaultRenderer(tableCell); table.setShowGrid(false); table.setIntercellSpacing(new Dimension(0, 0)); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.getTableHeader().setReorderingAllowed(false); if (UIManager.getColor("Panel.background") != null) { // NOI18N table.setBackground(UIManager.getColor("Panel.background")); // NOI18N table.setSelectionBackground(UIManager.getColor("Panel.background")); // NOI18N } } /** Synchronized table view with other view (TreeView, ListView). Two views (scroll panes) * have only one vertical scroll bar. Right view is allways table view, left view could be any * scroll pane. Use ControlledTableView.compoundScrollPane() to get compound view. */ static class ControlledTableView extends TableSheet { /** Scroll pane which controls vertical scroll bar */ JScrollPane controllingView; /** Table like header of controlling view */ Component header; /** Compound scroll pane used in MouseDragHandler */ JPanel compoundScrollPane; /** Creates controlled scroll pane with contView on the left, table view * on the right */ ControlledTableView(JScrollPane contrView) { super(); this.controllingView = contrView; initializeView(); } /** Creates controlled scroll pane with contView on the left, table view * on the right. */ ControlledTableView(JScrollPane contrView, NodeTableModel ntm) { super(ntm); this.controllingView = contrView; initializeView(); } /** Validate root is outer scroll pane. */ public boolean isValidateRoot() { return false; } /** initialize view */ private void initializeView() { // adjustment of controlling view Component comp = controllingView.getViewport().getView(); controllingView.setViewportView(comp); if (UIManager.getColor ("Table.background") != null) { // NOI18N getViewport().setBackground(UIManager.getColor("Table.background")); // NOI18N } // both views share one vertical scrollbar setVerticalScrollBar(controllingView.getVerticalScrollBar()); ScrollPaneLayout spl = new EnablingScrollPaneLayout(controllingView); setLayout(spl); spl.syncWithScrollPane(this); spl = new EnablingScrollPaneLayout(this); controllingView.setLayout(spl); spl.syncWithScrollPane(controllingView); table.setBorder(null); // table like header header = new JTable().getTableHeader().getDefaultRenderer() .getTableCellRendererComponent(null, " ", false, false, 0, 0); // NOI18N MouseInputListener mouseHandler = new MouseDragHandler(); header.addMouseListener(mouseHandler); header.addMouseMotionListener(mouseHandler); } /** Overriden to return table with controlled height * @param tm table model * @return table */ JTable createTable() { return new ATable(); } private class ATable extends JTable { public ATable() { // fix for JTable bug - JTable consumes Esc key which is wrong // after JDK bug 4624483 is fixed this workaround can // be removed getActionMap().put("cancel", new OurCancelEditingAction()); // NOI18N } public Dimension getPreferredScrollableViewportSize() { Dimension pref = super.getPreferredScrollableViewportSize(); if (this.getAutoResizeMode() != JTable.AUTO_RESIZE_OFF && getParent() != null) { Insets insets = getParent().getInsets(); Dimension size = getParent().getSize(); pref.height = size.height - insets.top - insets.bottom; } return pref; } private boolean trytorevalidate = true; /** Try to revalidate once again because we want table to have * width that it asked for. */ public void setBounds(int x, int y, int width, int height) { super.setBounds(x, y, width, height); if (this.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF) { return; } if (trytorevalidate && width != getPreferredScrollableViewportSize().width) { trytorevalidate = false; compoundScrollPane.validate(); trytorevalidate = true; } } private class OurCancelEditingAction extends AbstractAction { OurCancelEditingAction() {} public void actionPerformed(java.awt.event.ActionEvent e) { JTable table = (JTable)e.getSource(); table.removeEditor(); } public boolean isEnabled() { return ATable.this.isEditing(); } } } JTable getTable() { return table; } /** Overriden because I can't set border to null by calling setBorder(null). * @param border */ public void setBorder(Border border) { super.setBorder(null); } /** Is used to synchronize table row height with left view. */ void setRowHeight(int h) { table.setRowHeight(h); getVerticalScrollBar().setUnitIncrement(h); } /** Sets text of table like header above left scroll pane. */ void setHeaderText(String text) { if (header instanceof JLabel) { ((JLabel)header).setText(text); } } /** Sets preferred size of left scroll pane. */ void setControllingViewWidth(int width) { controllingView.setPreferredSize(new Dimension(width, 0)); } /** Gets preferred size of left scroll pane. */ int getControllingViewWidth() { return controllingView.getPreferredSize().width; } /* public void setPreferredSize(Dimension prefSize) { table.setPreferredScrollableViewportSize(prefSize); } */ /** Returns component which contains two synchronized scroll panes. Above left one is * placed table like header. */ JComponent compoundScrollPane() { JPanel leftPanel = new JPanel(new BorderLayout()); leftPanel.add(header, BorderLayout.NORTH); leftPanel.add(controllingView, BorderLayout.CENTER); compoundScrollPane = new CompoundScrollPane(); compoundScrollPane.setLayout(new BorderLayout()); compoundScrollPane.add(leftPanel, BorderLayout.CENTER); compoundScrollPane.add(this, BorderLayout.EAST); return compoundScrollPane; } private class MouseDragHandler extends MouseInputAdapter { MouseDragHandler() {} boolean dragging = false; int lastMouseX; public void mousePressed(MouseEvent e) { Point p = e.getPoint(); dragging = canResize(p); lastMouseX = p.x; } private void setCursor(Cursor c) { if (header.getCursor() != c) { header.setCursor(c); } } private boolean canResize(Point mousePoint) { return mousePoint.x >= header.getSize().width - 3; } public void mouseMoved(MouseEvent e) { if (canResize(e.getPoint()) || dragging) { setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); } else { setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } public void mouseDragged(MouseEvent e) { int mouseX = e.getX(); int deltaX = lastMouseX - mouseX; if (deltaX == 0) { return; } if (dragging) { Dimension size = table.getPreferredScrollableViewportSize(); int parentWidth = compoundScrollPane.getWidth(); int tableMinWidth = table.getMinimumSize().width; int newWidth; if (size.width + deltaX > parentWidth - 20) { newWidth = parentWidth - 20; } else if (size.width + deltaX < tableMinWidth){ newWidth = tableMinWidth; } else { newWidth = size.width + deltaX; } table.setPreferredScrollableViewportSize(new Dimension(newWidth, size.height)); lastMouseX = lastMouseX - (newWidth - size.width); table.revalidate(); table.repaint(); } else { lastMouseX = mouseX; } } public void mouseReleased(MouseEvent e) { dragging = false; } }; } /** Scrollable (better say not scrollable) pane. Used as container for * left (controlling) and rigth (controlled) scroll panes. */ private static class CompoundScrollPane extends JPanel implements Scrollable { CompoundScrollPane() {} public boolean getScrollableTracksViewportWidth() { return true; } public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { return 10; } public boolean getScrollableTracksViewportHeight() { return true; } public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { return 10; } } private static String getString(String key) { return org.openide.util.NbBundle.getBundle(TableSheet.class).getString(key); } /** Makes visible horizontal scroll bar of dependent scrollpane. Enables/disables * horizontal scrollbar of parent scrollpane. */ private static final class EnablingScrollPaneLayout extends ScrollPaneLayout { JScrollPane dependentScrollPane; public EnablingScrollPaneLayout(JScrollPane scrollPane) { dependentScrollPane = scrollPane; } public void layoutContainer(Container parent) { super.layoutContainer(parent); Component view = (viewport != null) ? viewport.getView() : null; Dimension viewPrefSize = (view != null) ? view.getPreferredSize() : new Dimension(0,0); Dimension extentSize = (viewport != null) ? viewport.toViewCoordinates(viewport.getSize()) : new Dimension(0,0); boolean viewTracksViewportWidth = (view instanceof Scrollable) && ((Scrollable)view).getScrollableTracksViewportWidth(); boolean hsbNeeded = !viewTracksViewportWidth && viewPrefSize.width > extentSize.width; // enable horizontal scrollbar only if it is needed if (hsb != null) { hsb.setEnabled(hsbNeeded); } // make dependent horizontal scrollbar visible by setting scrollbar policy JScrollPane scrollPane = (JScrollPane)parent; if (scrollPane.getHorizontalScrollBarPolicy() != JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS) { int newPolicy = hsbNeeded ? JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS : JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED; if (newPolicy != dependentScrollPane.getHorizontalScrollBarPolicy()) { dependentScrollPane.setHorizontalScrollBarPolicy(newPolicy); dependentScrollPane.getViewport().invalidate(); } } } } }
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.