diff --git a/o.n.swing.outline/apichanges.xml b/o.n.swing.outline/apichanges.xml --- a/o.n.swing.outline/apichanges.xml +++ b/o.n.swing.outline/apichanges.xml @@ -153,6 +153,20 @@ + + + Add a support for rendering of check-boxes in the tree column. + + + + + +

Added CheckRenderDataProvider interface. +

+
+ + +
diff --git a/o.n.swing.outline/manifest.mf b/o.n.swing.outline/manifest.mf --- a/o.n.swing.outline/manifest.mf +++ b/o.n.swing.outline/manifest.mf @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.swing.outline OpenIDE-Module-Localizing-Bundle: org/netbeans/swing/outline/Bundle.properties -OpenIDE-Module-Specification-Version: 1.3 +OpenIDE-Module-Specification-Version: 1.4 diff --git a/o.n.swing.outline/src/org/netbeans/swing/outline/CheckRenderDataProvider.java b/o.n.swing.outline/src/org/netbeans/swing/outline/CheckRenderDataProvider.java new file mode 100644 --- /dev/null +++ b/o.n.swing.outline/src/org/netbeans/swing/outline/CheckRenderDataProvider.java @@ -0,0 +1,86 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2009 Sun Microsystems, Inc. + */ + +package org.netbeans.swing.outline; + +/** + * An extension to {@link RenderDataProvider} adding a possibility to + * display a check box in the tree portion an Outline, next to the label. + * + * @author Martin Entlicher + * @since 1.4 + */ +public interface CheckRenderDataProvider extends RenderDataProvider { + + /** + * Tell the renderer to display the check-box. + * + * @param o the tree object + * @return true if the check-box should be displayed, false otherwise. + */ + boolean isCheckable(Object o); + + /** + * Provide the enabled state of the check-box. + * + * @param o the tree object + * @return true if the check-box should be enabled, false otherwise. + */ + boolean isCheckEnabled(Object o); + + /** + * Provide the selected state of the check-box. + * + * @param o the tree object + * @return true if the check-box should be selected, + * false if it should be unselected and + * null if the state is unknown. + */ + Boolean isSelected(Object o); + + /** + * Called by the renderer when the check-box gets selected/unselected + * + * @param o the tree object + * @param selected true if the check-box was selected, + * false if the check-box was unselected. + */ + void setSelected(Object o, Boolean selected); + +} diff --git a/o.n.swing.outline/src/org/netbeans/swing/outline/DefaultOutlineCellRenderer.java b/o.n.swing.outline/src/org/netbeans/swing/outline/DefaultOutlineCellRenderer.java --- a/o.n.swing.outline/src/org/netbeans/swing/outline/DefaultOutlineCellRenderer.java +++ b/o.n.swing.outline/src/org/netbeans/swing/outline/DefaultOutlineCellRenderer.java @@ -42,9 +42,12 @@ import java.awt.Color; import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; import java.awt.Insets; import javax.swing.BorderFactory; import javax.swing.Icon; +import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.SwingUtilities; @@ -66,10 +69,16 @@ private boolean leaf = true; private boolean showHandle = true; private int nestingDepth = 0; + private final JCheckBox theCheckBox; + private JCheckBox checkBox; private static final Border expansionBorder = new ExpansionHandleBorder(); /** Creates a new instance of DefaultOutlineTreeCellRenderer */ public DefaultOutlineCellRenderer() { + theCheckBox = new JCheckBox(); + theCheckBox.setSize(theCheckBox.getPreferredSize()); + theCheckBox.setBorderPainted(false); + theCheckBox.setOpaque(false); } /** Overridden to combine the expansion border (whose insets determine how @@ -140,6 +149,10 @@ private void setShowHandle (boolean val) { showHandle = val; } + + private void setCheckBox(JCheckBox checkBox) { + this.checkBox = checkBox; + } private boolean isLeaf () { return leaf; @@ -159,6 +172,14 @@ * node. */ private int getNestingDepth() { return nestingDepth; + } + + private JCheckBox getCheckBox() { + return checkBox; + } + + int getTheCheckBoxWidth() { + return theCheckBox.getSize().width; } /** Get a component that can render cells in an Outline. If @@ -218,6 +239,22 @@ tbl.getSelectionForeground() : tbl.getForeground()); } icon = rendata.getIcon(value); + + JCheckBox cb = null; + if (rendata instanceof CheckRenderDataProvider) { + CheckRenderDataProvider crendata = (CheckRenderDataProvider) rendata; + if (crendata.isCheckable(value)) { + cb = theCheckBox; + Boolean chSelected = crendata.isSelected(value); + cb.setSelected(!Boolean.FALSE.equals(chSelected)); + // Third state is "selected armed" to be consistent with org.openide.explorer.propertysheet.ButtonModel3Way + cb.getModel().setArmed(chSelected == null); + cb.getModel().setPressed(chSelected == null); + cb.setEnabled(crendata.isCheckEnabled(value)); + cb.setBackground(getBackground()); + } + } + setCheckBox(cb); } if (icon == null) { if (!isleaf) { @@ -239,7 +276,7 @@ } return this; } - + private static class ExpansionHandleBorder implements Border { private static final boolean isGtk = "GTK".equals (UIManager.getLookAndFeel ().getID ()); //NOI18N @@ -271,6 +308,9 @@ insets.right = 1; insets.bottom = 1; } + if (ren.getCheckBox() != null) { + insets.left += ren.getCheckBox().getSize().width; + } return insets; } @@ -296,7 +336,13 @@ } else { icon.paintIcon(c, g, iconX, iconY); } - + } + JCheckBox chBox = ren.getCheckBox(); + if (chBox != null) { + int chBoxX = getExpansionHandleWidth() + ren.getNestingDepth() * getNestingWidth(); + Dimension chDim = chBox.getSize(); + java.awt.Graphics gch = g.create(chBoxX, 0, chDim.width, chDim.height); + chBox.paint(gch); } } } diff --git a/o.n.swing.outline/src/org/netbeans/swing/outline/Outline.java b/o.n.swing.outline/src/org/netbeans/swing/outline/Outline.java --- a/o.n.swing.outline/src/org/netbeans/swing/outline/Outline.java +++ b/o.n.swing.outline/src/org/netbeans/swing/outline/Outline.java @@ -549,6 +549,38 @@ return false; } } + // It may be a request to check/uncheck a check-box + RenderDataProvider render = getRenderDataProvider(); + TableCellRenderer tcr = getDefaultRenderer(Object.class); + if (render instanceof CheckRenderDataProvider && tcr instanceof DefaultOutlineCellRenderer) { + CheckRenderDataProvider crender = (CheckRenderDataProvider) render; + DefaultOutlineCellRenderer ocr = (DefaultOutlineCellRenderer) tcr; + Object value = getValueAt(row, column); + if (crender.isCheckable(value)) { + int handleWidth = DefaultOutlineCellRenderer.getExpansionHandleWidth(); + int chWidth = ocr.getTheCheckBoxWidth(); + Insets ins = getInsets(); + int nd = path.getPathCount() - (isRootVisible() ? 1 : 2); + if (nd < 0) { + nd = 0; + } + int chStart = ins.left + (nd * DefaultOutlineCellRenderer.getNestingWidth()) + handleWidth; + int chEnd = chStart + chWidth; + //TODO: Translate x/y to position of column if non-0 + + boolean enabled = crender.isCheckEnabled(value); + if ((me.getX() > ins.left && me.getX() >= chStart && me.getX() <= chEnd) && + me.getClickCount() == 1 && enabled) { + + Boolean selected = crender.isSelected(value); + if (selected == null || Boolean.TRUE.equals(selected)) { + crender.setSelected(value, Boolean.FALSE); + } else { + crender.setSelected(value, Boolean.TRUE); + } + } + } + } } boolean res = super.editCellAt(row, column, e); diff --git a/o.n.swing.outline/src/org/netbeans/swing/outline/RenderDataProvider.java b/o.n.swing.outline/src/org/netbeans/swing/outline/RenderDataProvider.java --- a/o.n.swing.outline/src/org/netbeans/swing/outline/RenderDataProvider.java +++ b/o.n.swing.outline/src/org/netbeans/swing/outline/RenderDataProvider.java @@ -46,10 +46,7 @@ /** A class which can provide rendering data for the tree portion an Outline, * such as converting values to text, providing tooltip text and icons. * Makes it possible to provide most of the interesting data that affects - * display without needing to provide a custom cell renderer. An Outline - * will use its RenderDataProvider to fetch data for all - * its columns, so it is possible to affect the display of both property - * columns and the tree column via this interface. + * display without needing to provide a custom cell renderer. * * @author Tim Boudreau */ diff --git a/openide.explorer/apichanges.xml b/openide.explorer/apichanges.xml --- a/openide.explorer/apichanges.xml +++ b/openide.explorer/apichanges.xml @@ -47,9 +47,21 @@ Explorer API + + + Support for check-boxes displayed next to node icons. + + + + + Nodes can have check-boxes rendered next to their icons or display names. + + + + - setSelectedNodes() does partial selection instead of throwing IllegalArgumentException when + setSelectedNodes() does partial selection instead of throwing IllegalArgumentException when some of newly selected nodes are not under root context. @@ -57,14 +69,14 @@ Nodes can be removed outside of AWT thread while e.g. view can try to select them. This generated IllegalArgumentException during checking if - such a node is under root context. Now + such a node is under root context. Now setSelectedNodes(). - does partial selection + does partial selection of valid nodes instead of throwing IllegalArgumentException. - + Added OutlineView component which is a replacement for buggy TreeTableView. diff --git a/openide.explorer/nbproject/project.properties b/openide.explorer/nbproject/project.properties --- a/openide.explorer/nbproject/project.properties +++ b/openide.explorer/nbproject/project.properties @@ -44,4 +44,4 @@ javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml -spec.version.base=6.17.0 +spec.version.base=6.18.0 diff --git a/openide.explorer/nbproject/project.xml b/openide.explorer/nbproject/project.xml --- a/openide.explorer/nbproject/project.xml +++ b/openide.explorer/nbproject/project.xml @@ -51,7 +51,7 @@ - 1.0 + 1.4 diff --git a/openide.explorer/src/org/openide/explorer/view/CheckNodeCookie.java b/openide.explorer/src/org/openide/explorer/view/CheckNodeCookie.java new file mode 100644 --- /dev/null +++ b/openide.explorer/src/org/openide/explorer/view/CheckNodeCookie.java @@ -0,0 +1,84 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2009 Sun Microsystems, Inc. + */ + +package org.openide.explorer.view; + +import org.openide.nodes.Node; + +/** + * Node cookie, which adds a possibility to display a check box + * next to the node display name in the views that support it. + * + * @author Martin Entlicher + * @since 6.18 + */ +public interface CheckNodeCookie extends Node.Cookie { + + /** + * Tell the view to display a check-box for this node. + * + * @return true if the check-box should be displayed, false otherwise. + */ + boolean isCheckable(); + + /** + * Provide the enabled state of the check-box. + * + * @return true if the check-box should be enabled, false otherwise. + */ + boolean isCheckEnabled(); + + /** + * Provide the selected state of the check-box. + * + * @return true if the check-box should be selected, + * false if it should be unselected and + * null if the state is unknown. + */ + Boolean isSelected(); + + /** + * Called by the view when the check-box gets selected/unselected + * + * @param selected true if the check-box was selected, + * false if the check-box was unselected. + */ + void setSelected(Boolean selected); + +} diff --git a/openide.explorer/src/org/openide/explorer/view/NodeRenderDataProvider.java b/openide.explorer/src/org/openide/explorer/view/NodeRenderDataProvider.java --- a/openide.explorer/src/org/openide/explorer/view/NodeRenderDataProvider.java +++ b/openide.explorer/src/org/openide/explorer/view/NodeRenderDataProvider.java @@ -47,6 +47,7 @@ import javax.swing.tree.AbstractLayoutCache; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; +import org.netbeans.swing.outline.CheckRenderDataProvider; import org.netbeans.swing.outline.Outline; import org.netbeans.swing.outline.RenderDataProvider; import org.openide.nodes.Node; @@ -55,12 +56,12 @@ * * @author David Strupl */ -class NodeRenderDataProvider implements RenderDataProvider { +class NodeRenderDataProvider implements CheckRenderDataProvider { - private JTable table; + private Outline table; /** Creates a new instance of NodeRenderDataProvider */ - public NodeRenderDataProvider(JTable table) { + public NodeRenderDataProvider(Outline table) { this.table = table; } @@ -95,7 +96,7 @@ } Collections.reverse(al); TreePath tp = new TreePath(al.toArray()); - AbstractLayoutCache layout = ((Outline)table).getLayoutCache(); + AbstractLayoutCache layout = table.getLayoutCache(); expanded = layout.isExpanded(tp); } java.awt.Image image = null; @@ -118,5 +119,39 @@ public boolean isHtmlDisplayName(Object o) { return false; } - + + private CheckNodeCookie getCheckCookie(Object o) { + Node n = Visualizer.findNode(o); + if (n == null) { + throw new IllegalStateException("TreeNode must be VisualizerNode but was: " + o + " of class " + o.getClass().getName()); + } + return n.getCookie(CheckNodeCookie.class); + } + + public boolean isCheckable(Object o) { + CheckNodeCookie c = getCheckCookie(o); + return c != null && c.isCheckable(); + } + + public boolean isCheckEnabled(Object o) { + CheckNodeCookie c = getCheckCookie(o); + return c != null && c.isCheckEnabled(); + } + + public Boolean isSelected(Object o) { + CheckNodeCookie c = getCheckCookie(o); + if (c != null) { + return c.isSelected(); + } else { + return null; + } + } + + public void setSelected(Object o, Boolean selected) { + CheckNodeCookie c = getCheckCookie(o); + if (c != null) { + c.setSelected(selected); + } + } + }