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