1   /**
2    * QJ-Pro
3    * Copyright (c) 2004, http://qjpro.sourceforge.net
4    *
5    * This program is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License as published by the
7    * Free Software Foundation; either version 2 of the License, or
8    * (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful, but WITHOUT
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13   * details.
14   *
15   * You should have received a copy of the GNU General Public License along with
16   * this program; if not, write to the Free Software Foundation, Inc.,
17   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18   */
19  package com.qasystems.qstudio.java.gui.dialog;
20  
21  import com.qasystems.debug.DebugWriter;
22  import com.qasystems.international.MessageResource;
23  import com.qasystems.qstudio.java.gui.*;
24  import com.qasystems.swing.ButtonDialog;
25  import com.qasystems.swing.ScrollablePanel;
26  import com.qasystems.swing.layout.Anchor;
27  import com.qasystems.swing.layout.EGridConstraints;
28  import com.qasystems.swing.layout.EGridLayout;
29  import com.qasystems.swing.layout.Fill;
30  import com.qasystems.util.Utilities;
31  
32  import java.awt.BorderLayout;
33  import java.awt.Color;
34  import java.awt.Container;
35  import java.awt.Dialog;
36  import java.awt.Dimension;
37  import java.awt.Frame;
38  import java.awt.event.ActionEvent;
39  import java.awt.event.ActionListener;
40  import java.util.ArrayList;
41  import java.util.Arrays;
42  import java.util.Enumeration;
43  
44  import javax.swing.BorderFactory;
45  import javax.swing.BoxLayout;
46  import javax.swing.ButtonGroup;
47  import javax.swing.JComboBox;
48  import javax.swing.JLabel;
49  import javax.swing.JPanel;
50  import javax.swing.JRadioButton;
51  import javax.swing.JScrollPane;
52  import javax.swing.border.Border;
53  import javax.swing.border.TitledBorder;
54  
55  /**
56   * Edit the parameters of a RuleConfiguration.
57   */
58  public class ParameterDialog extends ButtonDialog {
59    /**
60     * Defines the relation between the Gui components
61     * (JComboBox and ButtonGroup) and the ConfigurationParameter.
62     * - for a ButtonGroup the corresponding parameter option is
63     *   kept in member "choice".
64     * - for a JComboBox the parameter option == the selected item.
65     *
66     * @author Arie Roy
67     * @version %full_filespec: ParameterDialog.java,1:java:1 %
68     */
69    private class EditParameterInfo {
70      private String choice = null;
71      private Object component = null;
72      private ConfigurationParameter parameter = null;
73  
74      /**
75       * default constructor
76       * @param aChoice the option (not needed in contect JComboBox)
77       * @param aComponent the buttongroup representing the choice OR
78       *                   the JComboBox holding the options.
79       * @param aParameter the parameter to which the option belongs
80       */
81      private EditParameterInfo(
82        String aChoice, Object aComponent, ConfigurationParameter aParameter
83      ) {
84        choice = aChoice;
85        component = aComponent;
86        parameter = aParameter;
87      }
88  
89      /**
90       * return the parameter
91       * @return the parameter
92       */
93      public ConfigurationParameter getParameter() {
94        return (parameter);
95      }
96  
97      /**
98       * return the component
99       * @return the component
100      */
101     public Object getComponent() {
102       return (component);
103     }
104 
105     /**
106      * return the choice
107      * @return the choice
108      */
109     public String getChoice() {
110       return choice;
111     }
112   }
113 
114   /** representation of Ok button */
115   public final static int OK = 0;
116 
117   /** representaton of Cancel button */
118   public final static int CANCEL = 1;
119   private static final MessageResource RESOURCES =
120     MessageResource.getClientInstance();
121   private final static int TWAALF = 12;
122   private final static int ELF = 11;
123   private final static int FACTOR = 3;
124   private final static int INCREMENT = 34;
125   private JPanel panel = new JPanel();
126   private SimplifiedRuleCheckBox simplified = null;
127   private RuleConfiguration configuration = null;
128   private ActionListener listener = null;
129   private ActionListener dropDownListener = null;
130   private ArrayList BUTTONGROUP_MAPPINGS = null;
131   private ArrayList DROPDOWN_MAPPINGS = null;
132   private EGridLayout egrid = new EGridLayout();
133   private EGridConstraints ec = new EGridConstraints();
134 
135   /**
136    * Default constructor.
137    *
138    * @param ruleCheckBox the rulecheckbox
139    * @param frame the frame to center the dialog with
140    */
141   public ParameterDialog(RuleCheckBox ruleCheckBox, Frame frame) {
142     super(frame);
143     init(ruleCheckBox, frame);
144   }
145 
146   /**
147    * Default constructor.
148    *
149    * @param ruleCheckBox the rulecheckbox
150    * @param dialog the dialog to center the dialog with
151    */
152   public ParameterDialog(RuleCheckBox ruleCheckBox, Dialog dialog) {
153     super(dialog);
154     init(ruleCheckBox, dialog);
155   }
156 
157   /**
158    * Cloning not allowed
159    *
160    * @return CloneNotSupportedException.
161    * @throws CloneNotSupportedException
162    */
163   public Object clone() throws CloneNotSupportedException {
164     throw new CloneNotSupportedException();
165   }
166 
167   /**
168    * Representation of this instance.
169    * @return representation
170    */
171   public String toString() {
172     return super.toString();
173   }
174 
175   /**
176    * Check for equality.
177    *
178    * @param obj the object to compare this object to
179    * @return <tt>true</tt> if this object equals obj
180    */
181   public boolean equals(Object obj) {
182     return (super.equals(obj));
183   }
184 
185   /**
186    * Return the settings made by the user
187    * - these setting were cloned when the dialog was created.
188    *
189    * @return array of ConfigurationParameter describing the settings.
190    */
191   public ConfigurationParameter[] getSelection() {
192     return configuration.getParams();
193   }
194 
195   /**
196    * final cleanup of the "configuration" reference
197    */
198   public synchronized void finalCleanup() {
199     configuration = null;
200   }
201 
202   /**
203    * - override superclass reaction to WindowClose event
204    */
205   protected void cancelDialog() {
206     cleanup();
207     super.cancelDialog();
208   }
209 
210   /**
211    * - override superclass button activation
212    * @param action describes the button chosen in the dialog
213    */
214   protected void onActionPerformed(int action) {
215     boolean closeDialog = true;
216 
217     if (action == OK) {
218       // check regular expressions
219       RegExpr regexpr = new RegExpr();
220       regexpr.setExtendedErrorMessage(true);
221 
222       try {
223         regexpr.checkRegularExpressionsRuleParams(configuration);
224       } catch (Exception ex) {
225         closeDialog = false;
226 
227         // Show dialog
228         final String pattern = RESOURCES.getString("MESSAGE_094");
229         final String[] options = { RESOURCES.getString("BUTTON_001") };
230         QStudioOptionPane.showOptionDialog(
231           this,
232           RESOURCES.format(
233             pattern,
234             new Object[] {
235               new Integer(
236                 configuration.getRule().getRuleIdentifier().getRuleId()
237               ), ex.getMessage()
238             }
239           ), RESOURCES.getString("WINDOWTITLE_003"),
240           QStudioOptionPane.DEFAULT_OPTION, QStudioOptionPane.ERROR_MESSAGE,
241           null, options, options[0]
242         );
243       }
244     }
245 
246     if (closeDialog) {
247       cleanup();
248       super.onActionPerformed(action);
249     }
250   }
251 
252   private synchronized void init(
253     RuleCheckBox ruleCheckBox, Container container
254   ) {
255     final RuleConfiguration copyConfig = ruleCheckBox.getRuleConfiguration();
256     ec.setAnchor(Anchor.WEST);
257     ec.setFill(Fill.HORIZONTAL);
258 
259     // clone the configuration to avoid interference
260     try {
261       configuration = (RuleConfiguration) copyConfig.clone();
262       simplified = new SimplifiedRuleCheckBox(configuration, container);
263     } catch (CloneNotSupportedException ex) {
264       new DebugWriter().writeException(ex, this);
265     }
266 
267     try {
268       jbInit(configuration);
269     } catch (Exception e) {
270       e.printStackTrace();
271     }
272 
273     pack();
274   }
275 
276   /**
277    * Do NOT remove the "configuration" member
278    * since it is queried after closing the dialog !
279    */
280   private synchronized void cleanup() {
281     if (panel != null) {
282       panel.removeAll();
283       panel = null;
284     }
285 
286     egrid = null;
287     ec = null;
288 
289     listener = null;
290     dropDownListener = null;
291 
292     if (simplified != null) {
293       simplified.cleanup();
294       simplified = null;
295     }
296 
297     cleanupArrays();
298   }
299 
300   private synchronized void cleanupArrays() {
301     if (BUTTONGROUP_MAPPINGS != null) {
302       BUTTONGROUP_MAPPINGS.clear();
303       BUTTONGROUP_MAPPINGS = null;
304     }
305 
306     if (DROPDOWN_MAPPINGS != null) {
307       DROPDOWN_MAPPINGS.clear();
308       DROPDOWN_MAPPINGS = null;
309     }
310   }
311 
312   private synchronized void jbInit(RuleConfiguration configuration) {
313     final ConfigurationParameter[] parameters = configuration.getParams();
314 
315     initDialog();
316     BUTTONGROUP_MAPPINGS = new ArrayList();
317     DROPDOWN_MAPPINGS = new ArrayList();
318     panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
319 
320     final JScrollPane composeConfiguration = createConfigurationView();
321     Utilities.discardResult(panel.add(composeConfiguration));
322 
323     /**
324      * Bottom panel only needed for Rule having one or more
325      * parameters of type Placeholder :
326      * - TYPE
327      * - OTHERMODIFIER
328      * - SCOPEMODIFIER
329      * - CLASSBODY_DECLARATION_TYPE
330      */
331     if (configuration.getRule().containsListConfiguration()) {
332       final JScrollPane editConfiguration = editConfigurationView(parameters);
333       Utilities.discardResult(panel.add(editConfiguration));
334     }
335 
336     this.setContent(panel);
337   }
338 
339   private synchronized void initDialog() {
340     final String[] BUTTONS =
341     { RESOURCES.getString("BUTTON_005"), RESOURCES.getString("BUTTON_001") };
342     final String pattern = RESOURCES.getString("WINDOWTITLE_027");
343 
344     setModal(true);
345     setResizable(true);
346     setTitle(
347       RESOURCES.format(pattern, new Object[] { simplified.getRuleLabel() })
348     );
349     setButtons(BUTTONS);
350     setInitialButton(OK);
351   }
352 
353   private Dimension adjustViewportSize(Dimension ruleSize, int maxHeight) {
354     final int MAX_WIDTH = 600;
355     final int deltaX = 24;
356     final int deltaY = 24;
357 
358     final int ruleWidth = new Double(ruleSize.getWidth()).intValue();
359     final int ruleHeight = new Double(ruleSize.getHeight()).intValue();
360     final int width =
361       ((Math.abs(ruleWidth) < MAX_WIDTH) ? (ruleWidth + deltaX) : MAX_WIDTH);
362     final int height =
363       ((Math.abs(ruleHeight) < maxHeight) ? (ruleHeight + deltaY) : maxHeight);
364 
365     return (new Dimension(width, height));
366   }
367 
368   /*
369    * Create interaction components for placeholdertypes
370    */
371   private JPanel createPanel(ConfigurationParameter parameter) {
372     JPanel myPanel = new JPanel();
373 
374     if (!parameter.isSingleValue()) {
375       Utilities.discardResult(myPanel.add(createOtherModifiers(parameter)));
376     } else {
377       final JPanel guiPanel = createGui(parameter);
378 
379       if (guiPanel != null) {
380         Utilities.discardResult(myPanel.add(guiPanel));
381       } else {
382         myPanel = null;
383       }
384     }
385 
386     return myPanel;
387   }
388 
389   private JPanel createOtherModifiers(ConfigurationParameter parameter) {
390     return (createRadioButtons(parameter));
391   }
392 
393   private JPanel createGui(ConfigurationParameter parameter) {
394     JPanel result = null;
395 
396     final Placeholder placeholder = parameter.getPlaceholder();
397     final String[] choices = placeholder.getItems();
398 
399     if ((choices != null) && placeholder.isChoicePlaceholder()) {
400       final int limit =
401         (parameter.isNegatable()) ? (2 * choices.length) : choices.length;
402 
403       if ((limit <= 4) && !placeholder.isEditable()) {
404         result = createButtonGroup(choices, parameter);
405       } else {
406         result = createDropDown(choices, parameter);
407       }
408     }
409 
410     return (result);
411   }
412 
413   private JPanel createButtonGroup(
414     String[] choices, ConfigurationParameter parameter
415   ) {
416     final JPanel myPanel = new JPanel();
417 
418     final ArrayList options = new ArrayList();
419     options.addAll(Arrays.asList(choices));
420     options.add(0, Placeholder.NONE_OPTION);
421 
422     final ButtonGroup buttonGroup = new ButtonGroup();
423     Utilities.discardBooleanResult(
424       BUTTONGROUP_MAPPINGS.add(
425         new EditParameterInfo("", buttonGroup, parameter)
426       )
427     );
428 
429     for (int i = 0; i < options.size(); i++) {
430       final String buttonLabel = (String) options.get(i);
431 
432       defineRadioButton(buttonLabel, parameter, myPanel, buttonGroup);
433 
434       if (parameter.isNegatable()) {
435         if (!Placeholder.NONE_OPTION.equals(buttonLabel)) {
436           defineRadioButton(
437             notMandatory(buttonLabel), parameter, myPanel, buttonGroup
438           );
439         }
440       }
441     }
442 
443     return (myPanel);
444   }
445 
446   private synchronized void defineRadioButton(
447     String buttonLabel, ConfigurationParameter parameter, JPanel myPanel,
448     ButtonGroup buttonGroup
449   ) {
450     final JRadioButton button = createRadioButton(buttonLabel, parameter);
451     Utilities.discardResult(myPanel.add(button));
452     buttonGroup.add(button);
453   }
454 
455   private synchronized JRadioButton createRadioButton(
456     String buttonLabel, ConfigurationParameter parameter
457   ) {
458     final JRadioButton button = new JRadioButton(buttonLabel);
459 
460     if (Placeholder.NONE_OPTION.equals(buttonLabel)) {
461       // when selecting "none" clear the entryfield
462       button.setActionCommand(Placeholder.OPTIONAL);
463     } else {
464       button.setActionCommand(buttonLabel);
465     }
466 
467     button.addActionListener(getActionListener());
468     button.setSelected(isSelected(buttonLabel, parameter));
469 
470     return (button);
471   }
472 
473   private JPanel createDropDown(
474     String[] choices, ConfigurationParameter parameter
475   ) {
476     final JPanel myPanel = new JPanel();
477     myPanel.setLayout(new BorderLayout());
478 
479     final JComboBox comboBox = createComboBox(parameter, choices);
480 
481     Utilities.discardBooleanResult(
482       DROPDOWN_MAPPINGS.add(
483         new EditParameterInfo(Placeholder.NONE_OPTION, comboBox, parameter)
484       )
485     );
486     myPanel.add(comboBox, BorderLayout.WEST);
487 
488     return (myPanel);
489   }
490 
491   private synchronized JComboBox createComboBox(
492     ConfigurationParameter parameter, String[] choices
493   ) {
494     final JComboBox comboBox = createDropDownOptions(choices, parameter);
495     final int visibleOptions =
496       (comboBox.getItemCount() < 15) ? comboBox.getItemCount() : 15;
497     comboBox.setMaximumRowCount(visibleOptions);
498     comboBox.addActionListener(getDropDownActionListener());
499 
500     final String selection = (String) parameter.getValue();
501 
502     if (selection == null) {
503       comboBox.setSelectedIndex(0);
504     } else {
505       comboBox.setSelectedItem(fromConfigurationToGui(parameter, selection));
506     }
507 
508     comboBox.setEditable(parameter.getPlaceholder().isEditable());
509 
510     return (comboBox);
511   }
512 
513   private synchronized JComboBox createDropDownOptions(
514     String[] choices, ConfigurationParameter parameter
515   ) {
516     final ArrayList options = new ArrayList();
517     options.addAll(Arrays.asList(choices));
518 
519 
520     final ArrayList result = new ArrayList();
521 
522     for (int i = 0; i < options.size(); i++) {
523       final String value = (String) options.get(i);
524       Utilities.discardBooleanResult(result.add(value));
525 
526       if (parameter.isNegatable()) {
527         Utilities.discardBooleanResult(
528           result.add(parameter.getNegation(value))
529         );
530       }
531     }
532 
533     if (!parameter.isMandatory()) {
534       result.add(0, Placeholder.NONE_OPTION);
535     }
536 
537     return (new JComboBox(result.toArray()));
538   }
539 
540   private synchronized ActionListener getDropDownActionListener() {
541     if (dropDownListener == null) {
542       dropDownListener =
543         new ActionListener() {
544             public void actionPerformed(ActionEvent event) {
545               updateDropDownSelections();
546             }
547           };
548     }
549 
550     return (dropDownListener);
551   }
552 
553   private JPanel createRadioButtons(ConfigurationParameter parameter) {
554     final JPanel myPanel = new JPanel();
555     final EGridLayout egridLayout = new EGridLayout();
556     myPanel.setLayout(egridLayout);
557     final EGridConstraints eConstraints = new EGridConstraints();
558     eConstraints.setAnchor(Anchor.WEST);
559     eConstraints.setFill(Fill.HORIZONTAL);
560     final ButtonGroup[] groups = createButtonGroups(parameter);
561 
562     createLabelColumn(myPanel, parameter, egridLayout, eConstraints, groups);
563     createMandatoryColumn(
564       myPanel, parameter, egridLayout, eConstraints, groups
565     );
566     createExcludeColumn(myPanel, parameter, egridLayout, eConstraints, groups);
567     createOptionalColumn(myPanel, parameter, eConstraints, groups);
568 
569     return (myPanel);
570   }
571 
572   private synchronized ButtonGroup[] createButtonGroups(
573     ConfigurationParameter parameter
574   ) {
575     final int numberChoices = parameter.getPlaceholder().getItems().length;
576     final ButtonGroup[] groups = new ButtonGroup[numberChoices];
577 
578     for (int i = 0; i < numberChoices; i++) {
579       groups[i] = new ButtonGroup();
580     }
581 
582     return (groups);
583   }
584 
585   private synchronized void createLabelColumn(
586     JPanel myPanel, ConfigurationParameter parameter, EGridLayout egridLayout,
587     EGridConstraints eConstraints, ButtonGroup[] groups
588   ) {
589     final int SPACE = 25;
590     final String[] choices = parameter.getPlaceholder().getItems();
591 
592     // Fill first column with OTHER modifier labels
593     myPanel.add(new JLabel(), eConstraints);
594 
595     for (int i = 0; i < choices.length; i++) {
596       final JLabel label = new JLabel(choices[i]);
597       Utilities.discardBooleanResult(
598         BUTTONGROUP_MAPPINGS.add(
599           new EditParameterInfo(choices[i], groups[i], parameter)
600         )
601       );
602 
603       myPanel.add(label, eConstraints);
604     }
605 
606     egridLayout.nextColumn(eConstraints);
607     createEmptyColumn(SPACE, egridLayout, eConstraints);
608   }
609 
610   private synchronized void createMandatoryColumn(
611     JPanel myPanel, ConfigurationParameter parameter, EGridLayout egridLayout,
612     EGridConstraints eConstraints, ButtonGroup[] groups
613   ) {
614     final int SPACE = 10;
615     final String[] choices = parameter.getPlaceholder().getItems();
616     createColumnHeader(RESOURCES.getString("LABEL_027"), myPanel, eConstraints);
617     final int numberChoices = choices.length;
618 
619     for (int i = 0; i < numberChoices; i++) {
620       final JRadioButton buttonPlus = new JRadioButton();
621       buttonPlus.addActionListener(getActionListener());
622       buttonPlus.setActionCommand(mandatory(choices[i]));
623       final boolean isMandatory = isSelected(mandatory(choices[i]), parameter);
624       buttonPlus.setSelected(isMandatory);
625       groups[i].add(buttonPlus);
626       myPanel.add(buttonPlus, eConstraints);
627     }
628 
629     egridLayout.nextColumn(eConstraints);
630     createEmptyColumn(SPACE, egridLayout, eConstraints);
631   }
632 
633   private synchronized void createExcludeColumn(
634     JPanel myPanel, ConfigurationParameter parameter, EGridLayout egridLayout,
635     EGridConstraints eConstraints, ButtonGroup[] groups
636   ) {
637     final int SPACE = 10;
638     final String[] choices = parameter.getPlaceholder().getItems();
639     createColumnHeader(RESOURCES.getString("LABEL_028"), myPanel, eConstraints);
640     final int numberChoices = choices.length;
641 
642     for (int i = 0; i < numberChoices; i++) {
643       final JRadioButton buttonMin = new JRadioButton();
644       buttonMin.addActionListener(getActionListener());
645       buttonMin.setActionCommand(notMandatory(choices[i]));
646       final boolean isNotMandatory =
647         isSelected(notMandatory(choices[i]), parameter);
648       buttonMin.setSelected(isNotMandatory);
649       groups[i].add(buttonMin);
650       myPanel.add(buttonMin, eConstraints);
651     }
652 
653     egridLayout.nextColumn(eConstraints);
654     createEmptyColumn(SPACE, egridLayout, eConstraints);
655   }
656 
657   private synchronized void createOptionalColumn(
658     JPanel myPanel, ConfigurationParameter parameter,
659     EGridConstraints eConstraints, ButtonGroup[] groups
660   ) {
661     final String[] choices = parameter.getPlaceholder().getItems();
662     createColumnHeader(RESOURCES.getString("LABEL_029"), myPanel, eConstraints);
663     final int numberChoices = choices.length;
664 
665     for (int i = 0; i < numberChoices; i++) {
666       final JRadioButton buttonSter = new JRadioButton();
667       buttonSter.addActionListener(getActionListener());
668       buttonSter.setActionCommand(optional());
669 
670       final boolean isMandatory = isSelected(mandatory(choices[i]), parameter);
671       final boolean isNotMandatory =
672         isSelected(notMandatory(choices[i]), parameter);
673       buttonSter.setSelected(!isMandatory && !isNotMandatory);
674       groups[i].add(buttonSter);
675       myPanel.add(buttonSter, eConstraints);
676     }
677   }
678 
679   private void createEmptyColumn(
680     int space, EGridLayout egrid, EGridConstraints ec
681   ) {
682     egrid.setColumnWidth(ec.getColumn(), space);
683     egrid.nextColumn(ec);
684   }
685 
686   private void createColumnHeader(
687     String header, JPanel panel, EGridConstraints ec
688   ) {
689     ec.setAnchor(Anchor.WEST);
690     final JLabel label = new JLabel(header);
691     panel.add(label, ec);
692     ec.setAnchor(Anchor.CENTER);
693   }
694 
695   private boolean isSelected(String label, ConfigurationParameter parameter) {
696     boolean selected = false;
697 
698     // now set the appropriate buttons
699     if (parameter.isSingleValue()) {
700       final Object value = parameter.getValue();
701 
702       String setting = null;
703 
704       if (value != null) {
705         setting = value.toString();
706       }
707 
708       selected = matchLabel(label, setting);
709     } else {
710       final Object[] settings = parameter.getSettings();
711 
712       for (int i = 0; (i < settings.length) && !selected; i++) {
713         final String setting = settings[i].toString();
714         selected = matchLabel(label, setting);
715       }
716     }
717 
718     return selected;
719   }
720 
721   private synchronized boolean matchLabel(String label, String setting) {
722     boolean selected = false;
723 
724     if (label.equals(setting)) {
725       selected = true;
726     } else {
727       // special case for the NONE_OPTION
728       if (
729         Placeholder.NONE_OPTION.equals(label) &&
730           ("".equals(setting) || (setting == null))
731       ) {
732         selected = true;
733       }
734     }
735 
736     return (selected);
737   }
738 
739   private String mandatory(String option) {
740     return Placeholder.MANDATORY + option;
741   }
742 
743   private String notMandatory(String option) {
744     return Placeholder.NOT_MANDATORY + option;
745   }
746 
747   private String optional() {
748     return Placeholder.OPTIONAL;
749   }
750 
751   private synchronized ActionListener getActionListener() {
752     if (listener == null) {
753       listener =
754         new ActionListener() {
755             public void actionPerformed(ActionEvent event) {
756               updateView();
757             }
758           };
759     }
760 
761     return listener;
762   }
763 
764   private void resetParameters() {
765     for (int i = 0; i < BUTTONGROUP_MAPPINGS.size(); i++) {
766       final EditParameterInfo view =
767         (EditParameterInfo) BUTTONGROUP_MAPPINGS.get(i);
768 
769       if (view != null) {
770         final ConfigurationParameter parameter = view.getParameter();
771 
772         parameter.clear();
773       }
774     }
775   }
776 
777   private void updateDropDownSelections() {
778     for (int i = 0; i < DROPDOWN_MAPPINGS.size(); i++) {
779       final EditParameterInfo view =
780         (EditParameterInfo) DROPDOWN_MAPPINGS.get(i);
781 
782       if (view != null) {
783         final JComboBox comboBox = (JComboBox) view.getComponent();
784         final ConfigurationParameter parameter = view.getParameter();
785 
786         final String selection = (String) comboBox.getSelectedItem();
787         parameter.getPlaceholder().addItem(selection);
788         updateParameter(parameter, selection);
789       }
790     }
791 
792     configuration.signalChange();
793   }
794 
795   private synchronized void updateParameter(
796     ConfigurationParameter parameter, String selection
797   ) {
798     parameter.clear();
799 
800     if (!Placeholder.NONE_OPTION.equals(selection)) {
801       parameter.addSetting(fromGuiToConfiguration(parameter, selection));
802     }
803   }
804 
805   private synchronized String fromGuiToConfiguration(
806     ConfigurationParameter parameter, String selection
807   ) {
808     String result = selection;
809 
810     if (parameter.isNegatable()) {
811       if (selection.startsWith(ConfigurationParameter.NONE_PREFIX)) {
812         result =
813           Placeholder.NOT_MANDATORY +
814           selection.substring(ConfigurationParameter.NONE_PREFIX.length());
815       }
816     }
817 
818     return (result);
819   }
820 
821   private synchronized String fromConfigurationToGui(
822     ConfigurationParameter parameter, String selection
823   ) {
824     String result = selection;
825 
826     if (parameter.isNegatable()) {
827       if (selection.startsWith(Placeholder.NOT_MANDATORY)) {
828         result =
829           ConfigurationParameter.NONE_PREFIX +
830           selection.substring(Placeholder.NOT_MANDATORY.length());
831       }
832     }
833 
834     return (result);
835   }
836 
837   private void updateView() {
838     resetParameters();
839 
840     for (int i = 0; i < BUTTONGROUP_MAPPINGS.size(); i++) {
841       final EditParameterInfo view =
842         (EditParameterInfo) BUTTONGROUP_MAPPINGS.get(i);
843 
844       if (view != null) {
845         final ButtonGroup group = (ButtonGroup) view.getComponent();
846         final ConfigurationParameter parameter = view.getParameter();
847 
848         updateButtonGroupParameter(group, parameter);
849       }
850     }
851 
852     configuration.signalChange();
853   }
854 
855   private synchronized void updateButtonGroupParameter(
856     ButtonGroup group, ConfigurationParameter parameter
857   ) {
858     final Enumeration enum = group.getElements();
859 
860     boolean found = false;
861 
862     while (enum.hasMoreElements() && !found) {
863       final JRadioButton button = (JRadioButton) enum.nextElement();
864 
865       if (button.isSelected()) {
866         found = true;
867         final String choice = button.getActionCommand();
868 
869         if (!Placeholder.OPTIONAL.equals(choice)) {
870           parameter.addSetting(fromGuiToConfiguration(parameter, choice));
871         }
872       }
873     }
874   }
875 
876   private synchronized JScrollPane createConfigurationView() {
877     final int MAX_HEIGHT_TOP = 250;
878     final ScrollablePanel configurationPanel = createConfigurationPanel();
879 
880     final JScrollPane composeConfiguration =
881       new JScrollPane(configurationPanel);
882     final Dimension sizeRule = simplified.getPreferredSize();
883     configurationPanel.setPreferredScrollableViewportSize(
884       adjustViewportSize(sizeRule, MAX_HEIGHT_TOP)
885     );
886     configurationPanel.revalidate();
887 
888     return (composeConfiguration);
889   }
890 
891   private synchronized ScrollablePanel createConfigurationPanel() {
892     final ScrollablePanel configurationPanel = new ScrollablePanel();
893     configurationPanel.setBorder(
894       BorderFactory.createEmptyBorder(TWAALF, TWAALF, ELF, ELF)
895     );
896     configurationPanel.setScrollableUnitIncrement(INCREMENT);
897     configurationPanel.setScrollableBlockIncrement(FACTOR * INCREMENT);
898 
899     final EGridLayout egridSimplified = new EGridLayout();
900     configurationPanel.setLayout(egridSimplified);
901     final EGridConstraints ecSimplified = new EGridConstraints();
902     ecSimplified.setAnchor(Anchor.WEST);
903     ecSimplified.setFill(Fill.VERTICAL);
904     configurationPanel.add(simplified, ecSimplified);
905 
906     return (configurationPanel);
907   }
908 
909   private synchronized JScrollPane editConfigurationView(
910     ConfigurationParameter[] parameters
911   ) {
912     final JPanel parametersPanel = new JPanel();
913     int preferredWidth = 400;
914 
915     parametersPanel.setLayout(egrid);
916 
917     //Introduced dummy panel to get the layout correct.
918     final JPanel dummy = new JPanel();
919     dummy.setPreferredSize(new Dimension(preferredWidth, 10));
920     parametersPanel.add(dummy, ec);
921 
922     for (int i = 0; i < parameters.length; i++) {
923       final JPanel parameterPanel = createPanel(parameters[i]);
924 
925       if (parameterPanel != null) {
926         createBorder(parameterPanel, parameters[i], i);
927 
928         final Dimension preferredSize =
929           egrid.preferredLayoutSize(parameterPanel);
930         preferredWidth =
931           Math.max(
932             preferredWidth, new Double(preferredSize.getWidth()).intValue()
933           );
934         parametersPanel.add(parameterPanel, ec);
935       }
936     }
937 
938     final ScrollablePanel bottomPanel =
939       createBottomPanel(parametersPanel, preferredWidth);
940     final JScrollPane bottomPane = new JScrollPane(bottomPanel);
941 
942     return (bottomPane);
943   }
944 
945   private synchronized ScrollablePanel createBottomPanel(
946     JPanel parameterPanel, int preferredWidth
947   ) {
948     final int MAX_HEIGHT_BOTTOM = 350;
949     final ScrollablePanel bottom = new ScrollablePanel();
950     bottom.setBorder(BorderFactory.createEmptyBorder(TWAALF, TWAALF, ELF, ELF));
951     bottom.setScrollableUnitIncrement(INCREMENT);
952     bottom.setScrollableBlockIncrement(FACTOR * INCREMENT);
953 
954     final Dimension preferredSize = egrid.preferredLayoutSize(bottom);
955     final int preferredHeight =
956       new Double(preferredSize.getHeight()).intValue();
957     bottom.setPreferredScrollableViewportSize(
958       adjustViewportSize(
959         new Dimension(preferredWidth, preferredHeight), MAX_HEIGHT_BOTTOM
960       )
961     );
962     Utilities.discardResult(bottom.add(parameterPanel));
963 
964 
965     return (bottom);
966   }
967 
968   private synchronized void createBorder(
969     JPanel parameterPanel, ConfigurationParameter parameter, int i
970   ) {
971     final Border lineBorder = BorderFactory.createLineBorder(Color.black);
972     final TitledBorder titleBorder =
973       BorderFactory.createTitledBorder(
974         lineBorder,
975         RESOURCES.getString("WINDOWTITLE_028") + " [" + (i + 1) + "] " +
976         parameter.getTitle()
977       );
978     parameterPanel.setBorder(titleBorder);
979   }
980 }
981