1 19 package org.openide.awt; 20 21 import org.openide.util.RequestProcessor; 22 import org.openide.util.Utilities; 23 24 import java.awt.*; 25 26 import java.util.StringTokenizer ; 27 28 import javax.swing.JMenu ; 29 import javax.swing.JPopupMenu ; 30 import javax.swing.SwingUtilities ; 31 32 33 46 public class JPopupMenuUtils { 47 private static boolean problemTested = false; 48 private static boolean problem = false; 49 private static RequestProcessor reqProc; 50 private static RequestProcessor.Task task; 51 53 60 public static void dynamicChange(final JPopupMenu popup, boolean usedToBeContained) { 61 if (!popup.isShowing()) { 62 return; 63 } 64 65 if (isProblemConfig()) { 66 callRefreshLater(popup); 67 68 return; 69 } 70 71 refreshPopup(popup); 72 73 Point p = popup.getLocationOnScreen(); 74 Point newPt = getPopupMenuOrigin(popup, p); 75 76 boolean willBeContained = willPopupBeContained(popup, newPt); 77 78 if (usedToBeContained != willBeContained) { 79 popup.setVisible(false); 80 } 81 82 if (!newPt.equals(p)) { 83 } 87 88 if (usedToBeContained != willBeContained) { 89 popup.setVisible(true); 90 } 91 } 92 93 94 private static void refreshPopup(JPopupMenu popup) { 95 popup.pack(); 96 popup.invalidate(); 97 98 Component c = popup.getParent(); 99 100 if (c != null) { 101 c.validate(); 102 } 103 } 104 105 108 private static void callRefreshLater(final JPopupMenu popup) { 109 if (reqProc == null) { 111 reqProc = new RequestProcessor(); 112 } 113 114 if (task == null) { 115 task = reqProc.create( 116 new Runnable () { 117 public void run() { 118 SwingUtilities.invokeLater( 119 new Runnable () { 120 public void run() { 121 task = null; 122 123 if (!popup.isShowing()) { 126 return; 127 } 128 129 Point p = popup.getLocationOnScreen(); 130 Point newPt = getPopupMenuOrigin(popup, p); 131 popup.setVisible(false); 132 refreshPopup(popup); 133 134 if (!newPt.equals(p)) { 135 } 139 140 popup.setVisible(true); 141 } 142 } 143 ); 144 } 145 } 146 ); 147 } 148 149 task.schedule(100); 150 } 151 152 158 private static boolean isProblemConfig() { 159 if (problemTested) { 161 return problem; 162 } 163 164 problem = false; 165 166 String needHack = System.getProperty("netbeans.popup.linuxhack"); 167 168 if (needHack != null) { 169 problem = true; 170 } 171 172 return problem; 173 } 174 175 184 public static void dynamicChangeToSubmenu(JPopupMenu popup, boolean usedToBeContained) { 185 Object invoker = popup.getInvoker(); 186 187 if (!(invoker instanceof JMenu )) { 188 return; 189 } 190 191 JMenu menu = (JMenu ) invoker; 192 193 if (!popup.isShowing()) { 194 return; 195 } 196 197 if (isProblemConfig()) { 198 callRefreshLater2(popup, menu); 199 200 return; 201 } 202 203 refreshPopup(popup); 204 205 Point p = popup.getLocationOnScreen(); 206 Dimension popupSize = popup.getPreferredSize(); 207 Rectangle popupRect = new Rectangle(p, popupSize); 208 Rectangle screenRect = getScreenRect(); 209 boolean willBeContained = isPopupContained(popup); 210 211 if (!screenRect.contains(popupRect)) { 212 215 menu.setPopupMenuVisible(false); 216 menu.setPopupMenuVisible(true); 217 } else if (usedToBeContained != willBeContained) { 218 223 popup.setVisible(false); 224 popup.setVisible(true); 225 } 226 } 227 228 231 private static void callRefreshLater2(final JPopupMenu popup, final JMenu menu) { 232 if (reqProc == null) { 234 reqProc = new RequestProcessor(); 235 } 236 237 if (task == null) { 238 task = reqProc.create( 239 new Runnable () { 240 public void run() { 241 SwingUtilities.invokeLater( 242 new Runnable () { 243 public void run() { 244 task = null; 245 246 if (!popup.isShowing()) { 249 return; 250 } 251 252 popup.setVisible(false); 253 refreshPopup(popup); 254 popup.setVisible(true); 255 256 Point p = popup.getLocationOnScreen(); 257 Dimension popupSize = popup.getPreferredSize(); 258 Rectangle popupRect = new Rectangle(p, popupSize); 259 Rectangle screenRect = getScreenRect(); 260 261 if (!screenRect.contains(popupRect)) { 262 menu.setPopupMenuVisible(false); 263 menu.setPopupMenuVisible(true); 264 } 265 } 266 } 267 ); 268 } 269 } 270 ); 271 } 272 273 task.schedule(100); 274 } 275 276 285 static Point getPopupMenuOrigin(JPopupMenu popup, Point p) { 286 Point newPt = new Point(p); 287 Dimension popupSize = popup.getPreferredSize(); 288 Rectangle screenRect = getScreenRect(); 289 int popupRight = newPt.x + popupSize.width; 290 int popupBottom = newPt.y + popupSize.height; 291 int screenRight = screenRect.x + screenRect.width; 292 int screenBottom = screenRect.y + screenRect.height; 293 294 if (popupRight > screenRight) { newPt.x = screenRight - popupSize.width; 296 } 297 298 if (newPt.x < screenRect.x) { newPt.x = screenRect.x; 300 } 301 302 if (popupBottom > screenBottom) { newPt.y = screenBottom - popupSize.height; 304 } 305 306 if (newPt.y < screenRect.y) { newPt.y = screenRect.y; 308 } 309 310 return newPt; 311 } 312 313 319 public static boolean isPopupContained(JPopupMenu popup) { 320 if (!popup.isShowing()) { 321 return false; 322 } 323 324 return willPopupBeContained(popup, popup.getLocationOnScreen()); 325 } 326 327 336 private static boolean willPopupBeContained(JPopupMenu popup, Point origin) { 337 if (!popup.isShowing()) { 338 return false; 339 } 340 341 Window w = SwingUtilities.windowForComponent(popup.getInvoker()); 342 Rectangle r = new Rectangle(origin, popup.getSize()); 343 344 return (w != null) && w.getBounds().contains(r); 345 } 346 347 356 public static Rectangle getScreenRect() { 357 return Utilities.getUsableScreenBounds(); 358 } 359 } 360 | Popular Tags |