diff --git a/core.io.ui/src/org/netbeans/core/io/ui/IOWindow.java b/core.io.ui/src/org/netbeans/core/io/ui/IOWindow.java --- a/core.io.ui/src/org/netbeans/core/io/ui/IOWindow.java +++ b/core.io.ui/src/org/netbeans/core/io/ui/IOWindow.java @@ -74,6 +74,7 @@ import org.openide.util.Utilities; import org.openide.awt.MouseUtils; import org.openide.awt.TabbedPaneFactory; +import org.openide.awt.ToolbarWithOverflow; import org.openide.util.HelpCtx; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; @@ -210,7 +211,7 @@ pane.addPropertyChangeListener(TabbedPaneFactory.PROP_CLOSE, this); setFocusable(true); - toolbar = new JToolBar(); + toolbar = new ToolbarWithOverflow(); toolbar.setOrientation(JToolBar.VERTICAL); toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.Y_AXIS)); toolbar.setFloatable(false); @@ -507,7 +508,7 @@ toolbar.add(buttons[i]); } } - toolbar.revalidate(); + toolbar.validate(); toolbar.repaint(); } diff --git a/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/ToolbarConfiguration.java b/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/ToolbarConfiguration.java --- a/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/ToolbarConfiguration.java +++ b/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/ToolbarConfiguration.java @@ -280,8 +280,10 @@ if (comps[j] instanceof JComponent) { if (smallToolbarIcons) { ((JComponent) comps[j]).putClientProperty("PreferredIconSize",null); //NOI18N + tb.putClientProperty("PreferredIconSize",null); //NOI18N } else { ((JComponent) comps[j]).putClientProperty("PreferredIconSize",Integer.valueOf(24)); //NOI18N + tb.putClientProperty("PreferredIconSize",Integer.valueOf(24)); //NOI18N } } //TODO add icon shadow for mac l&f? diff --git a/editor/src/org/netbeans/modules/editor/NbEditorToolBar.java b/editor/src/org/netbeans/modules/editor/NbEditorToolBar.java --- a/editor/src/org/netbeans/modules/editor/NbEditorToolBar.java +++ b/editor/src/org/netbeans/modules/editor/NbEditorToolBar.java @@ -97,6 +97,7 @@ import org.netbeans.lib.editor.util.swing.DocumentUtilities; import org.netbeans.modules.editor.impl.ToolbarActionsProvider; import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults; +import org.openide.awt.ToolbarWithOverflow; import org.openide.filesystems.FileChangeAdapter; import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileEvent; @@ -124,7 +125,7 @@ * @version 1.00 */ -/* package */ final class NbEditorToolBar extends JToolBar { +/* package */ final class NbEditorToolBar extends ToolbarWithOverflow { // -J-Dorg.netbeans.modules.editor.NbEditorToolBar.level=FINE private static final Logger LOG = Logger.getLogger(NbEditorToolBar.class.getName()); diff --git a/openide.awt/apichanges.xml b/openide.awt/apichanges.xml --- a/openide.awt/apichanges.xml +++ b/openide.awt/apichanges.xml @@ -50,6 +50,20 @@ AWT API + + + ToolbarWithOverflow class that adds an overflow button when the toolbar becomes too small to show all the available actions. + + + + + + ToolbarWithOverflow class is added. It can be used to add an overflow button + when the toolbar becomes too small to show all the available actions. + + + + Support for Check for Updates feature diff --git a/openide.awt/manifest.mf b/openide.awt/manifest.mf --- a/openide.awt/manifest.mf +++ b/openide.awt/manifest.mf @@ -2,5 +2,5 @@ OpenIDE-Module: org.openide.awt OpenIDE-Module-Localizing-Bundle: org/openide/awt/Bundle.properties AutoUpdate-Essential-Module: true -OpenIDE-Module-Specification-Version: 7.47 +OpenIDE-Module-Specification-Version: 7.50 diff --git a/openide.awt/src/org/openide/awt/ToolbarWithOverflow.java b/openide.awt/src/org/openide/awt/ToolbarWithOverflow.java new file mode 100644 --- /dev/null +++ b/openide.awt/src/org/openide/awt/ToolbarWithOverflow.java @@ -0,0 +1,274 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 2012 Sun Microsystems, Inc. + */ +package org.openide.awt; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JPopupMenu; +import javax.swing.JToolBar; +import org.openide.util.ImageUtilities; + +/** + * ToolbarWithOverflow provides a component which is useful for displaying commonly used + * actions. It adds an overflow button when the toolbar becomes too small to show all the + * available actions. + * + * @author Th. Oikonomou + * @since 7.50 + */ +public class ToolbarWithOverflow extends JToolBar { + + private JButton overflowButton; + private JPopupMenu popup; + private JToolBar overflowToolbar; + private int visibleButtons; + private final String overflowIcon = "org/openide/awt/resources/overflow_right.png"; //NOI18N + private final String PROP_PREF_ICON_SIZE = "PreferredIconSize"; //NOI18N + private final String PROP_DRAGGER = "_toolbar_dragger_"; //NOI18N + + /** + * Creates a new tool bar; orientation defaults to + * HORIZONTAL. + */ + public ToolbarWithOverflow() { + this(HORIZONTAL); + } + + /** + * Creates a new tool bar with the specified + * orientation. The + * orientation must be either + * HORIZONTAL or + * VERTICAL. + * + * @param orientation the orientation desired + */ + public ToolbarWithOverflow(int orientation) { + this(null, orientation); + } + + /** + * Creates a new tool bar with the specified + * name. The name is used as the title of the undocked tool + * bar. The default orientation is + * HORIZONTAL. + * + * @param name the name of the tool bar + */ + public ToolbarWithOverflow(String name) { + this(name, HORIZONTAL); + } + + /** + * Creates a new tool bar with a specified + * name and + * orientation. All other constructors call this constructor. + * If + * orientation is an invalid value, an exception will be + * thrown. + * + * @param name the name of the tool bar + * @param orientation the initial orientation -- it must be * either HORIZONTAL or VERTICAL + * @exception IllegalArgumentException if orientation is neither + * HORIZONTAL nor VERTICAL + */ + public ToolbarWithOverflow(String name, int orientation) { + super(name, orientation); + overflowButton = new JButton(ImageUtilities.loadImageIcon(overflowIcon, false)); + popup = new JPopupMenu(); + overflowToolbar = new JToolBar("overflowToolbar", orientation == HORIZONTAL ? VERTICAL : HORIZONTAL); + overflowToolbar.setFloatable(false); + overflowButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + popup.show(overflowButton, 0, overflowButton.getHeight()); + } + }); + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + maybeAddOverflow(); + } + }); + } + + @Override + public final Dimension getPreferredSize() { + Component[] comps = getAllComponents(); + int width = 0; + int height = 0; + for (int i = 0; i < comps.length; i++) { + Component comp = comps[i]; + width += getOrientation() == HORIZONTAL ? comp.getPreferredSize().width : comp.getPreferredSize().height; + height = getOrientation() == HORIZONTAL ? comp.getPreferredSize().height : comp.getPreferredSize().width; + } + if(overflowToolbar.getComponentCount() > 0) { + width += getOrientation() == HORIZONTAL ? overflowButton.getPreferredSize().width : overflowButton.getPreferredSize().height; + } + Dimension dim = getOrientation() == HORIZONTAL ? new Dimension(width, height) : new Dimension(height, width); + return dim; + } + + @Override + public void removeAll() { + super.removeAll(); + overflowToolbar.removeAll(); + } + + @Override + public void validate() { + computeVisibleButtons(); + if (visibleButtons == -1) { + handleOverflowRemoval(); + } else { + handleOverflowAddittion(); + } + super.validate(); + } + + /** + * Determines if an overflow button should be added to or removed from the toolbar. + */ + private void maybeAddOverflow() { + validate(); + repaint(); + } + + private void computeVisibleButtons() { + handleIconResize(); + Component[] comps = getAllComponents(); + int sizeSoFar = 0; + int maxSize = getOrientation() == HORIZONTAL ? getWidth() : getHeight(); + int overflowButtonSize = getOrientation() == HORIZONTAL ? overflowButton.getPreferredSize().width : overflowButton.getPreferredSize().height; + for (int i = 0; i < comps.length; i++) { + Component comp = comps[i]; + sizeSoFar += getOrientation() == HORIZONTAL ? comp.getPreferredSize().width : comp.getPreferredSize().height; + if (sizeSoFar > maxSize) { + visibleButtons = i; + break; + } else { + if (sizeSoFar + overflowButtonSize > maxSize && i + 1 != comps.length) { + visibleButtons = i; + break; + } else { + visibleButtons = i + 1; + } + } + } + if(visibleButtons == 0 && comps.length > 0) { + if (comps[0] instanceof JComponent) { + if (Boolean.TRUE.equals(((JComponent) comps[0]).getClientProperty(PROP_DRAGGER))) { + visibleButtons = 1; + } + } + } + if (visibleButtons == comps.length) { + visibleButtons = -1; + } + } + + private void handleOverflowAddittion() { + Component[] comps = getAllComponents(); + if (visibleButtons <= comps.length) { + removeAll(); + overflowToolbar.setOrientation(getOrientation() == HORIZONTAL ? VERTICAL : HORIZONTAL); + popup.removeAll(); + + for (int i = 0; i < visibleButtons; i++) { + add(comps[i]); + } + for (int i = visibleButtons; i < comps.length; i++) { + overflowToolbar.add(comps[i]); + } + popup.add(overflowToolbar); + add(overflowButton); + } + } + + private void handleOverflowRemoval() { + if (overflowToolbar.getComponents().length > 0) { + remove(overflowButton); + handleIconResize(); + for (Component comp : overflowToolbar.getComponents()) { + add(comp); + } + overflowToolbar.removeAll(); + popup.removeAll(); + } + } + + private void handleIconResize() { + for (Component comp : overflowToolbar.getComponents()) { + boolean smallToolbarIcons = getClientProperty(PROP_PREF_ICON_SIZE) == null; + if (smallToolbarIcons) { + ((JComponent) comp).putClientProperty(PROP_PREF_ICON_SIZE, null); + } else { + ((JComponent) comp).putClientProperty(PROP_PREF_ICON_SIZE, Integer.valueOf(24)); + } + } + } + + private Component[] getAllComponents() { + Component[] toolbarComps; + Component[] overflowComps = overflowToolbar.getComponents(); + if (overflowComps.length == 0) { + toolbarComps = getComponents(); + } else { + if (getComponentCount() > 0) { + toolbarComps = new Component[getComponents().length - 1]; + System.arraycopy(getComponents(), 0, toolbarComps, 0, toolbarComps.length); + } else { + toolbarComps = new Component[0]; + } + } + Component[] comps = new Component[toolbarComps.length + overflowComps.length]; + System.arraycopy(toolbarComps, 0, comps, 0, toolbarComps.length); + System.arraycopy(overflowComps, 0, comps, toolbarComps.length, overflowComps.length); + return comps; + } +} diff --git a/openide.awt/src/org/openide/awt/resources/overflow_right.png b/openide.awt/src/org/openide/awt/resources/overflow_right.png new file mode 100644 index 0000000000000000000000000000000000000000..d03f8b93cf248230420d9209d9728008c630371a GIT binary patch literal 542 zc$@(q0^$9MP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iylA z3pW=G^Cv$500Ev!L_t(2&yA7IirQcpg%3&m;ftYG1WCTy#Q1~Y&t}{hWLAT#u8J-c z7gAAIU3D>+&@$b(y@1jS7`kg2=nc%w4R`?~Xu_wBF`{obW9y=Yp5@^==Y8P-C(7sZ z007&z@lO>B1=TdoOV0VbQ`olc*PQb!0LbNXe*)QT)@-#}G#Cs>*YzJqzg#ZUa5$u5 zu_#VMvJgV7Rx5=uc3!DeOyBnn&-1>zuKSIMMvX=z>ihni*=+U}0Av6Ng5X975m6N7 z+_J2*AP5Z4^F9h8?!z$b)$8?`BuOvl^Z6(F_`+thxmmB*4~(%F)oS%@xm;eju6wyy zEWYn{yH~YZEfa>}SONgUFaQ9FMB+XYiD0|kf{3C3a5x<9WLX9gVZYx;q3b#TARdp8 z+wC@WIvvVnGS`oXYmVd4WHO;rsWb!d3;+;|#m3!km-_uarPJwa04jh)v)QESbV{7_ zp8&D|fMhahIgUfUUXL_Qy9FQtfMr=U8jX(d)89L!QmH4JrhQOV_45&aEPBrv`vTzk g-v*ZfDF5N%7t8;W@_A{?LI3~&07*qoM6N<$f_J^^iU0rr diff --git a/openide.loaders/src/org/openide/awt/Toolbar.java b/openide.loaders/src/org/openide/awt/Toolbar.java --- a/openide.loaders/src/org/openide/awt/Toolbar.java +++ b/openide.loaders/src/org/openide/awt/Toolbar.java @@ -79,7 +79,7 @@ * * @author David Peroutka, Libor Kramolis */ -public class Toolbar extends JToolBar /*implemented by patchsuperclass MouseInputListener*/ { +public class Toolbar extends ToolbarWithOverflow /*implemented by patchsuperclass MouseInputListener*/ { /** Basic toolbar height. @deprecated Use getBasicHeight instead. */ @Deprecated