1   /*
2    *  Copyright (c) 1998-2005, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Valentin Tablan 13/12/2000
10   *
11   *  $Id: TextAttributesChooser.java,v 1.14 2005/01/11 13:51:34 ian Exp $
12   *
13   */
14  
15  package gate.gui;
16  import java.awt.*;
17  import java.awt.event.*;
18  
19  import javax.swing.*;
20  import javax.swing.colorchooser.AbstractColorChooserPanel;
21  import javax.swing.event.ChangeEvent;
22  import javax.swing.event.ChangeListener;
23  import javax.swing.text.*;
24  
25  import gate.util.Out;
26  
27  /**
28   * A dialog used to set the attributes for text display. The attribute set
29   * includes font family, size, foreground and background colours, italic,
30   * bold, etc.
31   */
32  public class TextAttributesChooser extends JDialog {
33  
34    JComboBox fontFamilyCombo;
35    JComboBox fontSizeCombo;
36    JCheckBox boldChk;
37    JCheckBox italicChk;
38    JCheckBox underlineChk;
39    JCheckBox subscriptChk;
40    JCheckBox superscriptChk;
41    JCheckBox strikethroughChk;
42  
43    JCheckBox useForegroundChk;
44    JCheckBox useBackgroundChk;
45  
46    JColorChooser fgChooser;
47    JColorChooser bgChooser;
48    JTextPane sampleText;
49    JButton okButton;
50    JButton cancelButton;
51  
52    MutableAttributeSet currentStyle;
53  
54    boolean choice;
55  
56  
57    public TextAttributesChooser(Frame parent, String title, boolean modal) {
58      super(parent, title, modal);
59      try {
60        jbInit();
61        pack();
62      }
63      catch(Exception ex) {
64        ex.printStackTrace();
65      }
66    }// public TextAttributesChooser(Frame parent, String title, boolean modal)
67  
68    public TextAttributesChooser(Dialog parent, String title, boolean modal) {
69      super(parent, title, modal);
70      try {
71        jbInit();
72        pack();
73      }
74      catch(Exception ex) {
75        ex.printStackTrace();
76      }
77    }// public TextAttributesChooser(Dialog parent, String title, boolean modal)
78  
79  
80    public TextAttributesChooser() {
81      this((Frame)null, "", false);
82    }// public TextAttributesChooser()
83  
84  
85    void jbInit() throws Exception {
86      sampleText = new JTextPane();
87      sampleText.setText("Type your own sample here...");
88      if(currentStyle == null){
89        StyleContext context = new StyleContext();
90        currentStyle = context.addStyle(null, null);
91        currentStyle.addAttributes(sampleText.getInputAttributes());
92      }
93      //The overall organisation is:
94      //First level
95        //Font Tab
96        //Foreground colour
97        //Background colour
98      //Second level
99        //Sample text
100     //Third level
101       //Ok Button
102       //Cancel Button
103 
104     Box contents = Box.createVerticalBox();
105     //FIRST LEVEL
106     JTabbedPane firstLevel = new JTabbedPane();
107     //Font stuff
108     Box fontBox = Box.createVerticalBox();
109 
110     fontFamilyCombo = new JComboBox(
111                         GraphicsEnvironment.getLocalGraphicsEnvironment().
112                         getAvailableFontFamilyNames()
113                       );
114     fontFamilyCombo.setSelectedItem(StyleConstants.getFontFamily(currentStyle));
115     fontSizeCombo = new JComboBox(new String[]{"6", "8", "10", "12", "14", "16",
116                                               "18", "20", "22", "24", "26"});
117     fontSizeCombo.setSelectedItem(new Integer(
118                         StyleConstants.getFontSize(currentStyle)).toString());
119     fontSizeCombo.setEditable(true);
120     JPanel box = new JPanel();
121     box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
122     box.add(fontFamilyCombo);
123     box.add(Box.createHorizontalStrut(5));
124     box.add(fontSizeCombo);
125     box.add(Box.createHorizontalGlue());
126     box.setBorder(BorderFactory.createTitledBorder("Font"));
127     fontBox.add(box);
128 
129     box = new JPanel();
130     box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
131     //First column
132     Box box1 = Box.createVerticalBox();
133     boldChk = new JCheckBox("<html><b>Bold</b></html>");
134     boldChk.setSelected(StyleConstants.isBold(currentStyle));
135     box1.add(boldChk);
136 
137 //    italicChk = new JCheckBox("<html><i>Italic</i></html>");
138 //    italicChk.setSelected(StyleConstants.isItalic(currentStyle));
139 //    box1.add(italicChk);
140     underlineChk = new JCheckBox("<html><u>Underline</u></html>");
141     underlineChk.setSelected(StyleConstants.isUnderline(currentStyle));
142 //    box1.add(underlineChk);
143     box.add(box1);
144 
145     //Second column
146     box1 = Box.createVerticalBox();
147     italicChk = new JCheckBox("<html><i>Italic</i></html>");
148     italicChk.setSelected(StyleConstants.isItalic(currentStyle));
149     box1.add(italicChk);
150 
151 
152     subscriptChk = new JCheckBox("<html>T<sub>Subscript</sub></html>");
153     subscriptChk.setSelected(StyleConstants.isSubscript(currentStyle));
154 //    box1.add(subscriptChk);
155     superscriptChk = new JCheckBox("<html>T<sup>Superscript</sup></html>");
156     superscriptChk.setSelected(StyleConstants.isSuperscript(currentStyle));
157 //    box1.add(superscriptChk);
158     strikethroughChk = new JCheckBox(
159                                 "<html><strike>Strikethrough</strike></html>");
160     strikethroughChk.setSelected(StyleConstants.isStrikeThrough(currentStyle));
161 //    box1.add(strikethroughChk);
162     box.add(box1);
163     box.add(Box.createHorizontalGlue());
164     box.setBorder(BorderFactory.createTitledBorder("Effects"));
165 
166     fontBox.add(box);
167 
168     //Use colors checkboxes
169     box = new JPanel();
170     box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
171     useForegroundChk = new JCheckBox("Use foreground colour");
172     useForegroundChk.setSelected(false);
173     box.add(useForegroundChk);
174 
175     useBackgroundChk = new JCheckBox("Use background colour");
176     useBackgroundChk.setSelected(false);
177     box.add(useBackgroundChk);
178 
179     box.add(Box.createHorizontalGlue());
180     box.setBorder(BorderFactory.createTitledBorder("Use Colours"));
181 
182     fontBox.add(box);
183 
184 
185     fontBox.add(Box.createVerticalGlue());
186     firstLevel.add("Font", fontBox);
187     //Colors stuff
188     fgChooser = new JColorChooser(StyleConstants.getForeground(currentStyle));
189     JTabbedPane tp = new JTabbedPane();
190     AbstractColorChooserPanel[] panels = fgChooser.getChooserPanels();
191     for(int i=0; i < panels.length; i++){
192       tp.add(panels[i].getDisplayName(), panels[i]);
193     }
194     firstLevel.add("Foreground", tp);
195     bgChooser = new JColorChooser(StyleConstants.getBackground(currentStyle));
196     tp = new JTabbedPane();
197     panels = bgChooser.getChooserPanels();
198     for(int i=0; i < panels.length; i++){
199       tp.add(panels[i].getDisplayName(), panels[i]);
200     }
201     firstLevel.add("Background", tp);
202 
203     contents.add(firstLevel);
204 
205     //SECOND LEVEL
206     JPanel secondLevel = new JPanel();
207     secondLevel.setBorder(BorderFactory.createTitledBorder("Sample"));
208     //Sample text
209     JScrollPane scroller = new JScrollPane(sampleText);
210     scroller.setPreferredSize(new Dimension(400, 50));
211     secondLevel.add(scroller);
212     secondLevel.add(Box.createHorizontalGlue());
213     contents.add(secondLevel);
214 
215     //THIRD LEVEL
216     //Buttons
217     Box thirdLevel = Box.createHorizontalBox();
218     okButton = new JButton("OK");
219     thirdLevel.add(okButton);
220     cancelButton = new JButton("Cancel");
221     thirdLevel.add(cancelButton);
222 
223     contents.add(thirdLevel);
224 
225     getContentPane().add(contents, BorderLayout.CENTER);
226 
227     fontFamilyCombo.addActionListener(new ActionListener(){
228       public void actionPerformed(ActionEvent e){
229         StyleConstants.setFontFamily(currentStyle,
230                                      (String)fontFamilyCombo.getSelectedItem());
231         updateSample();
232       }// public void actionPerformed(ActionEvent e)
233     });
234 
235     fontSizeCombo.addActionListener(new ActionListener(){
236       public void actionPerformed(ActionEvent e){
237         try {
238           Integer.parseInt((String)fontSizeCombo.getSelectedItem());
239         } catch(NumberFormatException nfe) {
240           fontSizeCombo.setSelectedIndex(3);
241         }
242         StyleConstants.setFontSize(currentStyle,
243                                    Integer.parseInt((String)
244                                    fontSizeCombo.getSelectedItem()));
245         updateSample();
246       }// public void actionPerformed(ActionEvent e)
247     });
248 
249     boldChk.addActionListener(new ActionListener() {
250       public void actionPerformed(ActionEvent e) {
251         StyleConstants.setBold(currentStyle, boldChk.isSelected());
252         updateSample();
253       }// public void actionPerformed(ActionEvent e)
254     });
255 
256     italicChk.addActionListener(new ActionListener() {
257       public void actionPerformed(ActionEvent e) {
258         StyleConstants.setItalic(currentStyle, italicChk.isSelected());
259         updateSample();
260       }// public void actionPerformed(ActionEvent e)
261     });
262 
263     underlineChk.addActionListener(new ActionListener() {
264       public void actionPerformed(ActionEvent e) {
265         if(underlineChk.isSelected()) strikethroughChk.setSelected(false);
266         StyleConstants.setUnderline(currentStyle, underlineChk.isSelected());
267         updateSample();
268       }// public void actionPerformed(ActionEvent e)
269     });
270 
271     strikethroughChk.addActionListener(new ActionListener() {
272       public void actionPerformed(ActionEvent e) {
273         if(strikethroughChk.isSelected()) underlineChk.setSelected(false);
274         StyleConstants.setStrikeThrough(currentStyle,
275                                                 strikethroughChk.isSelected());
276         updateSample();
277       }// public void actionPerformed(ActionEvent e)
278     });
279 
280     superscriptChk.addActionListener(new ActionListener() {
281       public void actionPerformed(ActionEvent e) {
282         if(superscriptChk.isSelected()) subscriptChk.setSelected(false);
283         StyleConstants.setSuperscript(currentStyle,
284                                                   superscriptChk.isSelected());
285         updateSample();
286       }// public void actionPerformed(ActionEvent e)
287     });
288 
289     subscriptChk.addActionListener(new ActionListener() {
290       public void actionPerformed(ActionEvent e) {
291         if(subscriptChk.isSelected()) superscriptChk.setSelected(false);
292         StyleConstants.setSubscript(currentStyle, subscriptChk.isSelected());
293         updateSample();
294       }// public void actionPerformed(ActionEvent e)
295     });
296 
297     fgChooser.getSelectionModel().addChangeListener(new ChangeListener() {
298       public void stateChanged(ChangeEvent e) {
299         StyleConstants.setForeground(currentStyle, fgChooser.getColor());
300         useForegroundChk.setSelected(true);
301         updateSample();
302       }// public void stateChanged(ChangeEvent e)
303     });
304 
305     useForegroundChk.addActionListener(new ActionListener() {
306       public void actionPerformed(ActionEvent e) {
307         if(useForegroundChk.isSelected()) {
308           StyleConstants.setForeground(currentStyle, fgChooser.getColor());
309         } else {
310           currentStyle.removeAttribute(StyleConstants.Foreground);
311         }
312         updateSample();
313       }// public void actionPerformed(ActionEvent e)
314     });
315 
316     bgChooser.getSelectionModel().addChangeListener(new ChangeListener() {
317       public void stateChanged(ChangeEvent e) {
318         StyleConstants.setBackground(currentStyle, bgChooser.getColor());
319         useBackgroundChk.setSelected(true);
320         updateSample();
321       }// public void stateChanged(ChangeEvent e)
322     });
323 
324     useBackgroundChk.addActionListener(new ActionListener() {
325       public void actionPerformed(ActionEvent e) {
326         if(useBackgroundChk.isSelected()) {
327           StyleConstants.setBackground(currentStyle, bgChooser.getColor());
328         } else {
329           currentStyle.removeAttribute(StyleConstants.Background);
330         }
331         updateSample();
332       }// public void actionPerformed(ActionEvent e)
333     });
334 
335     this.addComponentListener(new ComponentAdapter() {
336       public void componentShown(ComponentEvent e) {
337         updateSample();
338       }// public void componentShown(ComponentEvent e)
339     });
340 
341     okButton.addActionListener(new ActionListener() {
342       public void actionPerformed(ActionEvent e) {
343         choice = true;
344         setVisible(false);
345       }// public void actionPerformed(ActionEvent e)
346     });
347 
348     cancelButton.addActionListener(new ActionListener() {
349       public void actionPerformed(ActionEvent e) {
350         choice = false;
351         setVisible(false);
352       }// public void actionPerformed(ActionEvent e)
353     });
354 
355   }// void jbInit()
356 
357   /**
358    * Initialises all the values for the attributes from the provided attribute
359    * set and displays the dialog allowing the user to make changes.
360    * If the user presses the <b>OK</b> button the method will return the values
361    * as modified by the user otherwise it will return the attribute set received
362    * as input.
363    * @param style the attribute set to be used as a starting point for the user's
364    * selections
365    * @return an {@link javax.swing.text.AttributeSet} containing the values
366    * selected by the user.
367    */
368   public AttributeSet show(AttributeSet style) {
369     currentStyle = new SimpleAttributeSet(style);
370     //currentStyle.addAttributes(style);
371     updateData();
372     updateSample();
373     setModal(true);
374     super.setVisible(true);
375     if(choice) return currentStyle;
376     else return style;
377   }// public AttributeSet show(AttributeSet style)
378 
379   /**
380    * Updates all the GUI components to show the values in the current attribute
381    * set.
382    */
383   protected void updateData() {
384     fontFamilyCombo.setSelectedItem(StyleConstants.getFontFamily(currentStyle));
385     fontSizeCombo.setSelectedItem(new Integer(
386                         StyleConstants.getFontSize(currentStyle)).toString());
387     boldChk.setSelected(StyleConstants.isBold(currentStyle));
388     italicChk.setSelected(StyleConstants.isItalic(currentStyle));
389     italicChk.setSelected(StyleConstants.isItalic(currentStyle));
390     underlineChk.setSelected(StyleConstants.isUnderline(currentStyle));
391     subscriptChk.setSelected(StyleConstants.isSubscript(currentStyle));
392     superscriptChk.setSelected(StyleConstants.isSuperscript(currentStyle));
393     strikethroughChk.setSelected(StyleConstants.isStrikeThrough(currentStyle));
394     if(currentStyle.isDefined(StyleConstants.Foreground)){
395       fgChooser.setColor(StyleConstants.getForeground(currentStyle));
396       useForegroundChk.setSelected(true);
397     } else useForegroundChk.setSelected(false);
398     if(currentStyle.isDefined(StyleConstants.Background)){
399       bgChooser.setColor(StyleConstants.getBackground(currentStyle));
400       useBackgroundChk.setSelected(true);
401     } else useBackgroundChk.setSelected(false);
402   }// protected void updateData()
403 
404   /**
405    * Updates the sample text with the current attributes.
406    */
407   protected void updateSample() {
408     if(sampleText.getSelectedText() != null &&
409        sampleText.getSelectedText().length() > 0){
410       sampleText.setCharacterAttributes(currentStyle, true);
411     } else {
412       sampleText.selectAll();
413       sampleText.setCharacterAttributes(currentStyle, true);
414       sampleText.setSelectionStart(0);
415       sampleText.setSelectionEnd(0);
416     }
417   }//protected void updateSample()
418 
419   /**
420    * Test code
421    */
422   public static void main(String[] args) {
423     try {
424       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
425       JFrame frame = new JFrame("Frame");
426       frame.addWindowListener(new WindowAdapter(){
427         public void windowClosing(WindowEvent e){
428           System.exit(0);
429         }
430       });
431       final TextAttributesChooser dialog = new TextAttributesChooser(frame,
432                                                               "Dialog", false);
433       //frame.getContentPane().add(dialog.getContentPane().getComponent(0));
434       JButton btn = new JButton("Display Dialog");
435       btn.addActionListener(new ActionListener(){
436         public void actionPerformed(ActionEvent e){
437           Style style = new StyleContext().addStyle(null,null);
438           StyleConstants.setBackground(style, Color.white);
439           Out.println(dialog.show(style));
440         }// public void actionPerformed(ActionEvent e)
441       });
442       frame.getContentPane().add(btn);
443       frame.pack();
444       frame.setVisible(true);
445 
446     } catch(Exception e){
447       e.printStackTrace();
448     }
449   }// main
450 }// class TextAttributesChooser extends JDialog