KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > palette > PaletteMenuView


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.form.palette;
21
22 import java.awt.*;
23 import javax.swing.*;
24 import javax.swing.event.*;
25 import java.lang.reflect.Field JavaDoc;
26
27 import org.openide.nodes.*;
28 import org.openide.util.*;
29 import org.openide.explorer.view.MenuView;
30
31 /**
32  * Hacked MenuView.Menu to use ScrollablePopupMenu instead of JPopupMenu
33  * as its popup, and to filter invalid palette item nodes.
34  */

35
36 public class PaletteMenuView extends org.openide.awt.JMenuPlus {
37
38     private Node menuNode;
39     private NodeAcceptor menuAction;
40
41     private boolean hacked = false;
42     private boolean filled = false;
43     private int level;
44
45     private static int maxHeight = Utilities.getUsableScreenBounds().height - 25;
46
47     public PaletteMenuView(NodeAcceptor acceptor) {
48         this(PaletteUtils.getPaletteNode(), acceptor);
49     }
50
51     public PaletteMenuView(Node node, NodeAcceptor acceptor) {
52         this(node, acceptor, 0);
53     }
54
55     private PaletteMenuView(Node node, NodeAcceptor acceptor, int level) {
56         menuNode = node;
57         menuAction = acceptor;
58         this.level = level;
59         setText(node.getDisplayName());
60         getSubNodes(); // force subnodes creation
61
}
62
63     /** popupMenu field should be set here because getPopupMenu() is called from
64      * superclass constructor.
65      */

66     public JPopupMenu getPopupMenu() {
67         if (!hacked) {
68             try {
69                 Field JavaDoc f = JMenu.class.getDeclaredField("popupMenu"); // NOI18N
70
f.setAccessible(true);
71                 if (f.get(this) == null) {
72                     ScrollPopupMenu popup = new ScrollPopupMenu(maxHeight);
73                     popup.setInvoker(this);
74                     f.set(this, popup);
75                 }
76                 hacked = true;
77             }
78             catch (Exception JavaDoc ex) {
79                 System.out.println("[WARNING] Cannot create scrollable popup menu."); // NOI18N
80
}
81         }
82
83         JPopupMenu popup = super.getPopupMenu();
84         fillSubMenu(popup);
85         return popup;
86     }
87
88     private void fillSubMenu(JPopupMenu popup) {
89         if (!filled) {
90             filled = true;
91             popup.addPopupMenuListener(new PopupListener(popup));
92             removeAll();
93
94             Node[] nodes = getSubNodes();
95             if (nodes.length > 0) {
96                 for (int i=0; i < nodes.length; i++)
97                     add(nodes[i].isLeaf() ?
98                        (JMenuItem) new MenuView.MenuItem(nodes[i], menuAction) :
99                        (JMenuItem) new PaletteMenuView(nodes[i], menuAction, level + 1));
100             }
101             else {
102                 JMenuItem empty = new JMenuItem(
103                     PaletteUtils.getBundleString("CTL_EmptyPaletteMenu")); // NOI18N
104
empty.setEnabled(false);
105                 add(empty);
106             }
107         }
108     }
109
110     private Node[] getSubNodes() {
111         return level == 0 ? PaletteUtils.getCategoryNodes(menuNode, true) :
112                             PaletteUtils.getItemNodes(menuNode, true);
113     }
114
115     private class PopupListener implements PopupMenuListener {
116         private JPopupMenu popup;
117
118         PopupListener(JPopupMenu popup) {
119             this.popup = popup;
120         }
121
122         public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
123             filled = false; // clear the status and stop listening
124
popup.removePopupMenuListener(this);
125         }
126         public void popupMenuCanceled(PopupMenuEvent e) {}
127         public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
128     }
129
130     protected Point getPopupMenuOrigin() {
131         int x = 0;
132         int y = 0;
133         JPopupMenu pm = getPopupMenu();
134         // Figure out the sizes needed to caclulate the menu position
135
Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize();
136         Dimension s = getSize();
137         Dimension pmSize = pm.getSize();
138         // For the first time the menu is popped up,
139
// the size has not yet been initiated
140
if (pmSize.width==0) {
141             pmSize = pm.getPreferredSize();
142         }
143         if (pmSize.height > maxHeight) {
144             pmSize.height = maxHeight + 2;
145             pmSize.width += 14;
146         }
147
148         Point position = getLocationOnScreen();
149
150         Container parent = getParent();
151         if (parent instanceof JPopupMenu) {
152             // We are a submenu (pull-right)
153

154             if( getComponentOrientation().isLeftToRight() ) {
155                 // First determine x:
156
if (position.x+s.width + pmSize.width < screenSize.width) {
157                     x = s.width; // Prefer placement to the right
158
} else {
159                     x = 0-pmSize.width; // Otherwise place to the left
160
}
161             } else {
162                 // First determine x:
163
if (position.x < pmSize.width) {
164                     x = s.width; // Prefer placement to the right
165
} else {
166                     x = 0-pmSize.width; // Otherwise place to the left
167
}
168             }
169             // Then the y:
170
if (position.y+pmSize.height < screenSize.height) {
171                 y = 0; // Prefer dropping down
172
} else {
173                 y = s.height-pmSize.height; // Otherwise drop 'up'
174
if (y < -position.y)
175                     y = -position.y + 6;
176             }
177         } else {
178             // We are a toplevel menu (pull-down)
179

180             if( getComponentOrientation().isLeftToRight() ) {
181                 // First determine the x:
182
if (position.x+pmSize.width < screenSize.width) {
183                     x = 0; // Prefer extending to right
184
} else {
185                     x = s.width-pmSize.width; // Otherwise extend to left
186
}
187             } else {
188                 // First determine the x:
189
if (position.x+s.width < pmSize.width) {
190                     x = 0; // Prefer extending to right
191
} else {
192                     x = s.width-pmSize.width; // Otherwise extend to left
193
}
194             }
195             // Then the y:
196
if (position.y+s.height+pmSize.height < screenSize.height) {
197                 y = s.height; // Prefer dropping down
198
} else {
199                 y = -pmSize.height; // Otherwise drop 'up'
200
}
201         }
202         return new Point(x,y);
203     }
204 }
205
Popular Tags