1 19 20 package org.netbeans.modules.options; 21 22 import java.awt.Color ; 23 import java.awt.Component ; 24 import java.awt.Cursor ; 25 import java.awt.Dimension ; 26 import java.awt.Font ; 27 import java.awt.Frame ; 28 import java.awt.GridBagConstraints ; 29 import java.awt.GridBagLayout ; 30 import java.awt.BorderLayout ; 31 import java.awt.SystemColor ; 32 import java.awt.Window ; 33 import java.awt.event.ActionEvent ; 34 import java.awt.event.FocusEvent ; 35 import java.awt.event.FocusListener ; 36 import java.awt.event.KeyEvent ; 37 import java.awt.event.MouseEvent ; 38 import java.awt.event.MouseListener ; 39 import java.beans.PropertyChangeEvent ; 40 import java.beans.PropertyChangeListener ; 41 import java.util.Iterator ; 42 import java.util.LinkedHashMap ; 43 import java.util.Map ; 44 import javax.swing.AbstractAction ; 45 import javax.swing.BorderFactory ; 46 import javax.swing.FocusManager ; 47 import javax.swing.Icon ; 48 import javax.swing.InputMap ; 49 import javax.swing.JComponent ; 50 import javax.swing.JLabel ; 51 import javax.swing.JPanel ; 52 import javax.swing.KeyStroke ; 53 import javax.swing.SwingUtilities ; 54 import javax.swing.UIManager ; 55 import javax.swing.border.CompoundBorder ; 56 import javax.swing.border.EmptyBorder ; 57 import javax.swing.border.LineBorder ; 58 import org.netbeans.modules.options.ui.LoweredBorder; 59 import org.netbeans.modules.options.ui.VariableBorder; 60 import org.netbeans.spi.options.OptionsPanelController; 61 import org.openide.awt.Mnemonics; 62 import org.openide.util.HelpCtx; 63 import org.openide.util.NbBundle; 64 import org.openide.util.NbPreferences; 65 import org.openide.util.RequestProcessor; 66 67 import org.openide.util.Utilities; 68 import org.openide.windows.WindowManager; 69 70 public class OptionsPanel extends JPanel { 71 private CategoryModel model = CategoryModel.getInstance(); 72 private JPanel pCategories; 73 private JPanel pCategories2; 74 private JPanel pOptions; 75 private JLabel lTitle; 76 private JPanel pTitle; 77 78 private Map <String , CategoryButton> buttons = new LinkedHashMap <String , CategoryButton>(); 79 private final boolean isMac = UIManager.getLookAndFeel ().getID ().equals ("Aqua"); 80 private Color selected = isMac ? new Color (221, 221, 221) : new Color (193, 210, 238); 81 private Color selectedB = isMac ? new Color (183, 183, 183) : new Color (149, 106, 197); 82 private Color highlighted = isMac ? new Color (221, 221, 221) : new Color (224, 232, 246); 83 private Color highlightedB = new Color (152, 180, 226); 84 private Color iconViewBorder = new Color (127, 157, 185); 85 private ControllerListener coltrollerListener = new ControllerListener (); 86 87 private final Color borderMac = new Color (141, 141, 141); 88 private final Font labelFontMac = new Font ("Lucida Grande", 0, 10); 89 90 private static String loc (String key) { 91 return NbBundle.getMessage (OptionsPanel.class, key); 92 } 93 94 95 public OptionsPanel () { 96 this(null); 97 } 98 99 public OptionsPanel (String categoryID) { 100 initUI(categoryID); 102 } 103 104 private String getCategoryID(String categoryID) { 105 return categoryID == null ? model.getCurrentCategoryID() : categoryID; 106 } 107 108 void initCurrentCategory (final String categoryID) { 109 boolean isGeneralPanel = "General".equals(getCategoryID(categoryID)); if (model.isLookupInitialized() || isGeneralPanel) { 113 setCurrentCategory(model.getCategory(getCategoryID(categoryID)), false); 114 initActions(); 115 } else { 116 RequestProcessor.getDefault().post(new Runnable () { 117 public void run() { 118 SwingUtilities.invokeLater(new Runnable () { 119 public void run() { 120 final Frame frame = WindowManager.getDefault().getMainWindow(); 122 final Cursor cursor = frame.getCursor(); 123 frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 124 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 125 setCurrentCategory(model.getCategory(getCategoryID(categoryID)), true); 126 initActions(); 127 frame.setCursor(cursor); 129 setCursor(cursor); 130 } 131 }); 132 } 133 }, 500); 134 } 135 } 136 137 private void setCurrentCategory (final CategoryModel.Category category, final boolean repaintAllowed) { 138 CategoryModel.Category oldCategory = model.getCurrent(); 139 if (oldCategory != null) { 140 ((CategoryButton) buttons.get (oldCategory.getID())).setNormal (); 141 } 142 if (category != null) { 143 ((CategoryButton) buttons.get (category.getID())).setSelected (); 144 } 145 146 model.setCurrent(category); 147 pOptions.removeAll (); 149 final Dimension size; 150 JComponent component = category.getComponent(); 151 category.update(coltrollerListener, false); 152 size = component.getSize(); 153 pOptions.add("Center",component); 154 Icon icon = category.getIcon (); 156 if (icon != null) { 157 lTitle.setIcon (icon); 158 } 159 lTitle.setText (category.getTitle ()); 160 161 SwingUtilities.invokeLater (new Runnable () { 164 public void run () { 165 if (!checkSize (size) && repaintAllowed) { 166 revalidate (); 167 repaint (); 168 } 169 if (model.getCurrent() != null) { 170 ((CategoryButton) buttons.get (model.getCurrentCategoryID())).requestFocus (); 171 } 172 } 173 }); 174 firePropertyChange ("buran" + OptionsPanelController.PROP_HELP_CTX, null, null); 175 } 176 177 HelpCtx getHelpCtx () { 178 return model.getHelpCtx (); 179 } 180 181 void update () { 182 model.update(coltrollerListener, true); 183 } 184 185 void save () { 186 model.save(); 187 } 188 189 void cancel () { 190 model.cancel(); 191 } 192 193 boolean dataValid () { 194 return model.dataValid(); 195 } 196 197 boolean isChanged () { 198 return model.isChanged(); 199 } 200 201 boolean needsReinit() { 202 return model.needsReinit(); 203 } 204 205 207 private void initUI(String categoryName) { 208 pOptions = new JPanel (); 210 pOptions.setLayout (new BorderLayout ()); 211 pOptions.setPreferredSize (getUserSize()); 212 JLabel label = new JLabel (loc ("CTL_Loading_Options")); 213 label.setHorizontalAlignment (label.CENTER); 214 pOptions.add ("Center", label); 215 216 JPanel pTitle = new JPanel (new BorderLayout ()); 218 lTitle = new JLabel (); 219 if (Utilities.isWindows ()) { 220 lTitle.setBackground (SystemColor.activeCaption); 221 lTitle.setForeground (SystemColor.activeCaptionText); 222 } else { 223 lTitle.setBackground (Color.white); 224 lTitle.setForeground (Color.black); 225 } 226 Font f = lTitle.getFont (); 227 lTitle.setFont (new Font (f.getName (), Font.BOLD, 16)); 228 lTitle.setIconTextGap (8); 229 lTitle.setOpaque (true); 230 if (Utilities.isWindows ()) { 231 pTitle.setBorder (new CompoundBorder ( 232 new LoweredBorder (), 233 new LineBorder (SystemColor.activeCaption, 1) 234 )); 235 } else { 236 pTitle.setBorder (new CompoundBorder ( 237 new LineBorder (iconViewBorder, 1), 238 new LineBorder (Color.white, 2) 239 )); 240 } 241 242 pTitle.add ("Center", lTitle); 243 244 pCategories2 = new JPanel (new GridBagLayout ()); 246 pCategories2.setBackground (Color.white); 247 pCategories2.setBorder (null); 248 addCategoryButtons(); 249 250 pCategories = new JPanel (new BorderLayout ()); 251 if (isMac) { 252 pCategories.setBorder (new CompoundBorder ( 253 new VariableBorder (null, null, borderMac, null), 254 BorderFactory.createEmptyBorder (0, 4, 0, 4) 255 )); 256 } else { 257 pCategories.setBorder (new LineBorder (iconViewBorder)); 258 } 259 pCategories.setBackground (Color.white); 260 pCategories.add ("North", pCategories2); 261 262 setLayout (new BorderLayout (10, 10)); 264 if (isMac) { 265 pOptions.setBorder (new CompoundBorder ( 266 new VariableBorder (null, null, borderMac, null), 267 BorderFactory.createEmptyBorder (0, 20, 5, 20) 268 )); 269 add (pCategories, BorderLayout.NORTH); 270 add (pOptions, BorderLayout.CENTER); 271 } else { 272 JPanel centralPanel = new JPanel (new BorderLayout (10, 10)); 273 centralPanel.add (pTitle, BorderLayout.NORTH); 274 centralPanel.add (pOptions, BorderLayout.CENTER); 275 add (pCategories, BorderLayout.WEST); 276 add (centralPanel, BorderLayout.CENTER); 277 setBorder (new EmptyBorder (10, 10, 0, 10)); 278 } 279 280 categoryName = getCategoryID(categoryName); 281 if (categoryName != null) { 282 CategoryModel.Category c = model.getCategory(getCategoryID(categoryName)); 283 Icon icon = c.getIcon(); 284 if (icon != null) { 285 lTitle.setIcon(icon); 286 } 287 lTitle.setText(c.getTitle()); 288 289 CategoryButton b = (CategoryButton) buttons.get(categoryName); 290 if (b != null) { 291 b.setSelected(); 292 } 293 } 294 } 295 296 private void initActions () { 297 if (getActionMap ().get("UP") == null) { 298 InputMap inputMap = getInputMap 299 (JComponent.WHEN_IN_FOCUSED_WINDOW); 300 inputMap.put ( 301 isMac ? KeyStroke.getKeyStroke (KeyEvent.VK_LEFT, 0) : 302 KeyStroke.getKeyStroke (KeyEvent.VK_UP, 0), 303 "UP" 304 ); 305 getActionMap ().put ("UP", new UpAction ()); 306 inputMap.put ( 307 KeyStroke.getKeyStroke (KeyEvent.VK_SPACE, 0), 308 "SPACE" 309 ); 310 getActionMap ().put ("SPACE", new SelectCurrentAction ()); 311 inputMap.put ( 312 isMac ? KeyStroke.getKeyStroke (KeyEvent.VK_RIGHT, 0) : 313 KeyStroke.getKeyStroke (KeyEvent.VK_DOWN, 0), 314 "DOWN" 315 ); 316 getActionMap ().put ("DOWN", new DownAction ()); 317 } 318 } 319 320 private void addCategoryButtons () { 321 Iterator it = buttons.values().iterator (); 323 while (it.hasNext ()) { 324 removeButton ((CategoryButton) it.next ()); 325 } 326 pCategories2.removeAll (); 327 buttons = new LinkedHashMap <String , CategoryButton>(); 328 329 String [] names = model.getCategoryIDs(); 331 for (int i = 0; i < names.length; i++) { 332 CategoryModel.Category category = model.getCategory(names[i]); 333 addButton (category); 334 } 335 336 addFakeButton (); 337 } 338 339 private void addButton (CategoryModel.Category category) { 340 int index = buttons.size (); 341 CategoryButton button = new CategoryButton (category); 342 343 KeyStroke keyStroke = KeyStroke.getKeyStroke 345 (button.getDisplayedMnemonic (), KeyEvent.ALT_MASK); 346 getInputMap (JComponent.WHEN_IN_FOCUSED_WINDOW).put (keyStroke, button); 347 getActionMap ().put (button, new SelectAction (category)); 348 349 if (isMac) { 350 GridBagConstraints gbc = new GridBagConstraints (); 351 gbc.anchor = GridBagConstraints.NORTHWEST; 352 gbc.fill = GridBagConstraints.VERTICAL; 353 gbc.weightx = 0.0; 354 gbc.weighty = 1.0; 355 gbc.gridx = index; 356 gbc.gridy = 0; 357 pCategories2.add (button, gbc); 358 } else { 359 GridBagConstraints gbc = new GridBagConstraints (); 360 gbc.anchor = GridBagConstraints.NORTHWEST; 361 gbc.fill = GridBagConstraints.HORIZONTAL; 362 gbc.weightx = 1.0; 363 gbc.weighty = 0.0; 364 gbc.gridx = 0; 365 gbc.gridy = index; 366 pCategories2.add (button, gbc); 367 } 368 buttons.put (category.getID(), button); 369 } 370 371 private void removeButton (CategoryButton button) { 372 KeyStroke keyStroke = KeyStroke.getKeyStroke 373 (button.getDisplayedMnemonic (), KeyEvent.ALT_MASK); 374 getInputMap (JComponent.WHEN_IN_FOCUSED_WINDOW).remove (keyStroke); 375 getActionMap ().remove (button); 376 } 377 378 private void addFakeButton () { 379 380 GridBagConstraints gbc = new GridBagConstraints (); 381 gbc.fill = GridBagConstraints.BOTH; 382 gbc.weightx = 1.0; 383 gbc.weighty = 1.0; 384 if (isMac) 385 gbc.gridy = 0; 386 else 387 gbc.gridx = 0; 388 pCategories2.add (new javax.swing.JLabel (""), gbc); 389 } 390 391 private Dimension getInitSize() { 392 return new Dimension (750, 500); 395 } 396 397 Dimension getUserSize() { 398 int w = NbPreferences.forModule(OptionsPanel.class).getInt("OptionsWidth",getInitSize().width); int h = NbPreferences.forModule(OptionsPanel.class).getInt("OptionsHeight",getInitSize().height); return new Dimension (w, h); 401 } 402 403 void storeUserSize() { 404 Dimension d = pOptions.getSize(); 405 NbPreferences.forModule(OptionsPanel.class).putInt("OptionsWidth",d.width); NbPreferences.forModule(OptionsPanel.class).putInt("OptionsHeight",d.height); pOptions.setPreferredSize(d); 408 } 409 410 private boolean checkSize(Dimension componentSize) { 411 boolean retval = false; 412 Dimension prefSize = pOptions.getPreferredSize(); 413 Dimension userSize = getUserSize(); 414 componentSize = new Dimension (Math.max(componentSize.width, userSize.width),Math.max(componentSize.height, userSize.height)); 415 if (prefSize.width < componentSize.width || prefSize.height < componentSize.height) { 416 Dimension newSize = new Dimension (Math.max(prefSize.width, componentSize.width),Math.max(prefSize.height, componentSize.height)); 417 pOptions.setPreferredSize(newSize); 418 Window w = (Window ) SwingUtilities.getAncestorOfClass(Window .class, this); 419 invalidate(); 420 if (w != null) w.pack(); 421 retval = true; 422 } 423 return retval; 424 } 425 426 428 private class SelectAction extends AbstractAction { 429 private CategoryModel.Category category; 430 431 SelectAction (CategoryModel.Category category) { 432 this.category = category; 433 } 434 public void actionPerformed (ActionEvent e) { 435 setCurrentCategory (category, true); 436 } 437 } 438 439 private class SelectCurrentAction extends AbstractAction { 440 public void actionPerformed (ActionEvent e) { 441 Component c = FocusManager.getCurrentManager ().getFocusOwner (); 442 if (c instanceof CategoryButton) { 443 setCurrentCategory (((CategoryButton) c).category, true); 444 ((CategoryButton) c).setSelected (); 445 } 446 } 447 } 448 449 private class UpAction extends AbstractAction { 450 public void actionPerformed (ActionEvent e) { 451 model.setPreviousCategoryAsCurrent(); 452 setCurrentCategory (model.getCurrent(), true); 453 } 454 } 455 456 private class DownAction extends AbstractAction { 457 public void actionPerformed (ActionEvent e) { 458 model.setNextCategoryAsCurrent(); 459 setCurrentCategory (model.getCurrent(), true); 460 } 461 } 462 463 class ControllerListener implements PropertyChangeListener { 464 public void propertyChange (PropertyChangeEvent evt) { 465 OptionsPanel.this.firePropertyChange 466 ("buran" + evt.getPropertyName (), null, null); 467 } 468 } 469 470 class CategoryButton extends JLabel implements MouseListener { 471 private final CategoryModel.Category category; 472 CategoryButton (final CategoryModel.Category category) { 473 super (category.getIcon()); 474 this.category = category; 475 Mnemonics.setLocalizedText (this, category.getCategoryName()); 476 setOpaque (true); 477 setVerticalTextPosition (BOTTOM); 478 setHorizontalTextPosition (CENTER); 479 setHorizontalAlignment (CENTER); 480 addMouseListener (this); 481 setFocusable (true); 482 setFocusTraversalKeysEnabled (true); 483 setForeground (Color.black); 484 485 if (isMac) { 486 setFont(labelFontMac); 487 setIconTextGap(2); 488 } 489 490 setNormal (); 491 addFocusListener(new FocusListener () { 492 public void focusGained(FocusEvent e) { 493 if (model.getCurrent() != null && !category.isCurrent()) { 494 setHighlighted(); 495 } 496 } 497 public void focusLost(FocusEvent e) { 498 if (model.getCurrent() != null && !category.isCurrent() && !isMac) { 499 setNormal(); 500 } 501 } 502 }); 503 } 504 505 void setNormal () { 506 if (isMac) { 507 setBorder (new EmptyBorder (5, 6, 3, 6)); 508 } else { 509 setBorder (new EmptyBorder (2, 4, 2, 4)); 510 } 511 setBackground (Color.white); 512 } 513 514 void setSelected () { 515 if (isMac) { 516 setBorder(new CompoundBorder ( 517 new VariableBorder(null, selectedB, null, selectedB), 518 BorderFactory.createEmptyBorder(5, 5, 3, 5) 519 )); 520 } else { 521 setBorder (new CompoundBorder ( 522 new CompoundBorder ( 523 new LineBorder (Color.white), 524 new LineBorder (selectedB) 525 ), 526 new EmptyBorder (0, 2, 0, 2) 527 )); 528 } 529 setBackground (selected); 530 } 531 532 void setHighlighted() { 533 if (!isMac) { 534 setBorder(new CompoundBorder ( 535 new CompoundBorder ( 536 new LineBorder (Color.white), 537 new LineBorder (highlightedB) 538 ), 539 new EmptyBorder (0, 2, 0, 2) 540 )); 541 setBackground(highlighted); 542 } 543 if (!category.isHighlited()) { 544 if (model.getHighlitedCategoryID() != null) { 545 CategoryButton b = (CategoryButton)buttons.get(model.getHighlitedCategoryID()); 546 if (b != null && !b.category.isCurrent()) { 547 b.setNormal(); 548 } 549 } 550 model.setHighlited(category); 551 } 552 } 553 554 public void mouseClicked (MouseEvent e) { 555 } 556 557 public void mousePressed (MouseEvent e) { 558 if (!isMac && model.getCurrent() != null) { 559 setSelected (); 560 } 561 } 562 563 public void mouseReleased (MouseEvent e) { 564 if (!category.isCurrent() && category.isHighlited() && model.getCurrent() != null) { 565 setCurrentCategory(category, true); 566 } 567 } 568 569 public void mouseEntered (MouseEvent e) { 570 if (!category.isCurrent() && model.getCurrent() != null) { 571 setHighlighted (); 572 } 573 } 574 575 public void mouseExited (MouseEvent e) { 576 if (!category.isCurrent() && !isMac && model.getCurrent() != null) { 577 setNormal (); 578 } 579 } 580 } 581 } 582 | Popular Tags |