OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / lib / classpath / examples / gnu / classpath / examples / swing / MetalThemeEditor.java
1 /* MetalThemeEditor.java -- Edit themes using this application
2    Copyright (C) 2006 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package gnu.classpath.examples.swing;
40
41 import gnu.javax.swing.plaf.metal.CustomizableTheme;
42
43 import java.awt.Color;
44 import java.awt.Component;
45 import java.awt.Graphics;
46 import java.awt.GridBagConstraints;
47 import java.awt.GridBagLayout;
48 import java.awt.Insets;
49 import java.awt.Window;
50 import java.awt.event.ActionEvent;
51 import java.awt.event.ActionListener;
52 import java.io.File;
53 import java.io.FileNotFoundException;
54 import java.io.FileOutputStream;
55 import java.io.IOException;
56 import java.io.OutputStreamWriter;
57 import java.io.Writer;
58
59 import javax.swing.BorderFactory;
60 import javax.swing.Box;
61 import javax.swing.BoxLayout;
62 import javax.swing.Icon;
63 import javax.swing.JButton;
64 import javax.swing.JColorChooser;
65 import javax.swing.JComponent;
66 import javax.swing.JFileChooser;
67 import javax.swing.JFrame;
68 import javax.swing.JLabel;
69 import javax.swing.JOptionPane;
70 import javax.swing.JPanel;
71 import javax.swing.SwingUtilities;
72 import javax.swing.UIManager;
73 import javax.swing.plaf.metal.MetalLookAndFeel;
74
75 /**
76  * This application serves two purposes: 1. demonstrate the color chooser
77  * component, 2. make creating new Metal themes as easy as possible.
78  *
79  * @author Roman Kennke (kennke@aicas.com)
80  */
81 public class MetalThemeEditor
82   extends JPanel
83 {
84   /**
85    * An icon to display a chosen color in a button.
86    */
87   private class ColorIcon implements Icon
88   {
89     /**
90      * The color to be shown on the icon.
91      */
92     Color color;
93
94     /**
95      * Creates a new ColorIcon.
96      *
97      * @param c the color to be displayed
98      */
99     ColorIcon(Color c)
100     {
101       color = c;
102     }
103
104     /**
105      * Returns the icon height, which is 10.
106      *
107      * @return 10
108      */
109     public int getIconHeight()
110     {
111       return 10;
112     }
113
114     /**
115      * Returns the icon width, which is 30.
116      *
117      * @return 30
118      */
119     public int getIconWidth()
120     {
121       return 30;
122     }
123
124     /**
125      * Paints the icon.
126      *
127      * @param c the component to paint on
128      * @param g the graphics to use
129      * @param x the x location
130      * @param y the y location
131      */
132     public void paintIcon(Component c, Graphics g, int x, int y)
133     {
134       g.setColor(color);
135       g.fillRect(x, y, 30, 10);
136     }
137     
138   }
139
140   /**
141    * Opens up a color chooser and lets the user select a color for the theme.
142    */
143   private class ChooseColorAction implements ActionListener
144   {
145
146     /**
147      * The button that will get updated when a new color is selected.
148      */
149     private JButton button;
150
151     /**
152      * Specifies which color of the theme should be updated. See constants in
153      * the MetalThemeEditor class.
154      */
155     private int colorType;
156
157     /**
158      * Creates a new ChooseColorAction. The specified button will have its
159      * icon updated to the new color if appropriate.
160      *
161      * @param b the button to update
162      * @param type the color type to update
163      */
164     ChooseColorAction(JButton b, int type)
165     {
166       button = b;
167       colorType = type;
168     }
169
170     /**
171      * Opens a color chooser and lets the user select a color.
172      */
173     public void actionPerformed(ActionEvent event)
174     {
175       Color c = JColorChooser.showDialog(button, "Choose a color",
176                                          getColor(colorType));
177       if (c != null)
178         {
179           setColor(colorType, c);
180           button.setIcon(new ColorIcon(c));
181         }
182     }
183   }
184
185   /**
186    * Denotes the primary1 color of the theme.
187    */
188   private static final int PRIMARY1 = 0;
189
190   /**
191    * Denotes the primary2 color of the theme.
192    */
193   private static final int PRIMARY2 = 1;
194
195   /**
196    * Denotes the primary3 color of the theme.
197    */
198   private static final int PRIMARY3 = 2;
199
200   /**
201    * Denotes the secondary1 color of the theme.
202    */
203   private static final int SECONDARY1 = 3;
204
205   /**
206    * Denotes the secondary2 color of the theme.
207    */
208   private static final int SECONDARY2 = 4;
209
210   /**
211    * Denotes the secondary3 color of the theme.
212    */
213   private static final int SECONDARY3 = 5;
214
215   /**
216    * The theme that is edited.
217    */
218   CustomizableTheme theme;
219
220   /**
221    * Creates a new instance of the MetalThemeEditor.
222    */
223   MetalThemeEditor()
224   {
225     theme = new CustomizableTheme();
226     setBorder(BorderFactory.createEmptyBorder(12, 12, 11, 11));
227     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
228     add(createConfigurationPanel());
229     add(Box.createVerticalStrut(17));
230     add(createButtonPanel());
231   }
232
233   /**
234    * Creates the main panel of the MetalThemeEditor. This is the upper
235    * area where the colors can be selected.
236    *
237    * @return the main panel
238    */
239   private JPanel createConfigurationPanel()
240   {
241     JPanel p = new JPanel();
242     p.setLayout(new GridBagLayout());
243     GridBagConstraints c = new GridBagConstraints();
244     c.weightx = 1;
245     c.weighty = 0;
246     c.fill = GridBagConstraints.HORIZONTAL;
247     Insets labelInsets = new Insets(0, 0, 11, 6);
248     Insets buttonInsets = new Insets(0, 0, 11, 0);
249
250     // Primary 1
251     JLabel primary1Label = new JLabel("Primary 1:");
252     c.gridx = 0;
253     c.gridy = 0;
254     c.insets = labelInsets;
255     p.add(primary1Label, c);
256
257     Icon p1Icon = new ColorIcon(theme.getPrimary1());
258     JButton primary1Button = new JButton(p1Icon);
259     primary1Button.addActionListener(new ChooseColorAction(primary1Button,
260                                                            PRIMARY1));
261     //c.weightx = 0;
262     c.gridx = 1;
263     c.insets = buttonInsets;
264     p.add(primary1Button, c);
265     primary1Label.setLabelFor(primary1Button);
266
267     // Primary 2
268     JLabel primary2Label = new JLabel("Primary 2:");
269     c.gridx = 0;
270     c.gridy = 1;
271     c.insets = labelInsets;
272     p.add(primary2Label, c);
273
274     Icon p2Icon = new ColorIcon(theme.getPrimary2());
275     JButton primary2Button = new JButton(p2Icon);
276     primary2Button.addActionListener(new ChooseColorAction(primary2Button,
277                                                            PRIMARY2));
278     c.gridx = 1;
279     c.insets = buttonInsets;
280     p.add(primary2Button, c);
281     primary2Label.setLabelFor(primary2Button);
282
283     // Primary 3
284     JLabel primary3Label = new JLabel("Primary 3:");
285     c.gridx = 0;
286     c.gridy = 2;
287     c.insets = labelInsets;
288     p.add(primary3Label, c);
289
290     Icon p3Icon = new ColorIcon(theme.getPrimary3());
291     JButton primary3Button = new JButton(p3Icon);
292     primary3Button.addActionListener(new ChooseColorAction(primary3Button,
293                                                            PRIMARY3));
294     c.gridx = 1;
295     c.insets = buttonInsets;
296     p.add(primary3Button, c);
297     primary3Label.setLabelFor(primary3Button);
298
299     // Secondary 1
300     JLabel secondary1Label = new JLabel("Secondary 1:");
301     c.gridx = 0;
302     c.gridy = 3;
303     c.insets = labelInsets;
304     p.add(secondary1Label, c);
305
306     Icon s1Icon = new ColorIcon(theme.getSecondary1());
307     JButton secondary1Button = new JButton(s1Icon);
308     secondary1Button.addActionListener(new ChooseColorAction(secondary1Button,
309                                                              SECONDARY1));
310     c.gridx = 1;
311     c.insets = buttonInsets;
312     p.add(secondary1Button, c);
313     secondary1Label.setLabelFor(secondary1Button);
314
315     // Secondary 2
316     JLabel secondary2Label = new JLabel("Secondary 2:");
317     c.gridx = 0;
318     c.gridy = 4;
319     c.insets = labelInsets;
320     p.add(secondary2Label, c);
321
322     Icon s2Icon = new ColorIcon(theme.getSecondary2());
323     JButton secondary2Button = new JButton(s2Icon);
324     secondary2Button.addActionListener(new ChooseColorAction(secondary2Button,
325                                                              SECONDARY2));
326     c.gridx = 1;
327     c.insets = buttonInsets;
328     p.add(secondary2Button, c);
329     secondary2Label.setLabelFor(secondary2Button);
330
331     // Secondary 3
332     JLabel secondary3Label = new JLabel("Secondary 3:");
333     c.gridx = 0;
334     c.gridy = 5;
335     c.insets = labelInsets;
336     p.add(secondary3Label, c);
337
338     Icon s3Icon = new ColorIcon(theme.getSecondary3());
339     JButton secondary3Button = new JButton(s3Icon);
340     secondary3Button.addActionListener(new ChooseColorAction(secondary3Button,
341                                                              SECONDARY3));
342     c.gridx = 1;
343     c.insets = buttonInsets;
344     p.add(secondary3Button, c);
345     secondary3Label.setLabelFor(secondary3Button);
346
347     return p;
348   }
349
350   /**
351    * Creates the button panel at the bottom of the MetalThemeEditor.
352    *
353    * @return the button panel
354    */
355   private JPanel createButtonPanel()
356   {
357     JPanel p = new JPanel();
358     p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
359     p.add(Box.createHorizontalGlue());
360
361     JButton applyButton = new JButton("Apply");
362     applyButton.addActionListener
363     (new ActionListener()
364      {
365        public void actionPerformed(ActionEvent ev)
366        {
367          try
368            {
369              CustomizableTheme copy = (CustomizableTheme) theme.clone();
370              MetalLookAndFeel.setCurrentTheme(copy);
371              UIManager.setLookAndFeel(new MetalLookAndFeel());
372              Window w = SwingUtilities.getWindowAncestor(MetalThemeEditor.this);
373              SwingUtilities.updateComponentTreeUI(w);
374            }
375          catch (Exception ex)
376            {
377              ex.printStackTrace();
378            }
379        }
380      });
381     p.add(applyButton);
382
383     p.add(Box.createHorizontalStrut(5));
384
385     JButton exportButton = new JButton("Export as Java File");
386     exportButton.addActionListener
387     (new ActionListener()
388      {
389        public void actionPerformed(ActionEvent ev)
390        {
391          export();
392        }
393      });
394     p.add(exportButton);
395
396     return p;
397   }
398
399   /**
400    * Exports the current theme as Java source file. This will prompt the user
401    * to choose a filename.
402    */
403   void export()
404   {
405     JFileChooser chooser = new JFileChooser();
406     int confirm = chooser.showSaveDialog(this);
407     if (confirm == JFileChooser.APPROVE_OPTION)
408       exportToFile(chooser.getSelectedFile());
409   }
410
411   /**
412    * Writes out the current configured Metal theme as Java source file.
413    *
414    * @param file the file to write into
415    */
416   void exportToFile(File file)
417   {
418     String fileName = file.getName();
419     if (! fileName.endsWith(".java"))
420       {
421         JOptionPane.showMessageDialog(this,
422                                  "Filename does not denote a Java source file",
423                                  "Invalid filename",
424                                  JOptionPane.ERROR_MESSAGE);
425         return;
426       }
427
428     String className = fileName.substring(0, fileName.length() - 5);
429     Color p1 = theme.getPrimary1();
430     Color p2 = theme.getPrimary2();
431     Color p3 = theme.getPrimary3();
432     Color s1 = theme.getSecondary1();
433     Color s2 = theme.getSecondary2();
434     Color s3 = theme.getSecondary3();
435
436     try
437       {
438         FileOutputStream out = new FileOutputStream(file);
439         Writer writer = new OutputStreamWriter(out);
440         writer.write("import javax.swing.plaf.ColorUIResource;\n");
441         writer.write("import javax.swing.plaf.metal.DefaultMetalTheme;\n");
442         writer.write("public class " + className + " extends DefaultMetalTheme\n");
443         writer.write("{\n");
444         writer.write("  protected ColorUIResource getPrimary1()\n");
445         writer.write("  {\n");
446         writer.write("    return new ColorUIResource(" + p1.getRGB() + ");\n");
447         writer.write("  }\n");
448         writer.write("  protected ColorUIResource getPrimary2()\n");
449         writer.write("  {\n");
450         writer.write("    return new ColorUIResource(" + p2.getRGB() + ");\n");
451         writer.write("  }\n");
452         writer.write("  protected ColorUIResource getPrimary3()\n");
453         writer.write("  {\n");
454         writer.write("    return new ColorUIResource(" + p3.getRGB() + ");\n");
455         writer.write("  }\n");
456         writer.write("  protected ColorUIResource getSecondary1()\n");
457         writer.write("  {\n");
458         writer.write("    return new ColorUIResource(" + s1.getRGB() + ");\n");
459         writer.write("  }\n");
460         writer.write("  protected ColorUIResource getSecondary2()\n");
461         writer.write("  {\n");
462         writer.write("    return new ColorUIResource(" + s2.getRGB() + ");\n");
463         writer.write("  }\n");
464         writer.write("  protected ColorUIResource getSecondary3()\n");
465         writer.write("  {\n");
466         writer.write("    return new ColorUIResource(" + s3.getRGB() + ");\n");
467         writer.write("  }\n");
468         writer.write("}\n");
469         writer.close();
470         out.close();
471       }
472     catch (FileNotFoundException ex)
473       {
474         ex.printStackTrace();
475       }
476     catch (IOException ex)
477       {
478         ex.printStackTrace();
479       }
480     
481   }
482
483   /**
484    * Returns the color of the theme with the specified type. For the possible
485    * types see the constants of this class.
486    *
487    * @param colorType the color type to fetch from the theme
488    *
489    * @return the current color of the specified type
490    *
491    * @throws IllegalArgumentException for illegal color types
492    */
493   Color getColor(int colorType)
494   {
495     Color color = null;
496     switch (colorType)
497     {
498     case PRIMARY1:
499       color = theme.getPrimary1();
500       break;
501     case PRIMARY2:
502       color = theme.getPrimary2();
503       break;
504     case PRIMARY3:
505       color = theme.getPrimary3();
506       break;
507     case SECONDARY1:
508       color = theme.getSecondary1();
509       break;
510     case SECONDARY2:
511       color = theme.getSecondary2();
512       break;
513     case SECONDARY3:
514       color = theme.getSecondary3();
515       break;
516     default:
517       throw new IllegalArgumentException("Unknown color type: " + colorType);
518     }
519     return color;
520   }
521
522   /**
523    * Sets the color of the specified type in the current theme.
524    *
525    * @param colorType the color type
526    * @param color the color to set
527    *
528    * @throws IllegalArgumentException for illegal color types
529    */
530   void setColor(int colorType, Color color)
531   {
532     switch (colorType)
533     {
534       case PRIMARY1:
535         theme.setPrimary1(color);
536         break;
537       case PRIMARY2:
538         theme.setPrimary2(color);
539         break;
540       case PRIMARY3:
541         theme.setPrimary3(color);
542         break;
543       case SECONDARY1:
544         theme.setSecondary1(color);
545         break;
546       case SECONDARY2:
547         theme.setSecondary2(color);
548         break;
549       case SECONDARY3:
550         theme.setSecondary3(color);
551         break;
552       default:
553         throw new IllegalArgumentException("Illegal color type: " + colorType);
554     }
555   }
556
557   /**
558    * The entry point to the application.
559    *
560    * @param args ignored
561    */
562   public static void main(String[] args)
563   {
564     JFrame f = new JFrame("MetalThemeEditor");
565     f.setContentPane(new MetalThemeEditor());
566     f.pack();
567     f.setVisible(true);
568   }
569
570   /**
571    * Returns a DemoFactory that creates a MetalThemeEditor.
572    *
573    * @return a DemoFactory that creates a MetalThemeEditor
574    */
575   public static DemoFactory createDemoFactory()
576   {
577     return new DemoFactory()
578     {
579       public JComponent createDemo()
580       {
581         return new MetalThemeEditor();
582       }
583     };
584   }
585 }