1 /* 2 * 3 * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of Oracle nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 import javax.swing.*; 34 import javax.swing.event.*; 35 import javax.swing.border.*; 36 37 import javax.swing.plaf.metal.MetalTheme; 38 import javax.swing.plaf.metal.OceanTheme; 39 import javax.swing.plaf.metal.DefaultMetalTheme; 40 import javax.swing.plaf.metal.MetalLookAndFeel; 41 42 import java.lang.reflect.*; 43 import java.awt.*; 44 import java.awt.event.*; 45 import java.util.*; 46 47 /** 48 * A demo that shows all of the Swing components. 49 * 50 * @author Jeff Dinkins 51 */ 52 public class SwingSet2 extends JPanel { 53 54 String[] demos = { 55 "ButtonDemo", 56 "ColorChooserDemo", 57 "ComboBoxDemo", 58 "FileChooserDemo", 59 "HtmlDemo", 60 "ListDemo", 61 "OptionPaneDemo", 62 "ProgressBarDemo", 63 "ScrollPaneDemo", 64 "SliderDemo", 65 "SplitPaneDemo", 66 "TabbedPaneDemo", 67 "TableDemo", 68 "ToolTipDemo", 69 "TreeDemo" 70 }; 71 loadDemos()72 void loadDemos() { 73 for(int i = 0; i < demos.length;) { 74 if(isApplet() && demos[i].equals("FileChooserDemo")) { 75 // don't load the file chooser demo if we are 76 // an applet 77 } else { 78 loadDemo(demos[i]); 79 } 80 i++; 81 } 82 } 83 84 // The current Look & Feel 85 private static LookAndFeelData currentLookAndFeel; 86 private static LookAndFeelData[] lookAndFeelData; 87 // List of demos 88 private ArrayList<DemoModule> demosList = new ArrayList<DemoModule>(); 89 90 // The preferred size of the demo 91 private static final int PREFERRED_WIDTH = 720; 92 private static final int PREFERRED_HEIGHT = 640; 93 94 // Box spacers 95 private Dimension HGAP = new Dimension(1,5); 96 private Dimension VGAP = new Dimension(5,1); 97 98 // A place to hold on to the visible demo 99 private DemoModule currentDemo = null; 100 private JPanel demoPanel = null; 101 102 // About Box 103 private JDialog aboutBox = null; 104 105 // Status Bar 106 private JTextField statusField = null; 107 108 // Tool Bar 109 private ToggleButtonToolBar toolbar = null; 110 private ButtonGroup toolbarGroup = new ButtonGroup(); 111 112 // Menus 113 private JMenuBar menuBar = null; 114 private JMenu lafMenu = null; 115 private JMenu themesMenu = null; 116 private JMenu audioMenu = null; 117 private JMenu optionsMenu = null; 118 private ButtonGroup lafMenuGroup = new ButtonGroup(); 119 private ButtonGroup themesMenuGroup = new ButtonGroup(); 120 private ButtonGroup audioMenuGroup = new ButtonGroup(); 121 122 // Popup menu 123 private JPopupMenu popupMenu = null; 124 private ButtonGroup popupMenuGroup = new ButtonGroup(); 125 126 // Used only if swingset is an application 127 private JFrame frame = null; 128 129 // Used only if swingset is an applet 130 private SwingSet2Applet applet = null; 131 132 // To debug or not to debug, that is the question 133 private boolean DEBUG = true; 134 private int debugCounter = 0; 135 136 // The tab pane that holds the demo 137 private JTabbedPane tabbedPane = null; 138 139 private JEditorPane demoSrcPane = null; 140 141 142 // contentPane cache, saved from the applet or application frame 143 Container contentPane = null; 144 145 146 // number of swingsets - for multiscreen 147 // keep track of the number of SwingSets created - we only want to exit 148 // the program when the last one has been closed. 149 private static int numSSs = 0; 150 private static Vector<SwingSet2> swingSets = new Vector<SwingSet2>(); 151 152 private boolean dragEnabled = false; 153 SwingSet2(SwingSet2Applet applet)154 public SwingSet2(SwingSet2Applet applet) { 155 this(applet, null); 156 } 157 158 /** 159 * SwingSet2 Constructor 160 */ SwingSet2(SwingSet2Applet applet, GraphicsConfiguration gc)161 public SwingSet2(SwingSet2Applet applet, GraphicsConfiguration gc) { 162 163 // Note that applet may be null if this is started as an application 164 this.applet = applet; 165 166 String lafClassName = UIManager.getLookAndFeel().getClass().getName(); 167 lookAndFeelData = getInstalledLookAndFeelData(); 168 currentLookAndFeel = Arrays.stream(lookAndFeelData) 169 .filter(laf -> lafClassName.equals(laf.className)) 170 .findFirst().get(); 171 172 if (!isApplet()) { 173 frame = createFrame(gc); 174 } 175 176 // set the layout 177 setLayout(new BorderLayout()); 178 179 // set the preferred size of the demo 180 setPreferredSize(new Dimension(PREFERRED_WIDTH,PREFERRED_HEIGHT)); 181 182 initializeDemo(); 183 preloadFirstDemo(); 184 185 showSwingSet2(); 186 187 // Start loading the rest of the demo in the background 188 DemoLoadThread demoLoader = new DemoLoadThread(this); 189 demoLoader.start(); 190 } 191 192 193 /** 194 * SwingSet2 Main. Called only if we're an application, not an applet. 195 */ main(final String[] args)196 public static void main(final String[] args) { 197 // must run in EDT when constructing the GUI components 198 SwingUtilities.invokeLater(() -> { 199 // Create SwingSet on the default monitor 200 UIManager.put("swing.boldMetal", Boolean.FALSE); 201 SwingSet2 swingset = new SwingSet2(null, GraphicsEnvironment. 202 getLocalGraphicsEnvironment(). 203 getDefaultScreenDevice(). 204 getDefaultConfiguration()); 205 }); 206 } 207 208 // ******************************************************* 209 // *************** Demo Loading Methods ****************** 210 // ******************************************************* 211 212 213 initializeDemo()214 public void initializeDemo() { 215 JPanel top = new JPanel(); 216 top.setLayout(new BorderLayout()); 217 add(top, BorderLayout.NORTH); 218 219 menuBar = createMenus(); 220 221 if (isApplet()) { 222 applet.setJMenuBar(menuBar); 223 } else { 224 frame.setJMenuBar(menuBar); 225 } 226 227 // creates popup menu accessible via keyboard 228 popupMenu = createPopupMenu(); 229 230 ToolBarPanel toolbarPanel = new ToolBarPanel(); 231 toolbarPanel.setLayout(new BorderLayout()); 232 toolbar = new ToggleButtonToolBar(); 233 toolbarPanel.add(toolbar, BorderLayout.CENTER); 234 top.add(toolbarPanel, BorderLayout.SOUTH); 235 toolbarPanel.addContainerListener(toolbarPanel); 236 237 tabbedPane = new JTabbedPane(); 238 add(tabbedPane, BorderLayout.CENTER); 239 tabbedPane.getModel().addChangeListener(new TabListener()); 240 241 statusField = new JTextField(""); 242 statusField.setEditable(false); 243 add(statusField, BorderLayout.SOUTH); 244 245 demoPanel = new JPanel(); 246 demoPanel.setLayout(new BorderLayout()); 247 demoPanel.setBorder(new EtchedBorder()); 248 tabbedPane.addTab("Hi There!", demoPanel); 249 250 // Add html src code viewer 251 demoSrcPane = new JEditorPane("text/html", getString("SourceCode.loading")); 252 demoSrcPane.setEditable(false); 253 254 JScrollPane scroller = new JScrollPane(); 255 scroller.getViewport().add(demoSrcPane); 256 257 tabbedPane.addTab( 258 getString("TabbedPane.src_label"), 259 null, 260 scroller, 261 getString("TabbedPane.src_tooltip") 262 ); 263 } 264 265 DemoModule currentTabDemo = null; 266 class TabListener implements ChangeListener { stateChanged(ChangeEvent e)267 public void stateChanged(ChangeEvent e) { 268 SingleSelectionModel model = (SingleSelectionModel) e.getSource(); 269 boolean srcSelected = model.getSelectedIndex() == 1; 270 if(currentTabDemo != currentDemo && demoSrcPane != null && srcSelected) { 271 demoSrcPane.setText(getString("SourceCode.loading")); 272 repaint(); 273 } 274 if(currentTabDemo != currentDemo && srcSelected) { 275 currentTabDemo = currentDemo; 276 setSourceCode(currentDemo); 277 } 278 } 279 } 280 281 282 /** 283 * Create menus 284 */ createMenus()285 public JMenuBar createMenus() { 286 JMenuItem mi; 287 // ***** create the menubar **** 288 JMenuBar menuBar = new JMenuBar(); 289 menuBar.getAccessibleContext().setAccessibleName( 290 getString("MenuBar.accessible_description")); 291 292 // ***** create File menu 293 JMenu fileMenu = (JMenu) menuBar.add(new JMenu(getString("FileMenu.file_label"))); 294 fileMenu.setMnemonic(getMnemonic("FileMenu.file_mnemonic")); 295 fileMenu.getAccessibleContext().setAccessibleDescription(getString("FileMenu.accessible_description")); 296 297 createMenuItem(fileMenu, "FileMenu.about_label", "FileMenu.about_mnemonic", 298 "FileMenu.about_accessible_description", new AboutAction(this)); 299 300 fileMenu.addSeparator(); 301 302 createMenuItem(fileMenu, "FileMenu.open_label", "FileMenu.open_mnemonic", 303 "FileMenu.open_accessible_description", null); 304 305 createMenuItem(fileMenu, "FileMenu.save_label", "FileMenu.save_mnemonic", 306 "FileMenu.save_accessible_description", null); 307 308 createMenuItem(fileMenu, "FileMenu.save_as_label", "FileMenu.save_as_mnemonic", 309 "FileMenu.save_as_accessible_description", null); 310 311 312 if(!isApplet()) { 313 fileMenu.addSeparator(); 314 315 createMenuItem(fileMenu, "FileMenu.exit_label", "FileMenu.exit_mnemonic", 316 "FileMenu.exit_accessible_description", new ExitAction(this) 317 ); 318 } 319 320 // Create these menu items for the first SwingSet only. 321 if (numSSs == 0) { 322 // ***** create laf switcher menu 323 lafMenu = (JMenu) menuBar.add(new JMenu(getString("LafMenu.laf_label"))); 324 lafMenu.setMnemonic(getMnemonic("LafMenu.laf_mnemonic")); 325 lafMenu.getAccessibleContext().setAccessibleDescription( 326 getString("LafMenu.laf_accessible_description")); 327 328 for (LookAndFeelData lafData : lookAndFeelData) { 329 mi = createLafMenuItem(lafMenu, lafData); 330 mi.setSelected(lafData.equals(currentLookAndFeel)); 331 } 332 333 // ***** create themes menu 334 themesMenu = (JMenu) menuBar.add(new JMenu(getString("ThemesMenu.themes_label"))); 335 themesMenu.setMnemonic(getMnemonic("ThemesMenu.themes_mnemonic")); 336 themesMenu.getAccessibleContext().setAccessibleDescription( 337 getString("ThemesMenu.themes_accessible_description")); 338 339 // ***** create the audio submenu under the theme menu 340 audioMenu = (JMenu) themesMenu.add(new JMenu(getString("AudioMenu.audio_label"))); 341 audioMenu.setMnemonic(getMnemonic("AudioMenu.audio_mnemonic")); 342 audioMenu.getAccessibleContext().setAccessibleDescription( 343 getString("AudioMenu.audio_accessible_description")); 344 345 createAudioMenuItem(audioMenu, "AudioMenu.on_label", 346 "AudioMenu.on_mnemonic", 347 "AudioMenu.on_accessible_description", 348 new OnAudioAction(this)); 349 350 mi = createAudioMenuItem(audioMenu, "AudioMenu.default_label", 351 "AudioMenu.default_mnemonic", 352 "AudioMenu.default_accessible_description", 353 new DefaultAudioAction(this)); 354 mi.setSelected(true); // This is the default feedback setting 355 356 createAudioMenuItem(audioMenu, "AudioMenu.off_label", 357 "AudioMenu.off_mnemonic", 358 "AudioMenu.off_accessible_description", 359 new OffAudioAction(this)); 360 361 362 // ***** create the font submenu under the theme menu 363 JMenu fontMenu = (JMenu) themesMenu.add(new JMenu(getString("FontMenu.fonts_label"))); 364 fontMenu.setMnemonic(getMnemonic("FontMenu.fonts_mnemonic")); 365 fontMenu.getAccessibleContext().setAccessibleDescription( 366 getString("FontMenu.fonts_accessible_description")); 367 ButtonGroup fontButtonGroup = new ButtonGroup(); 368 mi = createButtonGroupMenuItem(fontMenu, "FontMenu.plain_label", 369 "FontMenu.plain_mnemonic", 370 "FontMenu.plain_accessible_description", 371 new ChangeFontAction(this, true), fontButtonGroup); 372 mi.setSelected(true); 373 mi = createButtonGroupMenuItem(fontMenu, "FontMenu.bold_label", 374 "FontMenu.bold_mnemonic", 375 "FontMenu.bold_accessible_description", 376 new ChangeFontAction(this, false), fontButtonGroup); 377 378 379 380 // *** now back to adding color/font themes to the theme menu 381 mi = createThemesMenuItem(themesMenu, "ThemesMenu.ocean_label", 382 "ThemesMenu.ocean_mnemonic", 383 "ThemesMenu.ocean_accessible_description", 384 new OceanTheme()); 385 mi.setSelected(true); // This is the default theme 386 387 createThemesMenuItem(themesMenu, "ThemesMenu.steel_label", 388 "ThemesMenu.steel_mnemonic", 389 "ThemesMenu.steel_accessible_description", 390 new DefaultMetalTheme()); 391 392 createThemesMenuItem(themesMenu, "ThemesMenu.aqua_label", "ThemesMenu.aqua_mnemonic", 393 "ThemesMenu.aqua_accessible_description", new AquaTheme()); 394 395 createThemesMenuItem(themesMenu, "ThemesMenu.charcoal_label", "ThemesMenu.charcoal_mnemonic", 396 "ThemesMenu.charcoal_accessible_description", new CharcoalTheme()); 397 398 createThemesMenuItem(themesMenu, "ThemesMenu.contrast_label", "ThemesMenu.contrast_mnemonic", 399 "ThemesMenu.contrast_accessible_description", new ContrastTheme()); 400 401 createThemesMenuItem(themesMenu, "ThemesMenu.emerald_label", "ThemesMenu.emerald_mnemonic", 402 "ThemesMenu.emerald_accessible_description", new EmeraldTheme()); 403 404 createThemesMenuItem(themesMenu, "ThemesMenu.ruby_label", "ThemesMenu.ruby_mnemonic", 405 "ThemesMenu.ruby_accessible_description", new RubyTheme()); 406 407 // Enable theme menu based on L&F 408 themesMenu.setEnabled("Metal".equals(currentLookAndFeel.name)); 409 410 // ***** create the options menu 411 optionsMenu = (JMenu)menuBar.add( 412 new JMenu(getString("OptionsMenu.options_label"))); 413 optionsMenu.setMnemonic(getMnemonic("OptionsMenu.options_mnemonic")); 414 optionsMenu.getAccessibleContext().setAccessibleDescription( 415 getString("OptionsMenu.options_accessible_description")); 416 417 // ***** create tool tip submenu item. 418 mi = createCheckBoxMenuItem(optionsMenu, "OptionsMenu.tooltip_label", 419 "OptionsMenu.tooltip_mnemonic", 420 "OptionsMenu.tooltip_accessible_description", 421 new ToolTipAction()); 422 mi.setSelected(true); 423 424 // ***** create drag support submenu item. 425 createCheckBoxMenuItem(optionsMenu, "OptionsMenu.dragEnabled_label", 426 "OptionsMenu.dragEnabled_mnemonic", 427 "OptionsMenu.dragEnabled_accessible_description", 428 new DragSupportAction()); 429 430 } 431 432 433 // ***** create the multiscreen menu, if we have multiple screens 434 if (!isApplet()) { 435 GraphicsDevice[] screens = GraphicsEnvironment. 436 getLocalGraphicsEnvironment(). 437 getScreenDevices(); 438 if (screens.length > 1) { 439 440 JMenu multiScreenMenu = (JMenu) menuBar.add(new JMenu( 441 getString("MultiMenu.multi_label"))); 442 443 multiScreenMenu.setMnemonic(getMnemonic("MultiMenu.multi_mnemonic")); 444 multiScreenMenu.getAccessibleContext().setAccessibleDescription( 445 getString("MultiMenu.multi_accessible_description")); 446 447 createMultiscreenMenuItem(multiScreenMenu, MultiScreenAction.ALL_SCREENS); 448 for (int i = 0; i < screens.length; i++) { 449 createMultiscreenMenuItem(multiScreenMenu, i); 450 } 451 } 452 } 453 454 return menuBar; 455 } 456 457 /** 458 * Create a checkbox menu menu item 459 */ createCheckBoxMenuItem(JMenu menu, String label, String mnemonic, String accessibleDescription, Action action)460 private JMenuItem createCheckBoxMenuItem(JMenu menu, String label, 461 String mnemonic, 462 String accessibleDescription, 463 Action action) { 464 JCheckBoxMenuItem mi = (JCheckBoxMenuItem)menu.add( 465 new JCheckBoxMenuItem(getString(label))); 466 mi.setMnemonic(getMnemonic(mnemonic)); 467 mi.getAccessibleContext().setAccessibleDescription(getString( 468 accessibleDescription)); 469 mi.addActionListener(action); 470 return mi; 471 } 472 473 /** 474 * Create a radio button menu menu item for items that are part of a 475 * button group. 476 */ createButtonGroupMenuItem(JMenu menu, String label, String mnemonic, String accessibleDescription, Action action, ButtonGroup buttonGroup)477 private JMenuItem createButtonGroupMenuItem(JMenu menu, String label, 478 String mnemonic, 479 String accessibleDescription, 480 Action action, 481 ButtonGroup buttonGroup) { 482 JRadioButtonMenuItem mi = (JRadioButtonMenuItem)menu.add( 483 new JRadioButtonMenuItem(getString(label))); 484 buttonGroup.add(mi); 485 mi.setMnemonic(getMnemonic(mnemonic)); 486 mi.getAccessibleContext().setAccessibleDescription(getString( 487 accessibleDescription)); 488 mi.addActionListener(action); 489 return mi; 490 } 491 492 /** 493 * Create the theme's audio submenu 494 */ createAudioMenuItem(JMenu menu, String label, String mnemonic, String accessibleDescription, Action action)495 public JMenuItem createAudioMenuItem(JMenu menu, String label, 496 String mnemonic, 497 String accessibleDescription, 498 Action action) { 499 JRadioButtonMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(getString(label))); 500 audioMenuGroup.add(mi); 501 mi.setMnemonic(getMnemonic(mnemonic)); 502 mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription)); 503 mi.addActionListener(action); 504 505 return mi; 506 } 507 508 /** 509 * Creates a generic menu item 510 */ createMenuItem(JMenu menu, String label, String mnemonic, String accessibleDescription, Action action)511 public JMenuItem createMenuItem(JMenu menu, String label, String mnemonic, 512 String accessibleDescription, Action action) { 513 JMenuItem mi = (JMenuItem) menu.add(new JMenuItem(getString(label))); 514 mi.setMnemonic(getMnemonic(mnemonic)); 515 mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription)); 516 mi.addActionListener(action); 517 if(action == null) { 518 mi.setEnabled(false); 519 } 520 return mi; 521 } 522 523 /** 524 * Creates a JRadioButtonMenuItem for the Themes menu 525 */ createThemesMenuItem(JMenu menu, String label, String mnemonic, String accessibleDescription, MetalTheme theme)526 public JMenuItem createThemesMenuItem(JMenu menu, String label, String mnemonic, 527 String accessibleDescription, MetalTheme theme) { 528 JRadioButtonMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(getString(label))); 529 themesMenuGroup.add(mi); 530 mi.setMnemonic(getMnemonic(mnemonic)); 531 mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription)); 532 mi.addActionListener(new ChangeThemeAction(this, theme)); 533 534 return mi; 535 } 536 537 /** 538 * Creates a JRadioButtonMenuItem for the Look and Feel menu 539 */ createLafMenuItem(JMenu menu, LookAndFeelData lafData)540 public JMenuItem createLafMenuItem(JMenu menu, LookAndFeelData lafData) { 541 JMenuItem mi = menu.add(new JRadioButtonMenuItem(lafData.label)); 542 lafMenuGroup.add(mi); 543 mi.setMnemonic(lafData.mnemonic); 544 mi.getAccessibleContext().setAccessibleDescription(lafData.accDescription); 545 mi.addActionListener(new ChangeLookAndFeelAction(this, lafData)); 546 return mi; 547 } 548 549 /** 550 * Creates a multi-screen menu item 551 */ createMultiscreenMenuItem(JMenu menu, int screen)552 public JMenuItem createMultiscreenMenuItem(JMenu menu, int screen) { 553 JMenuItem mi = null; 554 if (screen == MultiScreenAction.ALL_SCREENS) { 555 mi = (JMenuItem) menu.add(new JMenuItem(getString("MultiMenu.all_label"))); 556 mi.setMnemonic(getMnemonic("MultiMenu.all_mnemonic")); 557 mi.getAccessibleContext().setAccessibleDescription(getString( 558 "MultiMenu.all_accessible_description")); 559 } 560 else { 561 mi = (JMenuItem) menu.add(new JMenuItem(getString("MultiMenu.single_label") + " " + 562 screen)); 563 mi.setMnemonic(KeyEvent.VK_0 + screen); 564 mi.getAccessibleContext().setAccessibleDescription(getString( 565 "MultiMenu.single_accessible_description") + " " + screen); 566 567 } 568 mi.addActionListener(new MultiScreenAction(this, screen)); 569 return mi; 570 } 571 createPopupMenu()572 public JPopupMenu createPopupMenu() { 573 JPopupMenu popup = new JPopupMenu("JPopupMenu demo"); 574 575 for (LookAndFeelData lafData : lookAndFeelData) { 576 createPopupMenuItem(popup, lafData); 577 } 578 579 // register key binding to activate popup menu 580 InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 581 map.put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, InputEvent.SHIFT_MASK), 582 "postMenuAction"); 583 map.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTEXT_MENU, 0), "postMenuAction"); 584 getActionMap().put("postMenuAction", new ActivatePopupMenuAction(this, popup)); 585 586 return popup; 587 } 588 589 /** 590 * Creates a JMenuItem for the Look and Feel popup menu 591 */ createPopupMenuItem(JPopupMenu menu, LookAndFeelData lafData)592 public JMenuItem createPopupMenuItem(JPopupMenu menu, LookAndFeelData lafData) { 593 JMenuItem mi = menu.add(new JMenuItem(lafData.label)); 594 popupMenuGroup.add(mi); 595 mi.setMnemonic(lafData.mnemonic); 596 mi.getAccessibleContext().setAccessibleDescription(lafData.accDescription); 597 mi.addActionListener(new ChangeLookAndFeelAction(this, lafData)); 598 return mi; 599 } 600 601 602 /** 603 * Load the first demo. This is done separately from the remaining demos 604 * so that we can get SwingSet2 up and available to the user quickly. 605 */ preloadFirstDemo()606 public void preloadFirstDemo() { 607 DemoModule demo = addDemo(new InternalFrameDemo(this)); 608 setDemo(demo); 609 } 610 611 612 /** 613 * Add a demo to the toolbar 614 */ addDemo(DemoModule demo)615 public DemoModule addDemo(DemoModule demo) { 616 demosList.add(demo); 617 if (dragEnabled) { 618 demo.updateDragEnabled(true); 619 } 620 // do the following on the gui thread 621 SwingUtilities.invokeLater(new SwingSetRunnable(this, demo) { 622 public void run() { 623 SwitchToDemoAction action = new SwitchToDemoAction(swingset, (DemoModule) obj); 624 JToggleButton tb = swingset.getToolBar().addToggleButton(action); 625 swingset.getToolBarGroup().add(tb); 626 if(swingset.getToolBarGroup().getSelection() == null) { 627 tb.setSelected(true); 628 } 629 tb.setText(null); 630 tb.setToolTipText(((DemoModule)obj).getToolTip()); 631 632 if(demos[demos.length-1].equals(obj.getClass().getName())) { 633 setStatus(getString("Status.popupMenuAccessible")); 634 } 635 636 } 637 }); 638 return demo; 639 } 640 641 642 /** 643 * Sets the current demo 644 */ setDemo(DemoModule demo)645 public void setDemo(DemoModule demo) { 646 currentDemo = demo; 647 648 // Ensure panel's UI is current before making visible 649 JComponent currentDemoPanel = demo.getDemoPanel(); 650 SwingUtilities.updateComponentTreeUI(currentDemoPanel); 651 652 demoPanel.removeAll(); 653 demoPanel.add(currentDemoPanel, BorderLayout.CENTER); 654 655 tabbedPane.setSelectedIndex(0); 656 tabbedPane.setTitleAt(0, demo.getName()); 657 tabbedPane.setToolTipTextAt(0, demo.getToolTip()); 658 } 659 660 661 /** 662 * Bring up the SwingSet2 demo by showing the frame (only 663 * applicable if coming up as an application, not an applet); 664 */ showSwingSet2()665 public void showSwingSet2() { 666 if(!isApplet() && getFrame() != null) { 667 // put swingset in a frame and show it 668 JFrame f = getFrame(); 669 f.setTitle(getString("Frame.title")); 670 f.getContentPane().add(this, BorderLayout.CENTER); 671 f.pack(); 672 673 Rectangle screenRect = f.getGraphicsConfiguration().getBounds(); 674 Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( 675 f.getGraphicsConfiguration()); 676 677 // Make sure we don't place the demo off the screen. 678 int centerWidth = screenRect.width < f.getSize().width ? 679 screenRect.x : 680 screenRect.x + screenRect.width/2 - f.getSize().width/2; 681 int centerHeight = screenRect.height < f.getSize().height ? 682 screenRect.y : 683 screenRect.y + screenRect.height/2 - f.getSize().height/2; 684 685 centerHeight = centerHeight < screenInsets.top ? 686 screenInsets.top : centerHeight; 687 688 f.setLocation(centerWidth, centerHeight); 689 f.show(); 690 numSSs++; 691 swingSets.add(this); 692 } 693 } 694 695 // ******************************************************* 696 // ****************** Utility Methods ******************** 697 // ******************************************************* 698 699 /** 700 * Loads a demo from a classname 701 */ 702 void loadDemo(String classname) { 703 setStatus(getString("Status.loading") + getString(classname + ".name")); 704 DemoModule demo = null; 705 try { 706 Class demoClass = Class.forName(classname); 707 Constructor demoConstructor = demoClass.getConstructor(new Class[]{SwingSet2.class}); 708 demo = (DemoModule) demoConstructor.newInstance(new Object[]{this}); 709 addDemo(demo); 710 } catch (Exception e) { 711 System.out.println("Error occurred loading demo: " + classname); 712 } 713 } 714 715 /** 716 * Determines if this is an applet or application 717 */ 718 public boolean isApplet() { 719 return (applet != null); 720 } 721 722 /** 723 * Returns the applet instance 724 */ 725 public SwingSet2Applet getApplet() { 726 return applet; 727 } 728 729 730 /** 731 * Returns the frame instance 732 */ 733 public JFrame getFrame() { 734 return frame; 735 } 736 737 /** 738 * Returns the menubar 739 */ 740 public JMenuBar getMenuBar() { 741 return menuBar; 742 } 743 744 /** 745 * Returns the toolbar 746 */ 747 public ToggleButtonToolBar getToolBar() { 748 return toolbar; 749 } 750 751 /** 752 * Returns the toolbar button group 753 */ 754 public ButtonGroup getToolBarGroup() { 755 return toolbarGroup; 756 } 757 758 /** 759 * Returns the content pane whether we're in an applet 760 * or application 761 */ 762 public Container getContentPane() { 763 if(contentPane == null) { 764 if(getFrame() != null) { 765 contentPane = getFrame().getContentPane(); 766 } else if (getApplet() != null) { 767 contentPane = getApplet().getContentPane(); 768 } 769 } 770 return contentPane; 771 } 772 773 /** 774 * Create a frame for SwingSet2 to reside in if brought up 775 * as an application. 776 */ 777 public static JFrame createFrame(GraphicsConfiguration gc) { 778 JFrame frame = new JFrame(gc); 779 if (numSSs == 0) { 780 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 781 } else { 782 WindowListener l = new WindowAdapter() { 783 public void windowClosing(WindowEvent e) { 784 numSSs--; 785 swingSets.remove(this); 786 } 787 }; 788 frame.addWindowListener(l); 789 } 790 return frame; 791 } 792 793 794 /** 795 * Set the status 796 */ 797 public void setStatus(String s) { 798 // do the following on the gui thread 799 SwingUtilities.invokeLater(new SwingSetRunnable(this, s) { 800 public void run() { 801 swingset.statusField.setText((String) obj); 802 } 803 }); 804 } 805 806 807 /** 808 * This method returns a string from the demo's resource bundle. 809 */ 810 public static String getString(String key) { 811 String value = null; 812 try { 813 value = TextAndMnemonicUtils.getTextAndMnemonicString(key); 814 } catch (MissingResourceException e) { 815 System.out.println("java.util.MissingResourceException: Couldn't find value for: " + key); 816 } 817 if(value == null) { 818 value = "Could not find resource: " + key + " "; 819 } 820 return value; 821 } 822 823 void setDragEnabled(boolean dragEnabled) { 824 if (dragEnabled == this.dragEnabled) { 825 return; 826 } 827 828 this.dragEnabled = dragEnabled; 829 830 for (DemoModule dm : demosList) { 831 dm.updateDragEnabled(dragEnabled); 832 } 833 834 demoSrcPane.setDragEnabled(dragEnabled); 835 } 836 837 boolean isDragEnabled() { 838 return dragEnabled; 839 } 840 841 842 /** 843 * Returns a mnemonic from the resource bundle. Typically used as 844 * keyboard shortcuts in menu items. 845 */ 846 public char getMnemonic(String key) { 847 return (getString(key)).charAt(0); 848 } 849 850 /** 851 * Creates an icon from an image contained in the "images" directory. 852 */ 853 public ImageIcon createImageIcon(String filename, String description) { 854 String path = "/resources/images/" + filename; 855 return new ImageIcon(getClass().getResource(path)); 856 } 857 858 /** 859 * If DEBUG is defined, prints debug information out to std ouput. 860 */ 861 public void debug(String s) { 862 if(DEBUG) { 863 System.out.println((debugCounter++) + ": " + s); 864 } 865 } 866 867 /** 868 * Stores the current L&F, and calls updateLookAndFeel, below 869 */ 870 public void setLookAndFeel(LookAndFeelData laf) { 871 if(!currentLookAndFeel.equals(laf)) { 872 currentLookAndFeel = laf; 873 /* The recommended way of synchronizing state between multiple 874 * controls that represent the same command is to use Actions. 875 * The code below is a workaround and will be replaced in future 876 * version of SwingSet2 demo. 877 */ 878 String lafName = laf.label; 879 themesMenu.setEnabled(laf.name.equals("Metal")); 880 updateLookAndFeel(); 881 for(int i=0;i<lafMenu.getItemCount();i++) { 882 JMenuItem item = lafMenu.getItem(i); 883 item.setSelected(item.getText().equals(lafName)); 884 } 885 } 886 } 887 888 private void updateThisSwingSet() { 889 if (isApplet()) { 890 SwingUtilities.updateComponentTreeUI(getApplet()); 891 } else { 892 JFrame frame = getFrame(); 893 if (frame == null) { 894 SwingUtilities.updateComponentTreeUI(this); 895 } else { 896 SwingUtilities.updateComponentTreeUI(frame); 897 } 898 } 899 900 SwingUtilities.updateComponentTreeUI(popupMenu); 901 if (aboutBox != null) { 902 SwingUtilities.updateComponentTreeUI(aboutBox); 903 } 904 } 905 906 /** 907 * Sets the current L&F on each demo module 908 */ 909 public void updateLookAndFeel() { 910 try { 911 UIManager.setLookAndFeel(currentLookAndFeel.className); 912 if (isApplet()) { 913 updateThisSwingSet(); 914 } else { 915 for (SwingSet2 ss : swingSets) { 916 ss.updateThisSwingSet(); 917 } 918 } 919 } catch (Exception ex) { 920 System.out.println("Failed loading L&F: " + currentLookAndFeel); 921 System.out.println(ex); 922 } 923 } 924 925 /** 926 * Loads and puts the source code text into JEditorPane in the "Source Code" tab 927 */ 928 public void setSourceCode(DemoModule demo) { 929 // do the following on the gui thread 930 SwingUtilities.invokeLater(new SwingSetRunnable(this, demo) { 931 public void run() { 932 swingset.demoSrcPane.setText(((DemoModule)obj).getSourceCode()); 933 swingset.demoSrcPane.setCaretPosition(0); 934 935 } 936 }); 937 } 938 939 // ******************************************************* 940 // ************** ToggleButtonToolbar ***************** 941 // ******************************************************* 942 static Insets zeroInsets = new Insets(1,1,1,1); 943 protected class ToggleButtonToolBar extends JToolBar { 944 public ToggleButtonToolBar() { 945 super(); 946 } 947 948 JToggleButton addToggleButton(Action a) { 949 JToggleButton tb = new JToggleButton( 950 (String)a.getValue(Action.NAME), 951 (Icon)a.getValue(Action.SMALL_ICON) 952 ); 953 tb.setMargin(zeroInsets); 954 tb.setText(null); 955 tb.setEnabled(a.isEnabled()); 956 tb.setToolTipText((String)a.getValue(Action.SHORT_DESCRIPTION)); 957 tb.setAction(a); 958 add(tb); 959 return tb; 960 } 961 } 962 963 // ******************************************************* 964 // ********* ToolBar Panel / Docking Listener *********** 965 // ******************************************************* 966 class ToolBarPanel extends JPanel implements ContainerListener { 967 968 public boolean contains(int x, int y) { 969 Component c = getParent(); 970 if (c != null) { 971 Rectangle r = c.getBounds(); 972 return (x >= 0) && (x < r.width) && (y >= 0) && (y < r.height); 973 } 974 else { 975 return super.contains(x,y); 976 } 977 } 978 979 public void componentAdded(ContainerEvent e) { 980 Container c = e.getContainer().getParent(); 981 if (c != null) { 982 c.getParent().validate(); 983 c.getParent().repaint(); 984 } 985 } 986 987 public void componentRemoved(ContainerEvent e) { 988 Container c = e.getContainer().getParent(); 989 if (c != null) { 990 c.getParent().validate(); 991 c.getParent().repaint(); 992 } 993 } 994 } 995 996 // ******************************************************* 997 // ****************** Runnables *********************** 998 // ******************************************************* 999 1000 /** 1001 * Generic SwingSet2 runnable. This is intended to run on the 1002 * AWT gui event thread so as not to muck things up by doing 1003 * gui work off the gui thread. Accepts a SwingSet2 and an Object 1004 * as arguments, which gives subtypes of this class the two 1005 * "must haves" needed in most runnables for this demo. 1006 */ 1007 class SwingSetRunnable implements Runnable { 1008 protected SwingSet2 swingset; 1009 protected Object obj; 1010 1011 public SwingSetRunnable(SwingSet2 swingset, Object obj) { 1012 this.swingset = swingset; 1013 this.obj = obj; 1014 } 1015 1016 public void run() { 1017 } 1018 } 1019 1020 1021 // ******************************************************* 1022 // ******************** Actions *********************** 1023 // ******************************************************* 1024 1025 public class SwitchToDemoAction extends AbstractAction { 1026 SwingSet2 swingset; 1027 DemoModule demo; 1028 1029 public SwitchToDemoAction(SwingSet2 swingset, DemoModule demo) { 1030 super(demo.getName(), demo.getIcon()); 1031 this.swingset = swingset; 1032 this.demo = demo; 1033 } 1034 1035 public void actionPerformed(ActionEvent e) { 1036 swingset.setDemo(demo); 1037 } 1038 } 1039 1040 class OkAction extends AbstractAction { 1041 JDialog aboutBox; 1042 1043 protected OkAction(JDialog aboutBox) { 1044 super("OkAction"); 1045 this.aboutBox = aboutBox; 1046 } 1047 1048 public void actionPerformed(ActionEvent e) { 1049 aboutBox.setVisible(false); 1050 } 1051 } 1052 1053 class ChangeLookAndFeelAction extends AbstractAction { 1054 SwingSet2 swingset; 1055 LookAndFeelData lafData; 1056 protected ChangeLookAndFeelAction(SwingSet2 swingset, LookAndFeelData lafData) { 1057 super("ChangeTheme"); 1058 this.swingset = swingset; 1059 this.lafData = lafData; 1060 } 1061 1062 public void actionPerformed(ActionEvent e) { 1063 swingset.setLookAndFeel(lafData); 1064 } 1065 } 1066 1067 class ActivatePopupMenuAction extends AbstractAction { 1068 SwingSet2 swingset; 1069 JPopupMenu popup; 1070 protected ActivatePopupMenuAction(SwingSet2 swingset, JPopupMenu popup) { 1071 super("ActivatePopupMenu"); 1072 this.swingset = swingset; 1073 this.popup = popup; 1074 } 1075 1076 public void actionPerformed(ActionEvent e) { 1077 Dimension invokerSize = getSize(); 1078 Dimension popupSize = popup.getPreferredSize(); 1079 popup.show(swingset, (invokerSize.width - popupSize.width) / 2, 1080 (invokerSize.height - popupSize.height) / 2); 1081 } 1082 } 1083 1084 // Turns on all possible auditory feedback 1085 class OnAudioAction extends AbstractAction { 1086 SwingSet2 swingset; 1087 protected OnAudioAction(SwingSet2 swingset) { 1088 super("Audio On"); 1089 this.swingset = swingset; 1090 } 1091 public void actionPerformed(ActionEvent e) { 1092 UIManager.put("AuditoryCues.playList", 1093 UIManager.get("AuditoryCues.allAuditoryCues")); 1094 swingset.updateLookAndFeel(); 1095 } 1096 } 1097 1098 // Turns on the default amount of auditory feedback 1099 class DefaultAudioAction extends AbstractAction { 1100 SwingSet2 swingset; 1101 protected DefaultAudioAction(SwingSet2 swingset) { 1102 super("Audio Default"); 1103 this.swingset = swingset; 1104 } 1105 public void actionPerformed(ActionEvent e) { 1106 UIManager.put("AuditoryCues.playList", 1107 UIManager.get("AuditoryCues.defaultCueList")); 1108 swingset.updateLookAndFeel(); 1109 } 1110 } 1111 1112 // Turns off all possible auditory feedback 1113 class OffAudioAction extends AbstractAction { 1114 SwingSet2 swingset; 1115 protected OffAudioAction(SwingSet2 swingset) { 1116 super("Audio Off"); 1117 this.swingset = swingset; 1118 } 1119 public void actionPerformed(ActionEvent e) { 1120 UIManager.put("AuditoryCues.playList", 1121 UIManager.get("AuditoryCues.noAuditoryCues")); 1122 swingset.updateLookAndFeel(); 1123 } 1124 } 1125 1126 // Turns on or off the tool tips for the demo. 1127 class ToolTipAction extends AbstractAction { 1128 protected ToolTipAction() { 1129 super("ToolTip Control"); 1130 } 1131 1132 public void actionPerformed(ActionEvent e) { 1133 boolean status = ((JCheckBoxMenuItem)e.getSource()).isSelected(); 1134 ToolTipManager.sharedInstance().setEnabled(status); 1135 } 1136 } 1137 1138 class DragSupportAction extends AbstractAction { 1139 protected DragSupportAction() { 1140 super("DragSupport Control"); 1141 } 1142 1143 public void actionPerformed(ActionEvent e) { 1144 boolean dragEnabled = ((JCheckBoxMenuItem)e.getSource()).isSelected(); 1145 if (isApplet()) { 1146 setDragEnabled(dragEnabled); 1147 } else { 1148 for (SwingSet2 ss : swingSets) { 1149 ss.setDragEnabled(dragEnabled); 1150 } 1151 } 1152 } 1153 } 1154 1155 class ChangeThemeAction extends AbstractAction { 1156 SwingSet2 swingset; 1157 MetalTheme theme; 1158 protected ChangeThemeAction(SwingSet2 swingset, MetalTheme theme) { 1159 super("ChangeTheme"); 1160 this.swingset = swingset; 1161 this.theme = theme; 1162 } 1163 1164 public void actionPerformed(ActionEvent e) { 1165 MetalLookAndFeel.setCurrentTheme(theme); 1166 swingset.updateLookAndFeel(); 1167 } 1168 } 1169 1170 class ExitAction extends AbstractAction { 1171 SwingSet2 swingset; 1172 protected ExitAction(SwingSet2 swingset) { 1173 super("ExitAction"); 1174 this.swingset = swingset; 1175 } 1176 1177 public void actionPerformed(ActionEvent e) { 1178 System.exit(0); 1179 } 1180 } 1181 1182 class AboutAction extends AbstractAction { 1183 SwingSet2 swingset; 1184 protected AboutAction(SwingSet2 swingset) { 1185 super("AboutAction"); 1186 this.swingset = swingset; 1187 } 1188 1189 public void actionPerformed(ActionEvent e) { 1190 if(aboutBox == null) { 1191 // JPanel panel = new JPanel(new BorderLayout()); 1192 JPanel panel = new AboutPanel(swingset); 1193 panel.setLayout(new BorderLayout()); 1194 1195 aboutBox = new JDialog(swingset.getFrame(), getString("AboutBox.title"), false); 1196 aboutBox.setResizable(false); 1197 aboutBox.getContentPane().add(panel, BorderLayout.CENTER); 1198 1199 // JButton button = new JButton(getString("AboutBox.ok_button_text")); 1200 JPanel buttonpanel = new JPanel(); 1201 buttonpanel.setBorder(new javax.swing.border.EmptyBorder(0, 0, 3, 0)); 1202 buttonpanel.setOpaque(false); 1203 JButton button = (JButton) buttonpanel.add( 1204 new JButton(getString("AboutBox.ok_button_text")) 1205 ); 1206 panel.add(buttonpanel, BorderLayout.SOUTH); 1207 1208 button.addActionListener(new OkAction(aboutBox)); 1209 } 1210 aboutBox.pack(); 1211 if (isApplet()) { 1212 aboutBox.setLocationRelativeTo(getApplet()); 1213 } else { 1214 aboutBox.setLocationRelativeTo(getFrame()); 1215 } 1216 aboutBox.show(); 1217 } 1218 } 1219 1220 class MultiScreenAction extends AbstractAction { 1221 static final int ALL_SCREENS = -1; 1222 int screen; 1223 protected MultiScreenAction(SwingSet2 swingset, int screen) { 1224 super("MultiScreenAction"); 1225 this.screen = screen; 1226 } 1227 1228 public void actionPerformed(ActionEvent e) { 1229 GraphicsDevice[] gds = GraphicsEnvironment. 1230 getLocalGraphicsEnvironment(). 1231 getScreenDevices(); 1232 if (screen == ALL_SCREENS) { 1233 for (int i = 0; i < gds.length; i++) { 1234 SwingSet2 swingset = new SwingSet2(null, 1235 gds[i].getDefaultConfiguration()); 1236 swingset.setDragEnabled(dragEnabled); 1237 } 1238 } 1239 else { 1240 SwingSet2 swingset = new SwingSet2(null, 1241 gds[screen].getDefaultConfiguration()); 1242 swingset.setDragEnabled(dragEnabled); 1243 } 1244 } 1245 } 1246 1247 // ******************************************************* 1248 // ********************** Misc ************************* 1249 // ******************************************************* 1250 1251 class DemoLoadThread extends Thread { 1252 SwingSet2 swingset; 1253 1254 DemoLoadThread(SwingSet2 swingset) { 1255 this.swingset = swingset; 1256 } 1257 1258 public void run() { 1259 SwingUtilities.invokeLater(swingset::loadDemos); 1260 } 1261 } 1262 1263 class AboutPanel extends JPanel { 1264 ImageIcon aboutimage = null; 1265 SwingSet2 swingset = null; 1266 1267 public AboutPanel(SwingSet2 swingset) { 1268 this.swingset = swingset; 1269 aboutimage = swingset.createImageIcon("About.jpg", "AboutBox.accessible_description"); 1270 setOpaque(false); 1271 } 1272 1273 public void paint(Graphics g) { 1274 aboutimage.paintIcon(this, g, 0, 0); 1275 super.paint(g); 1276 } 1277 1278 public Dimension getPreferredSize() { 1279 return new Dimension(aboutimage.getIconWidth(), 1280 aboutimage.getIconHeight()); 1281 } 1282 } 1283 1284 1285 private class ChangeFontAction extends AbstractAction { 1286 private SwingSet2 swingset; 1287 private boolean plain; 1288 1289 ChangeFontAction(SwingSet2 swingset, boolean plain) { 1290 super("FontMenu"); 1291 this.swingset = swingset; 1292 this.plain = plain; 1293 } 1294 1295 public void actionPerformed(ActionEvent e) { 1296 if (plain) { 1297 UIManager.put("swing.boldMetal", Boolean.FALSE); 1298 } 1299 else { 1300 UIManager.put("swing.boldMetal", Boolean.TRUE); 1301 } 1302 // Change the look and feel to force the settings to take effect. 1303 updateLookAndFeel(); 1304 } 1305 } 1306 1307 private static LookAndFeelData[] getInstalledLookAndFeelData() { 1308 return Arrays.stream(UIManager.getInstalledLookAndFeels()) 1309 .map(laf -> getLookAndFeelData(laf)) 1310 .toArray(LookAndFeelData[]::new); 1311 } 1312 1313 private static LookAndFeelData getLookAndFeelData( 1314 UIManager.LookAndFeelInfo info) { 1315 switch (info.getName()) { 1316 case "Metal": 1317 return new LookAndFeelData(info, "java"); 1318 case "Nimbus": 1319 return new LookAndFeelData(info, "nimbus"); 1320 case "Windows": 1321 return new LookAndFeelData(info, "windows"); 1322 case "GTK+": 1323 return new LookAndFeelData(info, "gtk"); 1324 case "CDE/Motif": 1325 return new LookAndFeelData(info, "motif"); 1326 case "Mac OS X": 1327 return new LookAndFeelData(info, "mac"); 1328 default: 1329 return new LookAndFeelData(info); 1330 } 1331 } 1332 1333 private static class LookAndFeelData { 1334 String name; 1335 String className; 1336 String label; 1337 char mnemonic; 1338 String accDescription; 1339 1340 public LookAndFeelData(UIManager.LookAndFeelInfo info) { 1341 this(info.getName(), info.getClassName(), info.getName(), 1342 info.getName(), info.getName()); 1343 } 1344 1345 public LookAndFeelData(UIManager.LookAndFeelInfo info, String property) { 1346 this(info.getName(), info.getClassName(), 1347 getString(String.format("LafMenu.%s_label", property)), 1348 getString(String.format("LafMenu.%s_mnemonic", property)), 1349 getString(String.format("LafMenu.%s_accessible_description", 1350 property))); 1351 } 1352 1353 public LookAndFeelData(String name, String className, String label, 1354 String mnemonic, String accDescription) { 1355 this.name = name; 1356 this.className = className; 1357 this.label = label; 1358 this.mnemonic = mnemonic.charAt(0); 1359 this.accDescription = accDescription; 1360 } 1361 1362 @Override 1363 public String toString() { 1364 return className; 1365 } 1366 } 1367 } 1368