TextAttributesChooser.java
001 /*
002  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004  *
005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
006  *  software, licenced under the GNU Library General Public License,
007  *  Version 2, June 1991 (in the distribution as file licence.html,
008  *  and also available at http://gate.ac.uk/gate/licence.html).
009  *
010  *  Valentin Tablan 13/12/2000
011  *
012  *  $Id: TextAttributesChooser.java 12006 2009-12-01 17:24:28Z thomas_heitz $
013  *
014  */
015 
016 package gate.gui;
017 import java.awt.*;
018 import java.awt.event.*;
019 
020 import javax.swing.*;
021 import javax.swing.colorchooser.AbstractColorChooserPanel;
022 import javax.swing.event.ChangeEvent;
023 import javax.swing.event.ChangeListener;
024 import javax.swing.text.*;
025 
026 import gate.util.Out;
027 
028 /**
029  * A dialog used to set the attributes for text display. The attribute set
030  * includes font family, size, foreground and background colours, italic,
031  * bold, etc.
032  */
033 public class TextAttributesChooser extends JDialog {
034 
035   JComboBox fontFamilyCombo;
036   JComboBox fontSizeCombo;
037   JCheckBox boldChk;
038   JCheckBox italicChk;
039   JCheckBox underlineChk;
040   JCheckBox subscriptChk;
041   JCheckBox superscriptChk;
042   JCheckBox strikethroughChk;
043 
044   JCheckBox useForegroundChk;
045   JCheckBox useBackgroundChk;
046 
047   JColorChooser fgChooser;
048   JColorChooser bgChooser;
049   JTextPane sampleText;
050   JButton okButton;
051   JButton cancelButton;
052 
053   MutableAttributeSet currentStyle;
054 
055   boolean choice;
056 
057 
058   public TextAttributesChooser(Frame parent, String title, boolean modal) {
059     super(parent, title, modal);
060     try {
061       jbInit();
062       pack();
063     }
064     catch(Exception ex) {
065       ex.printStackTrace();
066     }
067   }// public TextAttributesChooser(Frame parent, String title, boolean modal)
068 
069   public TextAttributesChooser(Dialog parent, String title, boolean modal) {
070     super(parent, title, modal);
071     try {
072       jbInit();
073       pack();
074     }
075     catch(Exception ex) {
076       ex.printStackTrace();
077     }
078   }// public TextAttributesChooser(Dialog parent, String title, boolean modal)
079 
080 
081   public TextAttributesChooser() {
082     this((Frame)null, ""false);
083   }// public TextAttributesChooser()
084 
085 
086   void jbInit() throws Exception {
087     sampleText = new JTextPane();
088     sampleText.setText("Type your own sample here...");
089     if(currentStyle == null){
090       StyleContext context = new StyleContext();
091       currentStyle = context.addStyle(null, null);
092       currentStyle.addAttributes(sampleText.getInputAttributes());
093     }
094     //The overall organisation is:
095     //First level
096       //Font Tab
097       //Foreground colour
098       //Background colour
099     //Second level
100       //Sample text
101     //Third level
102       //Ok Button
103       //Cancel Button
104 
105     Box contents = Box.createVerticalBox();
106     //FIRST LEVEL
107     JTabbedPane firstLevel = new JTabbedPane();
108     //Font stuff
109     Box fontBox = Box.createVerticalBox();
110 
111     fontFamilyCombo = new JComboBox(
112                         GraphicsEnvironment.getLocalGraphicsEnvironment().
113                         getAvailableFontFamilyNames()
114                       );
115     fontFamilyCombo.setSelectedItem(StyleConstants.getFontFamily(currentStyle));
116     fontSizeCombo = new JComboBox(new String[]{"6""8""10""12""14""16",
117                                               "18""20""22""24""26"});
118     fontSizeCombo.setSelectedItem(new Integer(
119                         StyleConstants.getFontSize(currentStyle)).toString());
120     fontSizeCombo.setEditable(true);
121     JPanel box = new JPanel();
122     box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
123     box.add(fontFamilyCombo);
124     box.add(Box.createHorizontalStrut(5));
125     box.add(fontSizeCombo);
126     box.add(Box.createHorizontalGlue());
127     box.setBorder(BorderFactory.createTitledBorder("Font"));
128     fontBox.add(box);
129 
130     box = new JPanel();
131     box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
132     //First column
133     Box box1 = Box.createVerticalBox();
134     boldChk = new JCheckBox("<html><b>Bold</b></html>");
135     boldChk.setSelected(StyleConstants.isBold(currentStyle));
136     box1.add(boldChk);
137 
138 //    italicChk = new JCheckBox("<html><i>Italic</i></html>");
139 //    italicChk.setSelected(StyleConstants.isItalic(currentStyle));
140 //    box1.add(italicChk);
141     underlineChk = new JCheckBox("<html><u>Underline</u></html>");
142     underlineChk.setSelected(StyleConstants.isUnderline(currentStyle));
143 //    box1.add(underlineChk);
144     box.add(box1);
145 
146     //Second column
147     box1 = Box.createVerticalBox();
148     italicChk = new JCheckBox("<html><i>Italic</i></html>");
149     italicChk.setSelected(StyleConstants.isItalic(currentStyle));
150     box1.add(italicChk);
151 
152 
153     subscriptChk = new JCheckBox("<html>T<sub>Subscript</sub></html>");
154     subscriptChk.setSelected(StyleConstants.isSubscript(currentStyle));
155 //    box1.add(subscriptChk);
156     superscriptChk = new JCheckBox("<html>T<sup>Superscript</sup></html>");
157     superscriptChk.setSelected(StyleConstants.isSuperscript(currentStyle));
158 //    box1.add(superscriptChk);
159     strikethroughChk = new JCheckBox(
160                                 "<html><strike>Strikethrough</strike></html>");
161     strikethroughChk.setSelected(StyleConstants.isStrikeThrough(currentStyle));
162 //    box1.add(strikethroughChk);
163     box.add(box1);
164     box.add(Box.createHorizontalGlue());
165     box.setBorder(BorderFactory.createTitledBorder("Effects"));
166 
167     fontBox.add(box);
168 
169     //Use colors checkboxes
170     box = new JPanel();
171     box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
172     useForegroundChk = new JCheckBox("Use foreground colour");
173     useForegroundChk.setSelected(false);
174     box.add(useForegroundChk);
175 
176     useBackgroundChk = new JCheckBox("Use background colour");
177     useBackgroundChk.setSelected(false);
178     box.add(useBackgroundChk);
179 
180     box.add(Box.createHorizontalGlue());
181     box.setBorder(BorderFactory.createTitledBorder("Use Colours"));
182 
183     fontBox.add(box);
184 
185 
186     fontBox.add(Box.createVerticalGlue());
187     firstLevel.add("Font", fontBox);
188     //Colors stuff
189     fgChooser = new JColorChooser(StyleConstants.getForeground(currentStyle));
190     JTabbedPane tp = new JTabbedPane();
191     AbstractColorChooserPanel[] panels = fgChooser.getChooserPanels();
192     for(int i=0; i < panels.length; i++){
193       tp.add(panels[i].getDisplayName(), panels[i]);
194     }
195     firstLevel.add("Foreground", tp);
196     bgChooser = new JColorChooser(StyleConstants.getBackground(currentStyle));
197     tp = new JTabbedPane();
198     panels = bgChooser.getChooserPanels();
199     for(int i=0; i < panels.length; i++){
200       tp.add(panels[i].getDisplayName(), panels[i]);
201     }
202     firstLevel.add("Background", tp);
203 
204     contents.add(firstLevel);
205 
206     //SECOND LEVEL
207     JPanel secondLevel = new JPanel();
208     secondLevel.setBorder(BorderFactory.createTitledBorder("Sample"));
209     //Sample text
210     JScrollPane scroller = new JScrollPane(sampleText);
211     scroller.setPreferredSize(new Dimension(40050));
212     secondLevel.add(scroller);
213     secondLevel.add(Box.createHorizontalGlue());
214     contents.add(secondLevel);
215 
216     //THIRD LEVEL
217     //Buttons
218     Box thirdLevel = Box.createHorizontalBox();
219     okButton = new JButton("OK");
220     thirdLevel.add(okButton);
221     cancelButton = new JButton("Cancel");
222     thirdLevel.add(cancelButton);
223 
224     contents.add(thirdLevel);
225 
226     getContentPane().add(contents, BorderLayout.CENTER);
227 
228     fontFamilyCombo.addActionListener(new ActionListener(){
229       public void actionPerformed(ActionEvent e){
230         StyleConstants.setFontFamily(currentStyle,
231                                      (String)fontFamilyCombo.getSelectedItem());
232         updateSample();
233       }// public void actionPerformed(ActionEvent e)
234     });
235 
236     fontSizeCombo.addActionListener(new ActionListener(){
237       public void actionPerformed(ActionEvent e){
238         try {
239           Integer.parseInt((String)fontSizeCombo.getSelectedItem());
240         catch(NumberFormatException nfe) {
241           fontSizeCombo.setSelectedIndex(3);
242         }
243         StyleConstants.setFontSize(currentStyle,
244                                    Integer.parseInt((String)
245                                    fontSizeCombo.getSelectedItem()));
246         updateSample();
247       }// public void actionPerformed(ActionEvent e)
248     });
249 
250     boldChk.addActionListener(new ActionListener() {
251       public void actionPerformed(ActionEvent e) {
252         StyleConstants.setBold(currentStyle, boldChk.isSelected());
253         updateSample();
254       }// public void actionPerformed(ActionEvent e)
255     });
256 
257     italicChk.addActionListener(new ActionListener() {
258       public void actionPerformed(ActionEvent e) {
259         StyleConstants.setItalic(currentStyle, italicChk.isSelected());
260         updateSample();
261       }// public void actionPerformed(ActionEvent e)
262     });
263 
264     underlineChk.addActionListener(new ActionListener() {
265       public void actionPerformed(ActionEvent e) {
266         if(underlineChk.isSelected()) strikethroughChk.setSelected(false);
267         StyleConstants.setUnderline(currentStyle, underlineChk.isSelected());
268         updateSample();
269       }// public void actionPerformed(ActionEvent e)
270     });
271 
272     strikethroughChk.addActionListener(new ActionListener() {
273       public void actionPerformed(ActionEvent e) {
274         if(strikethroughChk.isSelected()) underlineChk.setSelected(false);
275         StyleConstants.setStrikeThrough(currentStyle,
276                                                 strikethroughChk.isSelected());
277         updateSample();
278       }// public void actionPerformed(ActionEvent e)
279     });
280 
281     superscriptChk.addActionListener(new ActionListener() {
282       public void actionPerformed(ActionEvent e) {
283         if(superscriptChk.isSelected()) subscriptChk.setSelected(false);
284         StyleConstants.setSuperscript(currentStyle,
285                                                   superscriptChk.isSelected());
286         updateSample();
287       }// public void actionPerformed(ActionEvent e)
288     });
289 
290     subscriptChk.addActionListener(new ActionListener() {
291       public void actionPerformed(ActionEvent e) {
292         if(subscriptChk.isSelected()) superscriptChk.setSelected(false);
293         StyleConstants.setSubscript(currentStyle, subscriptChk.isSelected());
294         updateSample();
295       }// public void actionPerformed(ActionEvent e)
296     });
297 
298     fgChooser.getSelectionModel().addChangeListener(new ChangeListener() {
299       public void stateChanged(ChangeEvent e) {
300         StyleConstants.setForeground(currentStyle, fgChooser.getColor());
301         useForegroundChk.setSelected(true);
302         updateSample();
303       }// public void stateChanged(ChangeEvent e)
304     });
305 
306     useForegroundChk.addActionListener(new ActionListener() {
307       public void actionPerformed(ActionEvent e) {
308         if(useForegroundChk.isSelected()) {
309           StyleConstants.setForeground(currentStyle, fgChooser.getColor());
310         else {
311           currentStyle.removeAttribute(StyleConstants.Foreground);
312         }
313         updateSample();
314       }// public void actionPerformed(ActionEvent e)
315     });
316 
317     bgChooser.getSelectionModel().addChangeListener(new ChangeListener() {
318       public void stateChanged(ChangeEvent e) {
319         StyleConstants.setBackground(currentStyle, bgChooser.getColor());
320         useBackgroundChk.setSelected(true);
321         updateSample();
322       }// public void stateChanged(ChangeEvent e)
323     });
324 
325     useBackgroundChk.addActionListener(new ActionListener() {
326       public void actionPerformed(ActionEvent e) {
327         if(useBackgroundChk.isSelected()) {
328           StyleConstants.setBackground(currentStyle, bgChooser.getColor());
329         else {
330           currentStyle.removeAttribute(StyleConstants.Background);
331         }
332         updateSample();
333       }// public void actionPerformed(ActionEvent e)
334     });
335 
336     this.addComponentListener(new ComponentAdapter() {
337       public void componentShown(ComponentEvent e) {
338         updateSample();
339       }// public void componentShown(ComponentEvent e)
340     });
341 
342     okButton.addActionListener(new ActionListener() {
343       public void actionPerformed(ActionEvent e) {
344         choice = true;
345         setVisible(false);
346       }// public void actionPerformed(ActionEvent e)
347     });
348 
349     cancelButton.addActionListener(new ActionListener() {
350       public void actionPerformed(ActionEvent e) {
351         choice = false;
352         setVisible(false);
353       }// public void actionPerformed(ActionEvent e)
354     });
355 
356   }// void jbInit()
357 
358   /**
359    * Initialises all the values for the attributes from the provided attribute
360    * set and displays the dialog allowing the user to make changes.
361    * If the user presses the <b>OK</b> button the method will return the values
362    * as modified by the user otherwise it will return the attribute set received
363    * as input.
364    @param style the attribute set to be used as a starting point for the user's
365    * selections
366    @return an {@link javax.swing.text.AttributeSet} containing the values
367    * selected by the user.
368    */
369   public AttributeSet show(AttributeSet style) {
370     currentStyle = new SimpleAttributeSet(style);
371     //currentStyle.addAttributes(style);
372     updateData();
373     updateSample();
374     setModal(true);
375     super.setVisible(true);
376     if(choicereturn currentStyle;
377     else return style;
378   }// public AttributeSet show(AttributeSet style)
379 
380   /**
381    * Updates all the GUI components to show the values in the current attribute
382    * set.
383    */
384   protected void updateData() {
385     fontFamilyCombo.setSelectedItem(StyleConstants.getFontFamily(currentStyle));
386     fontSizeCombo.setSelectedItem(new Integer(
387                         StyleConstants.getFontSize(currentStyle)).toString());
388     boldChk.setSelected(StyleConstants.isBold(currentStyle));
389     italicChk.setSelected(StyleConstants.isItalic(currentStyle));
390     italicChk.setSelected(StyleConstants.isItalic(currentStyle));
391     underlineChk.setSelected(StyleConstants.isUnderline(currentStyle));
392     subscriptChk.setSelected(StyleConstants.isSubscript(currentStyle));
393     superscriptChk.setSelected(StyleConstants.isSuperscript(currentStyle));
394     strikethroughChk.setSelected(StyleConstants.isStrikeThrough(currentStyle));
395     if(currentStyle.isDefined(StyleConstants.Foreground)){
396       fgChooser.setColor(StyleConstants.getForeground(currentStyle));
397       useForegroundChk.setSelected(true);
398     else useForegroundChk.setSelected(false);
399     if(currentStyle.isDefined(StyleConstants.Background)){
400       bgChooser.setColor(StyleConstants.getBackground(currentStyle));
401       useBackgroundChk.setSelected(true);
402     else useBackgroundChk.setSelected(false);
403   }// protected void updateData()
404 
405   /**
406    * Updates the sample text with the current attributes.
407    */
408   protected void updateSample() {
409     if(sampleText.getSelectedText() != null &&
410        sampleText.getSelectedText().length() 0){
411       sampleText.setCharacterAttributes(currentStyle, true);
412     else {
413       sampleText.selectAll();
414       sampleText.setCharacterAttributes(currentStyle, true);
415       sampleText.setSelectionStart(0);
416       sampleText.setSelectionEnd(0);
417     }
418   }//protected void updateSample()
419 
420   /**
421    * Test code
422    */
423   public static void main(String[] args) {
424     try {
425       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
426       JFrame frame = new JFrame("Frame");
427       frame.addWindowListener(new WindowAdapter(){
428         public void windowClosing(WindowEvent e){
429           System.exit(0);
430         }
431       });
432       final TextAttributesChooser dialog = new TextAttributesChooser(frame,
433                                                               "Dialog"false);
434       //frame.getContentPane().add(dialog.getContentPane().getComponent(0));
435       JButton btn = new JButton("Display Dialog");
436       btn.addActionListener(new ActionListener(){
437         public void actionPerformed(ActionEvent e){
438           Style style = new StyleContext().addStyle(null,null);
439           StyleConstants.setBackground(style, Color.white);
440           Out.println(dialog.show(style));
441         }// public void actionPerformed(ActionEvent e)
442       });
443       frame.getContentPane().add(btn);
444       frame.pack();
445       frame.setVisible(true);
446 
447     catch(Exception e){
448       e.printStackTrace();
449     }
450   }// main
451 }// class TextAttributesChooser extends JDialog