001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.form.palette;
043:
044: import java.awt.*;
045: import javax.swing.*;
046: import java.lang.reflect.*;
047: import org.openide.awt.*;
048:
049: /** Hacked JPopupMenu(Plus) - displayed in JScrollPane if too long.
050: */
051: public class ScrollPopupMenu extends JPopupMenu {
052:
053: JWindow popWin;
054: JScrollPane scrollPane;
055: int posX, posY;
056: int maxHeight;
057:
058: ScrollPopupMenu(int maxH) {
059: maxHeight = maxH;
060: }
061:
062: @Override
063: public void setVisible(boolean visible) {
064: if (visible == isVisible())
065: return;
066:
067: if (visible) {
068: if (getInvoker() != null
069: && !(getInvoker() instanceof JMenu)) {
070: if (getSubElements().length > 0) {
071: MenuElement me[] = new MenuElement[2];
072: me[0] = (MenuElement) this ;
073: me[1] = getSubElements()[0];
074: MenuSelectionManager.defaultManager()
075: .setSelectedPath(me);
076: } else {
077: MenuElement me[] = new MenuElement[1];
078: me[0] = (MenuElement) this ;
079: MenuSelectionManager.defaultManager()
080: .setSelectedPath(me);
081: }
082: }
083:
084: firePopupMenuWillBecomeVisible();
085:
086: Component comp = getInvoker();
087: while (comp.getParent() != null)
088: comp = comp.getParent();
089:
090: popWin = comp instanceof Window ? new JWindow((Window) comp)
091: : new JWindow(new JFrame());
092: popWin.setLocation(posX, posY);
093:
094: pack();
095: popWin.setVisible(true);
096: } else {
097: getSelectionModel().clearSelection();
098: if (popWin != null) {
099: firePopupMenuWillBecomeInvisible();
100: popWin.dispose();
101: popWin = null;
102: scrollPane = null;
103: }
104: }
105: }
106:
107: @Override
108: public boolean isVisible() {
109: return popWin != null ? popWin.isShowing() : false;
110: }
111:
112: @Override
113: public void setLocation(int x, int y) {
114: if (popWin != null && popWin.isShowing())
115: popWin.setLocation(x, y);
116: else {
117: posX = x;
118: posY = y;
119: }
120: }
121:
122: @Override
123: public void pack() {
124: if (popWin == null)
125: return;
126:
127: Dimension prefSize = getPreferredSize();
128: if (maxHeight == 0 || prefSize.height <= maxHeight) {
129: if (scrollPane != null) {
130: popWin.getContentPane().remove(scrollPane);
131: scrollPane = null;
132: }
133: popWin.getContentPane().setLayout(null);
134: popWin.getContentPane().add(this );
135: setBounds(0, 0, prefSize.width, prefSize.height);
136: popWin.setSize(prefSize.width, prefSize.height);
137: } else {
138: if (scrollPane == null) {
139: JPanel view = new JPanel(new BorderLayout());
140: view.add(this , BorderLayout.CENTER);
141:
142: scrollPane = new JScrollPane(view);
143: scrollPane
144: .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
145: // scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
146: JScrollBar bar = scrollPane.getVerticalScrollBar();
147: if (bar != null) {
148: Dimension d = bar.getPreferredSize();
149: d.width = 12;
150: bar.setPreferredSize(d);
151: bar.setUnitIncrement(21);
152: // Issue 47181
153: doNotCancelPopupHack(bar);
154: }
155:
156: popWin.getContentPane().add(scrollPane,
157: BorderLayout.CENTER);
158: }
159: popWin.pack();
160: popWin.setSize(popWin.getSize().width + 12, maxHeight);
161: requestFocus();
162: }
163: }
164:
165: public JScrollPane getScrollPane() {
166: return scrollPane;
167: }
168:
169: public JScrollBar getScrollBar() {
170: return scrollPane != null ? scrollPane.getVerticalScrollBar()
171: : null;
172: }
173:
174: public static void doNotCancelPopupHack(JComponent component) {
175: if (System.getProperty("java.version").startsWith("1.5")) { // NOI18N
176: try {
177: Class clazz = javax.swing.plaf.basic.BasicComboBoxUI.class;
178: Field field = clazz.getDeclaredField("HIDE_POPUP_KEY"); // NOI18N
179: field.setAccessible(true);
180: component.putClientProperty("doNotCancelPopup", field
181: .get(null)); // NOI18N
182: for (int i = 0; i < component.getComponentCount(); i++) {
183: Component comp = component.getComponent(i);
184: if (comp instanceof JComponent) {
185: doNotCancelPopupHack((JComponent) comp);
186: }
187: }
188: } catch (Exception ex) {
189: ex.printStackTrace();
190: }
191: }
192: }
193: }
|