1 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 ; 26 27 import org.openide.nodes.*; 28 import org.openide.util.*; 29 import org.openide.explorer.view.MenuView; 30 31 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(); } 62 63 66 public JPopupMenu getPopupMenu() { 67 if (!hacked) { 68 try { 69 Field f = JMenu.class.getDeclaredField("popupMenu"); 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 ex) { 79 System.out.println("[WARNING] Cannot create scrollable popup menu."); } 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")); 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; 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 Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize(); 136 Dimension s = getSize(); 137 Dimension pmSize = pm.getSize(); 138 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 154 if( getComponentOrientation().isLeftToRight() ) { 155 if (position.x+s.width + pmSize.width < screenSize.width) { 157 x = s.width; } else { 159 x = 0-pmSize.width; } 161 } else { 162 if (position.x < pmSize.width) { 164 x = s.width; } else { 166 x = 0-pmSize.width; } 168 } 169 if (position.y+pmSize.height < screenSize.height) { 171 y = 0; } else { 173 y = s.height-pmSize.height; if (y < -position.y) 175 y = -position.y + 6; 176 } 177 } else { 178 180 if( getComponentOrientation().isLeftToRight() ) { 181 if (position.x+pmSize.width < screenSize.width) { 183 x = 0; } else { 185 x = s.width-pmSize.width; } 187 } else { 188 if (position.x+s.width < pmSize.width) { 190 x = 0; } else { 192 x = s.width-pmSize.width; } 194 } 195 if (position.y+s.height+pmSize.height < screenSize.height) { 197 y = s.height; } else { 199 y = -pmSize.height; } 201 } 202 return new Point(x,y); 203 } 204 } 205 | Popular Tags |