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