f4d1ab18a990107766544121d7b9d217e1c6a652
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / actions / EditFormatAction.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010-2011 - DIGITEO - Clement DAVID
4  * Copyright (C) 2011-2015 - Scilab Enterprises - Clement DAVID
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 package org.scilab.modules.xcos.actions;
18
19 import java.awt.Color;
20 import java.awt.Dimension;
21 import java.awt.Font;
22 import java.awt.Frame;
23 import java.awt.GraphicsEnvironment;
24 import java.awt.Toolkit;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.KeyEvent;
28 import java.io.File;
29 import java.net.MalformedURLException;
30 import java.net.URI;
31 import java.net.URISyntaxException;
32 import java.net.URL;
33
34 import javax.swing.BorderFactory;
35 import javax.swing.SpinnerModel;
36 import javax.swing.event.ChangeEvent;
37 import javax.swing.event.ChangeListener;
38
39 import org.scilab.modules.graph.ScilabComponent;
40 import org.scilab.modules.graph.ScilabGraph;
41 import org.scilab.modules.graph.actions.base.DefaultAction;
42 import org.scilab.modules.graph.utils.StyleMap;
43 import org.scilab.modules.gui.menuitem.MenuItem;
44 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
45 import org.scilab.modules.xcos.block.SuperBlock;
46 import org.scilab.modules.xcos.block.TextBlock;
47 import org.scilab.modules.xcos.graph.XcosDiagram;
48 import org.scilab.modules.xcos.utils.XcosMessages;
49
50 import com.mxgraph.model.mxCell;
51 import com.mxgraph.model.mxGraphModel;
52 import com.mxgraph.util.mxConstants;
53 import com.mxgraph.util.mxEvent;
54 import com.mxgraph.util.mxEventObject;
55 import com.mxgraph.util.mxUtils;
56
57 /**
58  * Customize the block representation.
59  */
60 @SuppressWarnings(value = { "serial" })
61 public final class EditFormatAction extends DefaultAction {
62     /**
63      * Name of the action
64      */
65     public static final String NAME = XcosMessages.EDIT + XcosMessages.DOTS;
66     /**
67      * Icon of the action
68      */
69     public static final String SMALL_ICON = "select-by-color";
70     /**
71      * Mnemonic key for the action
72      */
73     public static final int MNEMONIC_KEY = KeyEvent.VK_F2;
74     /**
75      * Accelerator key for the action
76      */
77     public static final int ACCELERATOR_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
78
79     /**
80      * The default color used on non initialized border color.
81      */
82     private static final Color DEFAULT_BORDERCOLOR = Color.BLACK;
83     /**
84      * The default color used on non initialized filled color.
85      */
86     private static final Color DEFAULT_FILLCOLOR = Color.WHITE;
87
88     /**
89      * Default constructor
90      *
91      * @param scilabGraph
92      *            the current graph
93      */
94     public EditFormatAction(ScilabGraph scilabGraph) {
95         super(scilabGraph);
96     }
97
98     /**
99      * Menu added to the menubar
100      *
101      * @param scilabGraph
102      *            associated diagram
103      * @return the menu
104      */
105     public static MenuItem createMenu(ScilabGraph scilabGraph) {
106         return createMenu(scilabGraph, EditFormatAction.class);
107     }
108
109     /**
110      * Create a new dialog for editing this cell
111      *
112      * @param c
113      *            the current component
114      * @param name
115      *            the window name
116      * @param selectedCell
117      *            the selected cell
118      * @param graph
119      *            the current graph
120      */
121     public static void showDialog(ScilabComponent c, String name, mxCell selectedCell, XcosDiagram graph) {
122         /*
123          * Looking for the parent window
124          */
125         final Frame window = javax.swing.JOptionPane.getFrameForComponent(c);
126
127         /*
128          * Create and show the dialog
129          */
130         EditFormatDialog dialog = createDialog(selectedCell, graph, window);
131         dialog.setName(name);
132         dialog.setVisible(true);
133     }
134
135     /**
136      * Create the dialog and set the default values
137      *
138      * @param cell
139      *            the current selected cell
140      * @param graph
141      *            the current graph
142      * @param window
143      *            the current windows
144      * @return the instantiated dialog
145      */
146     // CSOFF: NPathComplexity
147     // CSOFF: JavaNCSS
148     private static EditFormatDialog createDialog(final mxCell cell, final XcosDiagram graph, final Frame window) {
149         String working;
150         Color border;
151         Color fill;
152         String font;
153         int fontSize;
154         int fontStyle;
155         Color textColor;
156         String text;
157         String image = null;
158
159         final mxGraphModel model = (mxGraphModel) graph.getModel();
160         final StyleMap cellStyle = new StyleMap(cell.getStyle());
161
162         final mxCell identifier;
163         final StyleMap identifierStyle;
164         if (cell instanceof TextBlock) {
165             identifier = cell;
166             identifierStyle = cellStyle;
167         } else {
168             identifier = graph.getOrCreateCellIdentifier(cell);
169             identifierStyle = new StyleMap(identifier.getStyle());
170         }
171
172         /*
173          * Stroke color
174          */
175         working = cellStyle.get(mxConstants.STYLE_STROKECOLOR);
176         if (working == null) {
177             border = DEFAULT_BORDERCOLOR;
178         } else {
179             border = mxUtils.parseColor(working);
180         }
181
182         /*
183          * Fill color
184          */
185         working = cellStyle.get(mxConstants.STYLE_FILLCOLOR);
186         if (working == null) {
187             fill = DEFAULT_FILLCOLOR;
188         } else {
189             fill = mxUtils.parseColor(working);
190         }
191
192         /*
193          * Font
194          */
195         working = identifierStyle.get(mxConstants.STYLE_FONTFAMILY);
196         if (working == null) {
197             font = mxConstants.DEFAULT_FONTFAMILY;
198         } else {
199             font = working;
200         }
201
202         /*
203          * Font size
204          */
205         working = identifierStyle.get(mxConstants.STYLE_FONTSIZE);
206         if (working == null) {
207             fontSize = mxConstants.DEFAULT_FONTSIZE;
208         } else {
209             fontSize = Integer.parseInt(working);
210         }
211
212         /*
213          * Font modifier
214          */
215         working = identifierStyle.get(mxConstants.STYLE_FONTSTYLE);
216         if (working == null) {
217             fontStyle = 0;
218         } else {
219             fontStyle = Integer.parseInt(working);
220         }
221
222         /*
223          * Font color
224          */
225         working = identifierStyle.get(mxConstants.STYLE_FONTCOLOR);
226         if (working == null) {
227             textColor = Color.BLACK;
228         } else {
229             textColor = mxUtils.parseColor(working);
230         }
231
232         /*
233          * Image
234          */
235         working = cellStyle.get(mxConstants.STYLE_IMAGE);
236         if (working != null) {
237             image = working;
238         }
239
240         /*
241          * Text
242          */
243         final Object current = model.getValue(identifier);
244         if (current == null) {
245             text = "";
246         } else {
247             text = mxUtils.getBodyMarkup(current.toString(), false);
248         }
249
250         EditFormatDialog dialog = new EditFormatDialog(window);
251         dialog.setValues(border, fill, font, fontSize, fontStyle, textColor, text, image);
252         dialog.setGraph(graph);
253         dialog.setCell(cell);
254         return dialog;
255     }
256
257     // CSON: JavaNCSS
258     // CSON: NPathComplexity
259
260     /**
261      * Update the cell value from the dialog ones.
262      *
263      * @param dialog
264      *            the current dialog
265      * @param borderColor
266      *            the selected border color
267      * @param backgroundColor
268      *            the selected background color
269      * @param fontName
270      *            the selected font name
271      * @param fontSize
272      *            the selected font size
273      * @param isBold
274      *            is the text bold ?
275      * @param isItalic
276      *            is the text italic ?
277      * @param textColor
278      *            the selected color
279      * @param text
280      *            the typed text
281      * @param image
282      *            the image URL
283      */
284     // CSOFF: NPathComplexity
285     private static void updateFromDialog(EditFormatDialog dialog, Color borderColor, Color backgroundColor, String fontName, int fontSize, Color textColor,
286                                          boolean isBold, boolean isItalic, String text, String image) {
287         final XcosDiagram graph = dialog.getGraph();
288         final mxGraphModel model = (mxGraphModel) graph.getModel();
289
290         final mxCell cell = dialog.getCell();
291         final StyleMap cellStyle = new StyleMap(cell.getStyle());
292
293         final mxCell identifier;
294         final StyleMap identifierStyle;
295         if (cell instanceof TextBlock) {
296             identifier = cell;
297             identifierStyle = cellStyle;
298         } else {
299             identifier = graph.getOrCreateCellIdentifier(cell);
300             identifierStyle = new StyleMap(identifier.getStyle());
301         }
302
303         if (!borderColor.equals(DEFAULT_BORDERCOLOR)) {
304             cellStyle.put(mxConstants.STYLE_STROKECOLOR, mxUtils.hexString(borderColor));
305         } else {
306             cellStyle.remove(mxConstants.STYLE_STROKECOLOR);
307         }
308
309         if (!backgroundColor.equals(DEFAULT_FILLCOLOR)) {
310             cellStyle.put(mxConstants.STYLE_FILLCOLOR, mxUtils.hexString(backgroundColor));
311         } else {
312             cellStyle.remove(mxConstants.STYLE_FILLCOLOR);
313         }
314
315         if (!fontName.equals(mxConstants.DEFAULT_FONTFAMILY)) {
316             identifierStyle.put(mxConstants.STYLE_FONTFAMILY, fontName);
317         } else {
318             identifierStyle.remove(mxConstants.STYLE_FONTFAMILY);
319         }
320
321         applyFontStyle(isBold, isItalic, identifierStyle);
322
323         if (fontSize != mxConstants.DEFAULT_FONTSIZE) {
324             identifierStyle.put(mxConstants.STYLE_FONTSIZE, Integer.toString(fontSize));
325         } else {
326             identifierStyle.remove(mxConstants.DEFAULT_FONTSIZE);
327         }
328
329         if (!textColor.equals(DEFAULT_BORDERCOLOR)) {
330             identifierStyle.put(mxConstants.STYLE_FONTCOLOR, mxUtils.hexString(textColor));
331         } else {
332             identifierStyle.remove(mxConstants.STYLE_FONTCOLOR);
333         }
334
335         applyImage(image, cellStyle);
336
337         model.setStyle(cell, cellStyle.toString());
338         if (cell != identifier) {
339             model.setStyle(identifier, identifierStyle.toString());
340         }
341
342         graph.cellLabelChanged(identifier, text, false);
343         graph.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED, "cell", identifier, "value", text, "parent", cell));
344
345         /*
346          * Should also update diagram title
347          */
348         if (cell instanceof SuperBlock) {
349             graph.cellLabelChanged(cell, text, false);
350         }
351     }
352
353     // CSON: NPathComplexity
354
355     /**
356      * Reset to the default values
357      *
358      * @param dialog
359      *            the dialog to reset
360      */
361     private static void reset(EditFormatDialog dialog) {
362         final XcosDiagram graph = dialog.getGraph();
363         final mxGraphModel model = (mxGraphModel) graph.getModel();
364
365         final mxCell cell = dialog.getCell();
366         final StyleMap cellStyle = new StyleMap(cell.getStyle());
367
368         final mxCell identifier;
369         if (cell instanceof TextBlock) {
370             identifier = cell;
371         } else {
372             identifier = graph.getCellIdentifier(cell);
373             if (identifier != null) {
374                 model.remove(identifier);
375             }
376         }
377
378         cellStyle.clear();
379
380         dialog.setValues(DEFAULT_BORDERCOLOR, DEFAULT_FILLCOLOR, mxConstants.DEFAULT_FONTFAMILY, mxConstants.DEFAULT_FONTSIZE, 0, DEFAULT_BORDERCOLOR, "", null);
381
382         dialog.updateFont();
383     }
384
385     /**
386      * Apply image to the identifier style
387      *
388      * @param image
389      *            the image path
390      * @param cellStyle
391      *            the cell style
392      */
393     private static void applyImage(String image, final StyleMap cellStyle) {
394         if (image != null && !image.isEmpty()) {
395             String path;
396             try {
397                 URL url = new URL(image);
398                 path = url.toExternalForm();
399             } catch (MalformedURLException e) {
400                 path = image;
401             }
402
403             cellStyle.put(mxConstants.STYLE_IMAGE, path);
404         } else {
405             cellStyle.remove(mxConstants.STYLE_IMAGE);
406         }
407     }
408
409     /**
410      * Apply font style to the identifier style
411      *
412      * @param isBold
413      *            true if the font is bold
414      * @param isItalic
415      *            true is the font is italic
416      * @param identifierStyle
417      *            the identifier style
418      */
419     private static void applyFontStyle(boolean isBold, boolean isItalic, final StyleMap identifierStyle) {
420         int fontStyle = 0;
421         if (isBold) {
422             fontStyle |= mxConstants.FONT_BOLD;
423         }
424         if (isItalic) {
425             fontStyle |= mxConstants.FONT_ITALIC;
426         }
427
428         if (fontStyle != 0) {
429             identifierStyle.put(mxConstants.STYLE_FONTSTYLE, Integer.toString(fontStyle));
430         } else {
431             identifierStyle.remove(mxConstants.STYLE_FONTSTYLE);
432         }
433     }
434
435     /**
436      * Open a dialog to set the parameters
437      *
438      * @param e
439      *            the current event
440      * @see org.scilab.modules.graph.actions.base.DefaultAction#actionPerformed(java.awt.event.ActionEvent)
441      */
442     @Override
443     public void actionPerformed(ActionEvent e) {
444         XcosDiagram graph = (XcosDiagram) getGraph(null);
445         final Object selectedCell = graph.getSelectionCell();
446
447         if (selectedCell == null) {
448             return;
449         }
450
451         EditFormatAction.showDialog((ScilabComponent) graph.getAsComponent(), NAME, (mxCell) selectedCell, graph);
452
453         graph.getView().clear(selectedCell, true, true);
454         graph.refresh();
455     }
456
457     /**
458      * Dialog used to edit the current cell.
459      *
460      * This class perform UI instantiation and thus doesn't pass checkstyle
461      * metrics.
462      */
463     // CSOFF: ClassDataAbstractionCoupling
464     // CSOFF: ClassFanOutComplexity
465     private static final class EditFormatDialog extends javax.swing.JDialog {
466         private static final int TEXT_AREA_ROWS = 5;
467         private static final int TEXT_AREA_COLUMNS = 20;
468
469         /**
470          * The default model used to set a font size.
471          */
472         private static final SpinnerModel FONTSIZE_MODEL = new javax.swing.SpinnerNumberModel(10, 0, 100, 1);
473         /**
474          * The default border size used to separate buttons
475          */
476         private static final int BORDER_SIZE = 10;
477
478         private javax.swing.JColorChooser backgroundColorChooser;
479         private javax.swing.JColorChooser borderColorChooser;
480         private javax.swing.JColorChooser textColorChooser;
481         private javax.swing.JComboBox fontNameComboBox;
482         private javax.swing.JLabel fontNameLabel;
483         private javax.swing.JSpinner fontSizeSpinner;
484         private javax.swing.JLabel fontSizeLabel;
485         private javax.swing.JCheckBox fontStyleBold;
486         private javax.swing.JCheckBox fontStyleItalic;
487         private javax.swing.JLabel fontStyleLabel;
488         private javax.swing.JPanel backgroundPane;
489
490         private javax.swing.JLabel imagePathLabel;
491         private javax.swing.JTextField imagePath;
492         private javax.swing.JButton imageFileChooserBtn;
493
494         private javax.swing.JPanel jPanel2;
495         private javax.swing.JScrollPane jScrollPane1;
496         private javax.swing.JTabbedPane mainTab;
497         private javax.swing.JTextArea textArea;
498         private javax.swing.JPanel textFormat;
499
500         private javax.swing.JButton cancelButton;
501         private javax.swing.JButton okButton;
502         private javax.swing.JButton resetButton;
503         private javax.swing.JPanel buttonPane;
504
505         private XcosDiagram graph;
506         private mxCell cell;
507
508         private final transient ChangeListener defaultChangeListener = new ChangeListener() {
509             /**
510              * Update the text area font
511              *
512              * @param e
513              *            the event parameters
514              * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
515              */
516             @Override
517             public void stateChanged(ChangeEvent e) {
518                 updateFont();
519             }
520         };
521
522         private final transient ActionListener defaultActionListener = new ActionListener() {
523             /**
524              * Update the text area font
525              *
526              * @param e
527              *            the event parameters
528              * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
529              */
530             @Override
531             public void actionPerformed(ActionEvent e) {
532                 updateFont();
533             }
534         };
535
536         /**
537          * Construct the dialog
538          *
539          * @param f
540          *            the current graph frame
541          */
542         public EditFormatDialog(Frame f) {
543             super(f, true);
544             setDefaultCloseOperation(DISPOSE_ON_CLOSE);
545             setLocationRelativeTo(f);
546             ScilabSwingUtilities.closeOnEscape(this);
547
548             initComponents();
549         }
550
551         /**
552          * Initialize the dialog parameters
553          *
554          * @param borderColor
555          *            the default border color
556          * @param backgroundColor
557          *            the default background color
558          * @param fontName
559          *            The default font name
560          * @param fontSize
561          *            the default font size
562          * @param fontStyle
563          *            the current font style
564          * @param textColor
565          *            the current text color
566          * @param text
567          *            the current text
568          * @param image
569          *            the current URL of the image (may be null, absolute or
570          *            relative)
571          */
572         public void setValues(Color borderColor, Color backgroundColor, String fontName, int fontSize, int fontStyle, Color textColor, String text, String image) {
573             borderColorChooser.setColor(borderColor);
574             backgroundColorChooser.setColor(backgroundColor);
575             textColorChooser.setColor(textColor);
576
577             fontNameComboBox.getModel().setSelectedItem(fontName);
578             fontSizeSpinner.getModel().setValue(fontSize);
579
580             fontStyleBold.setSelected((fontStyle & mxConstants.FONT_BOLD) != 0);
581             fontStyleItalic.setSelected((fontStyle & mxConstants.FONT_ITALIC) != 0);
582
583             textArea.setText(text);
584             if (image != null) {
585                 imagePath.setText(image);
586             }
587         }
588
589         /**
590          * @param graph
591          *            the current graph to set
592          */
593         public void setGraph(XcosDiagram graph) {
594             this.graph = graph;
595         }
596
597         /**
598          * @return the current graph
599          */
600         public XcosDiagram getGraph() {
601             return graph;
602         }
603
604         /**
605          * Set the currently selected cell
606          *
607          * @param selectedCell
608          *            the current cell
609          */
610         public void setCell(mxCell selectedCell) {
611             cell = selectedCell;
612
613             // enable/disable the fill color pane
614             if (selectedCell.isVertex()) {
615                 mainTab.addTab(XcosMessages.FILL_COLOR, backgroundPane);
616             } else {
617                 mainTab.remove(backgroundPane);
618             }
619
620             pack();
621         }
622
623         /**
624          * @return the currently selected cell
625          */
626         public mxCell getCell() {
627             return cell;
628         }
629
630         /**
631          * @return the current dialog
632          */
633         public EditFormatDialog getDialog() {
634             return this;
635         }
636
637         /**
638          * Initialize the dialog.
639          *
640          * This code is UI initialization and thus doesn't pass checkstyle
641          * metrics.
642          */
643         // CSOFF: JavaNCSS
644         // CSOFF: LineLength
645         // CSOFF: MethodLength
646         private void initComponents() {
647
648             mainTab = new javax.swing.JTabbedPane();
649             borderColorChooser = new javax.swing.JColorChooser();
650             backgroundColorChooser = new javax.swing.JColorChooser();
651             textColorChooser = new javax.swing.JColorChooser();
652             textFormat = new javax.swing.JPanel();
653             jPanel2 = new javax.swing.JPanel();
654             fontSizeLabel = new javax.swing.JLabel();
655             fontSizeSpinner = new javax.swing.JSpinner();
656             fontNameLabel = new javax.swing.JLabel();
657             fontNameComboBox = new javax.swing.JComboBox();
658             fontStyleBold = new javax.swing.JCheckBox();
659             fontStyleItalic = new javax.swing.JCheckBox();
660             fontStyleLabel = new javax.swing.JLabel();
661             imageFileChooserBtn = new javax.swing.JButton(XcosMessages.DOTS);
662             imagePathLabel = new javax.swing.JLabel();
663             imagePath = new javax.swing.JTextField(TEXT_AREA_COLUMNS);
664             backgroundPane = new javax.swing.JPanel();
665
666             jScrollPane1 = new javax.swing.JScrollPane();
667             textArea = new javax.swing.JTextArea();
668
669             textArea.setColumns(TEXT_AREA_COLUMNS);
670             textArea.setRows(TEXT_AREA_ROWS);
671             textArea.setLineWrap(true);
672             textArea.setWrapStyleWord(true);
673
674             cancelButton = new javax.swing.JButton(XcosMessages.CANCEL);
675             okButton = new javax.swing.JButton(XcosMessages.OK);
676             resetButton = new javax.swing.JButton(XcosMessages.RESET);
677             buttonPane = new javax.swing.JPanel();
678
679             backgroundPane.setLayout(new java.awt.BorderLayout());
680             textFormat.setLayout(new java.awt.BorderLayout());
681
682             fontSizeLabel.setText(XcosMessages.FONT_SIZE);
683
684             fontSizeSpinner.setModel(FONTSIZE_MODEL);
685             fontSizeSpinner.addChangeListener(defaultChangeListener);
686
687             fontNameLabel.setText(XcosMessages.FONT_NAME);
688
689             fontNameComboBox.setModel(new javax.swing.DefaultComboBoxModel(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames()));
690
691             fontNameComboBox.addActionListener(defaultActionListener);
692
693             fontStyleLabel.setText(XcosMessages.FONT_STYLE);
694
695             fontStyleBold.setText(XcosMessages.BOLD);
696             fontStyleBold.addChangeListener(defaultChangeListener);
697
698             fontStyleItalic.setText(XcosMessages.ITALIC);
699             fontStyleItalic.addChangeListener(defaultChangeListener);
700
701             imagePathLabel.setText(XcosMessages.IMAGE_PATH);
702
703             javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
704             jPanel2.setLayout(jPanel2Layout);
705             jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
706                                              .addGroup(
707                                                  javax.swing.GroupLayout.Alignment.TRAILING,
708                                                  jPanel2Layout
709                                                  .createSequentialGroup()
710                                                  .addContainerGap()
711                                                  .addGroup(
712                                                          jPanel2Layout
713                                                          .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
714                                                          .addComponent(fontNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
715                                                                  Short.MAX_VALUE)
716                                                          .addComponent(fontSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE,
717                                                                  Short.MAX_VALUE)
718                                                          .addComponent(fontStyleLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
719                                                                  Short.MAX_VALUE))
720                                                  .addGap(BORDER_SIZE)
721                                                  .addGroup(
722                                                          jPanel2Layout
723                                                          .createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
724                                                          .addComponent(fontNameComboBox, 0, javax.swing.GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
725                                                          .addComponent(fontSizeSpinner, 0, javax.swing.GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
726                                                          .addGroup(
727                                                                  jPanel2Layout.createSequentialGroup().addComponent(fontStyleBold)
728                                                                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
729                                                                  .addComponent(fontStyleItalic))).addContainerGap()));
730             jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
731                                                jPanel2Layout
732                                                .createSequentialGroup()
733                                                .addGroup(
734                                                    jPanel2Layout
735                                                    .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
736                                                    .addComponent(fontSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE,
737                                                            javax.swing.GroupLayout.PREFERRED_SIZE)
738                                                    .addComponent(fontSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
739                                                            javax.swing.GroupLayout.PREFERRED_SIZE))
740                                                .addGap(BORDER_SIZE)
741                                                .addGroup(
742                                                    jPanel2Layout
743                                                    .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
744                                                    .addComponent(fontNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE,
745                                                            javax.swing.GroupLayout.PREFERRED_SIZE)
746                                                    .addComponent(fontNameComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
747                                                            javax.swing.GroupLayout.PREFERRED_SIZE))
748                                                .addGap(BORDER_SIZE)
749                                                .addGroup(
750                                                    jPanel2Layout
751                                                    .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
752                                                    .addComponent(fontStyleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE,
753                                                            javax.swing.GroupLayout.PREFERRED_SIZE)
754                                                    .addComponent(fontStyleBold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
755                                                            javax.swing.GroupLayout.PREFERRED_SIZE)
756                                                    .addComponent(fontStyleItalic, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
757                                                            javax.swing.GroupLayout.PREFERRED_SIZE))
758                                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
759
760             textFormat.add(jPanel2, java.awt.BorderLayout.PAGE_END);
761
762             jScrollPane1.setViewportView(textArea);
763             jScrollPane1.setBackground(Color.WHITE);
764
765             textFormat.add(jScrollPane1, java.awt.BorderLayout.CENTER);
766
767             backgroundPane.add(backgroundColorChooser, java.awt.BorderLayout.CENTER);
768             javax.swing.JPanel filePane = new javax.swing.JPanel();
769             filePane.setBorder(BorderFactory.createEtchedBorder());
770             filePane.add(imagePathLabel);
771             filePane.add(imagePath);
772             filePane.add(imageFileChooserBtn);
773             backgroundPane.add(filePane, java.awt.BorderLayout.SOUTH);
774
775             mainTab.addTab(XcosMessages.TEXT_SETTINGS, textFormat);
776             mainTab.addTab(XcosMessages.BORDER_COLOR, borderColorChooser);
777             mainTab.addTab(XcosMessages.TEXT_COLOR, textColorChooser);
778             // backgroundColorChooser is added on the setCell method only if the
779             // cell is a vertex
780             // mainTab.addTab(XcosMessages.FILL_COLOR, backgroundColorChooser);
781
782             mainTab.addChangeListener(defaultChangeListener);
783
784             cancelButton.addActionListener(new ActionListener() {
785                 /**
786                  * On cancel close the window
787                  *
788                  * @param e
789                  *            the current event parameter
790                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
791                  */
792                 @Override
793                 public void actionPerformed(ActionEvent e) {
794                     getDialog().dispose();
795                 }
796             });
797
798             okButton.addActionListener(new ActionListener() {
799                 /**
800                  * On OK, set the current parameter on the cell
801                  *
802                  * @param e
803                  *            the current parameters
804                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
805                  */
806                 @Override
807                 public void actionPerformed(ActionEvent e) {
808                     graph.getModel().beginUpdate();
809                     EditFormatAction.updateFromDialog(getDialog(), borderColorChooser.getColor(), backgroundColorChooser.getColor(),
810                                                       (String) fontNameComboBox.getSelectedItem(), (Integer) fontSizeSpinner.getValue(), textColorChooser.getColor(),
811                                                       fontStyleBold.isSelected(), fontStyleItalic.isSelected(), textArea.getText(), imagePath.getText());
812                     graph.getModel().endUpdate();
813                     getDialog().dispose();
814                 }
815             });
816
817             resetButton.addActionListener(new ActionListener() {
818
819                 @Override
820                 public void actionPerformed(ActionEvent e) {
821                     graph.getModel().beginUpdate();
822                     EditFormatAction.reset(getDialog());
823                     graph.getModel().endUpdate();
824                 }
825             });
826
827             imageFileChooserBtn.addActionListener(new ActionListener() {
828                 /**
829                  * On file chooser open the file chooser with image filter.
830                  *
831                  * @param e
832                  *            the event
833                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
834                  */
835                 @Override
836                 public void actionPerformed(ActionEvent e) {
837                     javax.swing.JFileChooser chooser = new javax.swing.JFileChooser();
838                     javax.swing.filechooser.FileNameExtensionFilter filter = new javax.swing.filechooser.FileNameExtensionFilter("Images", "jpg", "png", "svg",
839                             "gif");
840                     chooser.setFileFilter(filter);
841
842                     final String current = imagePath.getText();
843                     final File savedFile = getGraph().getSavedFile();
844                     if (current != null && !current.isEmpty()) {
845                         try {
846                             // try to handle an absolute URL
847                             final URI uri = new URI(current);
848                             chooser.setSelectedFile(new File(uri));
849                         } catch (URISyntaxException e1) {
850                             // this is a relative path
851                             if (savedFile != null) {
852                                 final File parent = savedFile.getParentFile();
853                                 chooser.setSelectedFile(new File(parent, current));
854                             }
855                         }
856                     } else {
857                         if (savedFile != null) {
858                             chooser.setCurrentDirectory(savedFile.getParentFile());
859                         }
860                     }
861
862                     int returnVal = chooser.showOpenDialog(mainTab);
863                     if (returnVal == javax.swing.JFileChooser.APPROVE_OPTION) {
864                         if (savedFile != null) {
865                             final String relativeChild = savedFile.getParentFile().toURI().relativize(chooser.getSelectedFile().toURI()).toASCIIString();
866                             imagePath.setText(relativeChild);
867                         } else {
868                             final String uri = chooser.getSelectedFile().toURI().toASCIIString();
869                             imagePath.setText(uri);
870                         }
871                     }
872                 }
873             });
874
875             getRootPane().setDefaultButton(okButton);
876
877             buttonPane.setLayout(new javax.swing.BoxLayout(buttonPane, javax.swing.BoxLayout.LINE_AXIS));
878             buttonPane.setBorder(javax.swing.BorderFactory.createEmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
879             buttonPane.add(javax.swing.Box.createHorizontalGlue());
880             buttonPane.add(okButton);
881             buttonPane.add(javax.swing.Box.createRigidArea(new Dimension(BORDER_SIZE, 0)));
882             buttonPane.add(cancelButton);
883             buttonPane.add(javax.swing.Box.createRigidArea(new Dimension(BORDER_SIZE, 0)));
884             buttonPane.add(javax.swing.Box.createRigidArea(new Dimension(BORDER_SIZE, 0)));
885             buttonPane.add(resetButton);
886
887             java.awt.Container contentPane = getContentPane();
888             contentPane.add(mainTab, java.awt.BorderLayout.CENTER);
889             contentPane.add(buttonPane, java.awt.BorderLayout.PAGE_END);
890         }
891
892         // CSON: JavaNCSS
893         // CSON: LineLength
894         // CSON: MethodLength
895
896         /**
897          * Update the text area from the font
898          */
899         protected void updateFont() {
900             int style = 0;
901             if (fontStyleBold.isSelected()) {
902                 style |= Font.BOLD;
903             }
904             if (fontStyleItalic.isSelected()) {
905                 style |= Font.ITALIC;
906             }
907
908             Font f = new Font((String) fontNameComboBox.getSelectedItem(), style, (Integer) fontSizeSpinner.getValue());
909             textArea.setFont(f);
910             textArea.setBackground(backgroundColorChooser.getColor());
911             textArea.setForeground(textColorChooser.getColor());
912
913             // Repaint the parent scroll pane to force a full redraw call.
914             jScrollPane1.repaint();
915         }
916     }
917     // CSON: ClassDataAbstractionCoupling
918     // CSON: ClassFanOutComplexity
919 }