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