public CreateDialog(LayerPanel panel) {
    this.panel = panel;
    // setPreferredSize(new Dimension(200, 200));
    // setMinimumSize(new Dimension(200, 200));
    setLayout(new GridLayout(7, 0));
    XIn = new JFormattedTextField(NumberFormat.getNumberInstance());
    YIn = new JFormattedTextField(NumberFormat.getNumberInstance());
    ZIn = new JFormattedTextField(NumberFormat.getNumberInstance());

    create = new JButton("Create");
    ButtonListener buttonListener = new ButtonListener();
    create.addActionListener(buttonListener);
    XIn.setValue(new Integer(8));
    YIn.setValue(new Integer(8));
    ZIn.setValue(new Integer(8));
    XIn.addPropertyChangeListener(buttonListener);
    YIn.addPropertyChangeListener(buttonListener);
    ZIn.addPropertyChangeListener(buttonListener);
    add(new JLabel("Width:"));
    add(XIn);
    add(new JLabel("Height:"));
    add(YIn);
    add(new JLabel("Length:"));
    add(ZIn);
    add(create);
  }
  public FormattedTextFieldDemo() {
    super(new BorderLayout());
    setUpFormats();
    double payment = computePayment(amount, rate, numPeriods);

    // Create the labels.
    amountLabel = new JLabel(amountString);
    rateLabel = new JLabel(rateString);
    numPeriodsLabel = new JLabel(numPeriodsString);
    paymentLabel = new JLabel(paymentString);

    // Create the text fields and set them up.
    amountField = new JFormattedTextField(amountFormat);
    amountField.setValue(new Double(amount));
    amountField.setColumns(10);
    amountField.addPropertyChangeListener("value", this);

    rateField = new JFormattedTextField(percentFormat);
    rateField.setValue(new Double(rate));
    rateField.setColumns(10);
    rateField.addPropertyChangeListener("value", this);

    numPeriodsField = new JFormattedTextField();
    numPeriodsField.setValue(new Integer(numPeriods));
    numPeriodsField.setColumns(10);
    numPeriodsField.addPropertyChangeListener("value", this);

    paymentField = new JFormattedTextField(paymentFormat);
    paymentField.setValue(new Double(payment));
    paymentField.setColumns(10);
    paymentField.setEditable(false);
    paymentField.setForeground(Color.red);

    // Tell accessibility tools about label/textfield pairs.
    amountLabel.setLabelFor(amountField);
    rateLabel.setLabelFor(rateField);
    numPeriodsLabel.setLabelFor(numPeriodsField);
    paymentLabel.setLabelFor(paymentField);

    // Lay out the labels in a panel.
    JPanel labelPane = new JPanel(new GridLayout(0, 1));
    labelPane.add(amountLabel);
    labelPane.add(rateLabel);
    labelPane.add(numPeriodsLabel);
    labelPane.add(paymentLabel);

    // Layout the text fields in a panel.
    JPanel fieldPane = new JPanel(new GridLayout(0, 1));
    fieldPane.add(amountField);
    fieldPane.add(rateField);
    fieldPane.add(numPeriodsField);
    fieldPane.add(paymentField);

    // Put the panels in this panel, labels on left,
    // text fields on right.
    setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
    add(labelPane, BorderLayout.CENTER);
    add(fieldPane, BorderLayout.LINE_END);
  }
Beispiel #3
0
 /**
  * equivalent to registering a <code>PropertyChangeListener</code> on <code>value</code>.
  *
  * @param l
  */
 public void addValueChangeListener(ValueChangeListener listener) {
   if (valListener == null) {
     valListener =
         new PropertyChangeListener() {
           public void propertyChange(PropertyChangeEvent evt) {
             fireValueChange(evt.getOldValue(), evt.getNewValue());
           }
         };
     super.addPropertyChangeListener("value", valListener); // $NON-NLS-1$
   }
   listenerList.add(ValueChangeListener.class, listener);
   //		listener.valueChange(new ValueChangeEvent(this,getValue(),getValue()));
 }
  /** @param driver Needed for the Replicator-specific options */
  public PreferencesWindow(final MachineInterface machine) {
    super("Preferences");
    setResizable(true);

    Image icon = Base.getImage("images/icon.gif", this);
    setIconImage(icon);

    JTabbedPane prefTabs = new JTabbedPane();

    JPanel basic = new JPanel();

    //		Container content = this.getContentPane();
    Container content = basic;
    content.setLayout(new MigLayout("fill"));

    content.add(new JLabel("MainWindow font size: "), "split");
    fontSizeField = new JFormattedTextField(Base.getLocalFormat());
    fontSizeField.setColumns(4);
    content.add(fontSizeField);
    content.add(new JLabel("  (requires restart of ReplicatorG)"), "wrap");

    boolean checkTempDuringBuild = Base.preferences.getBoolean("build.monitor_temp", true);
    boolean displaySpeedWarning = Base.preferences.getBoolean("build.speed_warning", true);

    addCheckboxForPref(
        content, "Monitor temperature during builds", "build.monitor_temp", checkTempDuringBuild);
    addCheckboxForPref(
        content, "Display Accelerated Speed Warnings", "build.speed_warning", displaySpeedWarning);
    addCheckboxForPref(
        content, "Automatically connect to machine at startup", "replicatorg.autoconnect", true);
    addCheckboxForPref(
        content, "Show experimental machine profiles", "machine.showExperimental", false);
    addCheckboxForPref(
        content,
        "Review GCode for potential toolhead problems before building",
        "build.safetyChecks",
        true);
    addCheckboxForPref(
        content,
        "Break Z motion into separate moves (normally false)",
        "replicatorg.parser.breakzmoves",
        false);
    addCheckboxForPref(
        content, "Show starfield in model preview window", "ui.show_starfield", false);
    addCheckboxForPref(
        content, "Notifications in System tray", "ui.preferSystemTrayNotifications", false);
    addCheckboxForPref(
        content,
        "Automatically regenerate gcode when building from model view.",
        "build.autoGenerateGcode",
        true);
    addCheckboxForPref(
        content, "Use native avrdude for uploading code", "uploader.useNative", false);

    JPanel advanced = new JPanel();
    content = advanced;
    content.setLayout(new MigLayout("fill"));

    JButton modelColorButton;
    modelColorButton = new JButton("Choose model color");
    modelColorButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Note that this color is also defined in EditingModel.java
            Color modelColor = new Color(Base.preferences.getInt("ui.modelColor", -19635));
            modelColor = JColorChooser.showDialog(null, "Choose Model Color", modelColor);
            if (modelColor == null) return;

            Base.preferences.putInt("ui.modelColor", modelColor.getRGB());
            Base.getEditor().refreshPreviewPanel();
          }
        });
    modelColorButton.setVisible(true);
    content.add(modelColorButton, "split");

    JButton backgroundColorButton;
    backgroundColorButton = new JButton("Choose background color");
    backgroundColorButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Note that this color is also defined in EditingModel.java
            Color backgroundColor = new Color(Base.preferences.getInt("ui.backgroundColor", 0));
            backgroundColor =
                JColorChooser.showDialog(null, "Choose Background Color", backgroundColor);
            if (backgroundColor == null) return;

            Base.preferences.putInt("ui.backgroundColor", backgroundColor.getRGB());
            Base.getEditor().refreshPreviewPanel();
          }
        });
    backgroundColorButton.setVisible(true);
    content.add(backgroundColorButton, "wrap");

    content.add(new JLabel("Firmware update URL: "), "split");
    firmwareUpdateUrlField = new JTextField(34);
    content.add(firmwareUpdateUrlField, "growx, wrap");

    {
      JLabel arcResolutionLabel = new JLabel("Arc resolution (in mm): ");
      content.add(arcResolutionLabel, "split");
      double value = Base.preferences.getDouble("replicatorg.parser.curve_segment_mm", 1.0);
      JFormattedTextField arcResolutionField = new JFormattedTextField(Base.getLocalFormat());
      arcResolutionField.setValue(new Double(value));
      content.add(arcResolutionField);
      String arcResolutionHelp =
          "<html><small><em>"
              + "The arc resolution is the default segment length that the gcode parser will break arc codes <br>"
              + "like G2 and G3 into.  Drivers that natively handle arcs will ignore this setting."
              + "</em></small></html>";
      arcResolutionField.setToolTipText(arcResolutionHelp);
      arcResolutionLabel.setToolTipText(arcResolutionHelp);
      //			content.add(new JLabel(arcResolutionHelp),"growx,wrap");
      arcResolutionField.setColumns(10);
      arcResolutionField.addPropertyChangeListener(
          new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
              if (evt.getPropertyName() == "value") {
                try {
                  Double v = (Double) evt.getNewValue();
                  if (v == null) return;
                  Base.preferences.putDouble(
                      "replicatorg.parser.curve_segment_mm", v.doubleValue());
                } catch (ClassCastException cce) {
                  Base.logger.warning(
                      "Unexpected value type: " + evt.getNewValue().getClass().toString());
                }
              }
            }
          });
    }

    {
      JLabel sfTimeoutLabel = new JLabel("Skeinforge timeout: ");
      content.add(sfTimeoutLabel, "split, gap unrelated");
      int value = Base.preferences.getInt("replicatorg.skeinforge.timeout", -1);
      JFormattedTextField sfTimeoutField = new JFormattedTextField(Base.getLocalFormat());
      sfTimeoutField.setValue(new Integer(value));
      content.add(sfTimeoutField, "wrap 10px, growx");
      String sfTimeoutHelp =
          "<html><small><em>"
              + "The Skeinforge timeout is the number of seconds that replicatorg will wait while the<br>"
              + "Skeinforge preferences window is open. If you find that RepG freezes after editing profiles<br>"
              + "you can set this number greater than -1 (-1 means no timeout)."
              + "</em></small></html>";
      sfTimeoutField.setToolTipText(sfTimeoutHelp);
      sfTimeoutLabel.setToolTipText(sfTimeoutHelp);
      //			content.add(new JLabel(sfTimeoutHelp),"growx,wrap");
      sfTimeoutField.setColumns(10);
      sfTimeoutField.addPropertyChangeListener(
          new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
              if (evt.getPropertyName() == "value") {
                try {
                  Integer v = ((Number) evt.getNewValue()).intValue();
                  if (v == null) return;
                  Base.preferences.putInt("replicatorg.skeinforge.timeout", v.intValue());
                } catch (ClassCastException cce) {
                  Base.logger.warning(
                      "Unexpected value type: " + evt.getNewValue().getClass().toString());
                }
              }
            }
          });
    }

    {
      content.add(new JLabel("Debugging level (default INFO):"), "split");
      content.add(makeDebugLevelDropdown(), "wrap");

      final JCheckBox logCb = new JCheckBox("Log to file");
      logCb.setSelected(Base.preferences.getBoolean("replicatorg.useLogFile", false));
      content.add(logCb, "split");
      logCb.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              Base.preferences.putBoolean("replicatorg.useLogFile", logCb.isSelected());
            }
          });

      final JLabel logPathLabel = new JLabel("Log file name: ");
      content.add(logPathLabel, "split");
      logPathField = new JTextField(34);
      content.add(logPathField, "growx, wrap 10px");
      logPathField.setEnabled(logCb.isSelected());
      logPathLabel.setEnabled(logCb.isSelected());

      logCb.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              JCheckBox box = (JCheckBox) e.getSource();
              logPathField.setEnabled(box.isSelected());
              logPathLabel.setEnabled(box.isSelected());
            }
          });
    }

    {
      final int defaultTemp = 75;
      final String tooltipGeneral =
          "When enabled, starting all builds heats components to this temperature";
      final String tooltipHead = "Set preheat temperature for the specified toolhead";
      final String tooltipPlatform = "Set preheat temperature for the build platfom";

      final JCheckBox preheatCb = new JCheckBox("Preheat builds");
      preheatCb.setToolTipText(tooltipGeneral);
      content.add(preheatCb, "split");

      preheatCb.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
              Base.preferences.putBoolean("build.doPreheat", preheatCb.isSelected());
            }
          });
      preheatCb.setSelected(Base.preferences.getBoolean("build.doPreheat", false));

      final JLabel t0Label = new JLabel("Toolhead Right: ");
      final JLabel t1Label = new JLabel("Toolhead Left: ");
      final JLabel pLabel = new JLabel("Platform: ");

      Integer t0Value = Base.preferences.getInt("build.preheatTool0", defaultTemp);
      Integer t1Value = Base.preferences.getInt("build.preheatTool1", defaultTemp);
      Integer pValue = Base.preferences.getInt("build.preheatPlatform", defaultTemp);

      final JFormattedTextField t0Field = new JFormattedTextField(Base.getLocalFormat());
      final JFormattedTextField t1Field = new JFormattedTextField(Base.getLocalFormat());
      final JFormattedTextField pField = new JFormattedTextField(Base.getLocalFormat());

      t0Field.setToolTipText(tooltipHead);
      t0Label.setToolTipText(tooltipHead);
      t1Field.setToolTipText(tooltipHead);
      t1Label.setToolTipText(tooltipHead);
      pField.setToolTipText(tooltipPlatform);
      pLabel.setToolTipText(tooltipPlatform);

      t0Field.setValue(t0Value);
      t1Field.setValue(t1Value);
      pField.setValue(pValue);

      // let's avoid creating too many Anon. inner Listeners, also is fewer lines (and just as
      // clear)!
      PropertyChangeListener p =
          new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
              if (evt.getPropertyName() == "value") {
                double target;
                if (evt.getSource() == t0Field) {
                  target = ((Number) t0Field.getValue()).doubleValue();
                  target = confirmTemperature(target, "temperature.acceptedLimit", 200.0);
                  if (target == Double.MIN_VALUE) {
                    t0Field.setValue(Base.preferences.getInt("build.preheatTool0", defaultTemp));
                    return;
                  }
                  Base.preferences.putInt("build.preheatTool0", (int) target);
                } else if (evt.getSource() == t1Field) {
                  target = ((Number) t1Field.getValue()).doubleValue();
                  target = confirmTemperature(target, "temperature.acceptedLimit", 200.0);
                  if (target == Double.MIN_VALUE) {
                    t0Field.setValue(Base.preferences.getInt("build.preheatTool1", defaultTemp));
                    return;
                  }
                  Base.preferences.putInt("build.preheatTool1", (int) target);
                } else if (evt.getSource() == pField) {
                  target = ((Number) pField.getValue()).doubleValue();
                  target = confirmTemperature(target, "temperature.acceptedLimit.bed", 110.0);
                  if (target == Double.MIN_VALUE) {
                    t0Field.setValue(Base.preferences.getInt("build.preheatPlatform", defaultTemp));
                    return;
                  }
                  Base.preferences.putInt("build.preheatPlatform", (int) target);
                }
              }
            }
          };

      t0Field.addPropertyChangeListener(p);
      t1Field.addPropertyChangeListener(p);
      pField.addPropertyChangeListener(p);

      content.add(t0Label, "split, gap 20px");
      content.add(t0Field, "split, growx");
      content.add(t1Label, "split, gap unrelated");
      content.add(t1Field, "split, growx");
      content.add(pLabel, "split, gap unrelated");
      content.add(pField, "split, growx, wrap 10px");
    }

    {
      JButton b = new JButton("Select Python interpreter...");
      content.add(b, "spanx,wrap 10px");
      b.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              SwingPythonSelector sps = new SwingPythonSelector(PreferencesWindow.this);
              String path = sps.selectFreeformPath();
              if (path != null) {
                PythonUtils.setPythonPath(path);
              }
            }
          });
    }

    addInitialFilePrefs(content);

    prefTabs.add(basic, "Basic");
    prefTabs.add(advanced, "Advanced");

    content = getContentPane();
    content.setLayout(new MigLayout());

    content.add(prefTabs, "wrap");

    JButton allPrefs = new JButton("View Preferences Table");
    content.add(allPrefs, "split");
    allPrefs.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            JFrame advancedPrefs = new AdvancedPrefs();
            advancedPrefs.setVisible(true);
          }
        });

    // Also available as a menu item in the main gui.
    JButton delPrefs = new JButton("Reset all preferences");
    content.add(delPrefs);
    delPrefs.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            editor.resetPreferences();
          }
        });

    JButton button;
    button = new JButton("Close");
    button.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            applyFrame();
            dispose();
          }
        });
    content.add(button, "tag ok");

    showCurrentSettings();

    // closing the window is same as hitting cancel button
    addWindowListener(
        new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            dispose();
          }
        });

    ActionListener disposer =
        new ActionListener() {
          public void actionPerformed(ActionEvent actionEvent) {
            dispose();
          }
        };
    Base.registerWindowCloseKeys(getRootPane(), disposer);

    pack();
    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    setLocation((screen.width - getWidth()) / 2, (screen.height - getHeight()) / 2);

    // handle window closing commands for ctrl/cmd-W or hitting ESC.

    getContentPane()
        .addKeyListener(
            new KeyAdapter() {
              public void keyPressed(KeyEvent e) {
                KeyStroke wc = MainWindow.WINDOW_CLOSE_KEYSTROKE;
                if ((e.getKeyCode() == KeyEvent.VK_ESCAPE)
                    || (KeyStroke.getKeyStrokeForEvent(e).equals(wc))) {
                  dispose();
                }
              }
            });
  }
  @Override
  public JComponent createControl() {
    layerCanvasModelChangeChangeHandler = new LayerCanvasModelChangeHandler();
    productNodeChangeHandler = createProductNodeListener();
    cursorSynchronizer = new CursorSynchronizer(VisatApp.getApp());

    final DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(Locale.ENGLISH);
    scaleFormat = new DecimalFormat("#####.##", decimalFormatSymbols);
    scaleFormat.setGroupingUsed(false);
    scaleFormat.setDecimalSeparatorAlwaysShown(false);

    zoomInButton =
        ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/ZoomIn24.gif"), false);
    zoomInButton.setToolTipText("Zoom in."); /*I18N*/
    zoomInButton.setName("zoomInButton");
    zoomInButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(final ActionEvent e) {
            zoom(getCurrentView().getZoomFactor() * 1.2);
          }
        });

    zoomOutButton =
        ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/ZoomOut24.gif"), false);
    zoomOutButton.setName("zoomOutButton");
    zoomOutButton.setToolTipText("Zoom out."); /*I18N*/
    zoomOutButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(final ActionEvent e) {
            zoom(getCurrentView().getZoomFactor() / 1.2);
          }
        });

    zoomDefaultButton =
        ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/ZoomPixel24.gif"), false);
    zoomDefaultButton.setToolTipText("Actual Pixels (image pixel = view pixel)."); /*I18N*/
    zoomDefaultButton.setName("zoomDefaultButton");
    zoomDefaultButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(final ActionEvent e) {
            zoomToPixelResolution();
          }
        });

    zoomAllButton =
        ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/ZoomAll24.gif"), false);
    zoomAllButton.setName("zoomAllButton");
    zoomAllButton.setToolTipText("Zoom all."); /*I18N*/
    zoomAllButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(final ActionEvent e) {
            zoomAll();
          }
        });

    syncViewsButton =
        ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/SyncViews24.png"), true);
    syncViewsButton.setToolTipText("Synchronise compatible product views."); /*I18N*/
    syncViewsButton.setName("syncViewsButton");
    syncViewsButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(final ActionEvent e) {
            maybeSynchronizeCompatibleProductViews();
          }
        });

    syncCursorButton =
        ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/SyncCursor24.png"), true);
    syncCursorButton.setToolTipText("Synchronise cursor position."); /*I18N*/
    syncCursorButton.setName("syncCursorButton");
    syncCursorButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(final ActionEvent e) {
            cursorSynchronizer.setEnabled(syncCursorButton.isSelected());
          }
        });

    AbstractButton helpButton =
        ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/Help24.gif"), false);
    helpButton.setToolTipText("Help."); /*I18N*/
    helpButton.setName("helpButton");

    final JPanel eastPane = GridBagUtils.createPanel();
    final GridBagConstraints gbc = new GridBagConstraints();
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.fill = GridBagConstraints.NONE;
    gbc.weightx = 0.0;
    gbc.weighty = 0.0;

    gbc.gridy = 0;
    eastPane.add(zoomInButton, gbc);

    gbc.gridy++;
    eastPane.add(zoomOutButton, gbc);

    gbc.gridy++;
    eastPane.add(zoomDefaultButton, gbc);

    gbc.gridy++;
    eastPane.add(zoomAllButton, gbc);

    gbc.gridy++;
    eastPane.add(syncViewsButton, gbc);

    gbc.gridy++;
    eastPane.add(syncCursorButton, gbc);

    gbc.gridy++;
    gbc.weighty = 1.0;
    gbc.fill = GridBagConstraints.VERTICAL;
    eastPane.add(new JLabel(" "), gbc); // filler
    gbc.fill = GridBagConstraints.NONE;
    gbc.weighty = 0.0;

    gbc.gridy++;
    eastPane.add(helpButton, gbc);

    zoomFactorField = new JTextField();
    zoomFactorField.setColumns(8);
    zoomFactorField.setHorizontalAlignment(JTextField.CENTER);
    zoomFactorField.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(final ActionEvent e) {
            handleZoomFactorFieldUserInput();
          }
        });
    zoomFactorField.addFocusListener(
        new FocusAdapter() {
          @Override
          public void focusLost(final FocusEvent e) {
            handleZoomFactorFieldUserInput();
          }
        });

    rotationAngleSpinner = new JSpinner(new SpinnerNumberModel(0.0, -1800.0, 1800.0, 5.0));
    final JSpinner.NumberEditor editor = (JSpinner.NumberEditor) rotationAngleSpinner.getEditor();
    rotationAngleField = editor.getTextField();
    final DecimalFormat rotationFormat;
    rotationFormat = new DecimalFormat("#####.##", decimalFormatSymbols);
    rotationFormat.setGroupingUsed(false);
    rotationFormat.setDecimalSeparatorAlwaysShown(false);
    rotationAngleField.setFormatterFactory(
        new JFormattedTextField.AbstractFormatterFactory() {
          @Override
          public JFormattedTextField.AbstractFormatter getFormatter(JFormattedTextField tf) {
            return new NumberFormatter(rotationFormat);
          }
        });
    rotationAngleField.setColumns(6);
    rotationAngleField.setEditable(true);
    rotationAngleField.setHorizontalAlignment(JTextField.CENTER);
    rotationAngleField.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            handleRotationAngleFieldUserInput();
          }
        });
    rotationAngleField.addFocusListener(
        new FocusAdapter() {
          @Override
          public void focusLost(FocusEvent e) {
            handleRotationAngleFieldUserInput();
          }
        });
    rotationAngleField.addPropertyChangeListener(
        "value",
        new PropertyChangeListener() {

          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            handleRotationAngleFieldUserInput();
          }
        });

    zoomSlider = new JSlider(JSlider.HORIZONTAL);
    zoomSlider.setValue(0);
    zoomSlider.setMinimum(MIN_SLIDER_VALUE);
    zoomSlider.setMaximum(MAX_SLIDER_VALUE);
    zoomSlider.setPaintTicks(false);
    zoomSlider.setPaintLabels(false);
    zoomSlider.setSnapToTicks(false);
    zoomSlider.setPaintTrack(true);
    zoomSlider.addChangeListener(
        new ChangeListener() {
          @Override
          public void stateChanged(final ChangeEvent e) {
            if (!inUpdateMode) {
              zoom(sliderValueToZoomFactor(zoomSlider.getValue()));
            }
          }
        });

    final JPanel zoomFactorPane = new JPanel(new BorderLayout());
    zoomFactorPane.add(zoomFactorField, BorderLayout.WEST);

    final JPanel rotationAnglePane = new JPanel(new BorderLayout());
    rotationAnglePane.add(rotationAngleSpinner, BorderLayout.EAST);
    rotationAnglePane.add(new JLabel(" "), BorderLayout.CENTER);

    final JPanel sliderPane = new JPanel(new BorderLayout(2, 2));
    sliderPane.add(zoomFactorPane, BorderLayout.WEST);
    sliderPane.add(zoomSlider, BorderLayout.CENTER);
    sliderPane.add(rotationAnglePane, BorderLayout.EAST);

    canvas = createNavigationCanvas();
    canvas.setBackground(new Color(138, 133, 128)); // image background
    canvas.setForeground(new Color(153, 153, 204)); // slider overlay

    final JPanel centerPane = new JPanel(new BorderLayout(4, 4));
    centerPane.add(BorderLayout.CENTER, canvas);
    centerPane.add(BorderLayout.SOUTH, sliderPane);

    final JPanel mainPane = new JPanel(new BorderLayout(8, 8));
    mainPane.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
    mainPane.add(centerPane, BorderLayout.CENTER);
    mainPane.add(eastPane, BorderLayout.EAST);

    mainPane.setPreferredSize(new Dimension(320, 320));

    if (getDescriptor().getHelpId() != null) {
      HelpSys.enableHelpOnButton(helpButton, getDescriptor().getHelpId());
      HelpSys.enableHelpKey(mainPane, getDescriptor().getHelpId());
    }

    setCurrentView(VisatApp.getApp().getSelectedProductSceneView());

    updateState();

    // Add an internal frame listener to VISAT so that we can update our
    // navigation window with the information of the currently activated
    // product scene view.
    //
    VisatApp.getApp().addInternalFrameListener(new NavigationIFL());

    return mainPane;
  }
  public fileBackupProgram(JFrame frame) {
    super(new BorderLayout());
    this.frame = frame;

    errorDialog = new CustomDialog(frame, "Please enter a new name for the error log", this);
    errorDialog.pack();

    moveDialog = new CustomDialog(frame, "Please enter a new name for the move log", this);
    moveDialog.pack();

    printer = new FilePrinter();
    timers = new ArrayList<>();
    log = new JTextArea(5, 20);
    log.setMargin(new Insets(5, 5, 5, 5));
    log.setEditable(false);
    JScrollPane logScrollPane = new JScrollPane(log);
    Object obj;
    copy = true;
    listModel = new DefaultListModel();
    // destListModel = new DefaultListModel();
    directoryList = new directoryStorage();

    // Create a file chooser
    fc = new JFileChooser();

    // Create the menu bar.
    menuBar = new JMenuBar();

    // Build the first menu.
    menu = new JMenu("File");
    menu.getAccessibleContext()
        .setAccessibleDescription("The only menu in this program that has menu items");
    menuBar.add(menu);

    editError = new JMenuItem("Save Error Log As...");
    editError
        .getAccessibleContext()
        .setAccessibleDescription("Change the name of the error log file");
    editError.addActionListener(new ErrorListener());
    menu.add(editError);

    editMove = new JMenuItem("Save Move Log As...");
    editMove
        .getAccessibleContext()
        .setAccessibleDescription("Change the name of the move log file");
    editMove.addActionListener(new MoveListener());
    menu.add(editMove);

    exit = new JMenuItem("Exit");
    exit.getAccessibleContext().setAccessibleDescription("Exit the Program");
    exit.addActionListener(new CloseListener());
    menu.add(exit);
    frame.setJMenuBar(menuBar);
    // Uncomment one of the following lines to try a different
    // file selection mode.  The first allows just directories
    // to be selected (and, at least in the Java look and feel,
    // shown).  The second allows both files and directories
    // to be selected.  If you leave these lines commented out,
    // then the default mode (FILES_ONLY) will be used.
    //
    fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    // fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

    openButton = new JButton(openString);
    openButton.setActionCommand(openString);
    openButton.addActionListener(new OpenListener());

    destButton = new JButton(destString);
    destButton.setActionCommand(destString);
    destButton.addActionListener(new DestListener());

    // Create the save button.  We use the image from the JLF
    // Graphics Repository (but we extracted it from the jar).
    saveButton = new JButton(saveString);
    saveButton.setActionCommand(saveString);
    saveButton.addActionListener(new SaveListener());

    URL imageURL = getClass().getResource(greenButtonIcon);
    ImageIcon greenSquare = new ImageIcon(imageURL);
    startButton = new JButton("Start", greenSquare);
    startButton.setSize(60, 20);
    startButton.setHorizontalTextPosition(AbstractButton.LEADING);
    startButton.setActionCommand("Start");
    startButton.addActionListener(new StartListener());

    imageURL = getClass().getResource(redButtonIcon);
    ImageIcon redSquare = new ImageIcon(imageURL);
    stopButton = new JButton("Stop", redSquare);
    stopButton.setSize(60, 20);
    stopButton.setHorizontalTextPosition(AbstractButton.LEADING);
    stopButton.setActionCommand("Stop");
    stopButton.addActionListener(new StopListener());

    copyButton = new JRadioButton("Copy");
    copyButton.setActionCommand("Copy");
    copyButton.setSelected(true);
    copyButton.addActionListener(new RadioListener());

    moveButton = new JRadioButton("Move");
    moveButton.setActionCommand("Move");
    moveButton.addActionListener(new RadioListener());

    ButtonGroup group = new ButtonGroup();
    group.add(copyButton);
    group.add(moveButton);

    // For layout purposes, put the buttons in a separate panel

    JPanel optionPanel = new JPanel();

    GroupLayout layout = new GroupLayout(optionPanel);
    optionPanel.setLayout(layout);

    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);

    layout.setHorizontalGroup(
        layout.createSequentialGroup().addComponent(copyButton).addComponent(moveButton));
    layout.setVerticalGroup(
        layout
            .createSequentialGroup()
            .addGroup(
                layout
                    .createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(copyButton)
                    .addComponent(moveButton)));

    JPanel buttonPanel = new JPanel(); // use FlowLayout

    layout = new GroupLayout(buttonPanel);
    buttonPanel.setLayout(layout);

    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);

    layout.setHorizontalGroup(
        layout
            .createSequentialGroup()
            .addGroup(
                layout
                    .createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(openButton)
                    .addComponent(optionPanel))
            .addComponent(destButton)
            .addComponent(startButton)
            .addComponent(stopButton)
        // .addComponent(saveButton)
        );
    layout.setVerticalGroup(
        layout
            .createSequentialGroup()
            .addGroup(
                layout
                    .createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(openButton)
                    .addComponent(destButton)
                    .addComponent(startButton)
                    .addComponent(stopButton)
                // .addComponent(saveButton)
                )
            .addComponent(optionPanel));

    buttonPanel.add(optionPanel);
    /*
    buttonPanel.add(openButton);
    buttonPanel.add(destButton);
    buttonPanel.add(startButton);
    buttonPanel.add(stopButton);
    buttonPanel.add(saveButton);
    buttonPanel.add(listLabel);
    buttonPanel.add(copyButton);
    buttonPanel.add(moveButton);
    */
    destButton.setEnabled(false);
    startButton.setEnabled(false);
    stopButton.setEnabled(false);

    // Add the buttons and the log to this panel.

    // add(logScrollPane, BorderLayout.CENTER);

    JLabel listLabel = new JLabel("Monitored Directory:");
    listLabel.setLabelFor(list);

    // Create the list and put it in a scroll pane.
    list = new JList(listModel);
    list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    list.setSelectedIndex(0);
    list.addListSelectionListener(this);
    list.setVisibleRowCount(8);
    JScrollPane listScrollPane = new JScrollPane(list);
    JPanel listPane = new JPanel();
    listPane.setLayout(new BorderLayout());

    listPane.add(listLabel, BorderLayout.PAGE_START);
    listPane.add(listScrollPane, BorderLayout.CENTER);

    listSelectionModel = list.getSelectionModel();
    listSelectionModel.addListSelectionListener(new SharedListSelectionHandler());
    // monitored, destination, waitInt, check

    destination = new JLabel("Destination Directory: ");

    waitField = new JFormattedTextField();
    // waitField.setValue(240);
    waitField.setEditable(false);
    waitField.addPropertyChangeListener(new FormattedTextListener());

    waitInt = new JLabel("Wait Interval (in minutes)");
    // waitInt.setLabelFor(waitField);

    checkField = new JFormattedTextField();
    checkField.setSize(1, 10);
    // checkField.setValue(60);
    checkField.setEditable(false);
    checkField.addPropertyChangeListener(new FormattedTextListener());

    check = new JLabel("Check Interval (in minutes)");
    // check.setLabelFor(checkField);

    fireButton = new JButton(fireString);
    fireButton.setActionCommand(fireString);
    fireButton.addActionListener(new FireListener());

    JPanel fieldPane = new JPanel();
    // fieldPane.add(destField);
    layout = new GroupLayout(fieldPane);
    fieldPane.setLayout(layout);

    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);

    layout.setHorizontalGroup(
        layout
            .createSequentialGroup()
            .addGroup(
                layout
                    .createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(waitInt)
                    .addComponent(check))
            .addGroup(
                layout
                    .createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(waitField, 60, 60, 60)
                    .addComponent(checkField, 60, 60, 60)));

    layout.setVerticalGroup(
        layout
            .createSequentialGroup()
            .addGroup(
                layout
                    .createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(waitInt)
                    .addComponent(waitField))
            .addGroup(
                layout
                    .createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(check)
                    .addComponent(checkField)));

    JPanel labelPane = new JPanel();

    labelPane.setLayout(new BorderLayout());

    labelPane.add(destination, BorderLayout.PAGE_START);
    labelPane.add(fieldPane, BorderLayout.CENTER);

    layout = new GroupLayout(labelPane);
    labelPane.setLayout(layout);

    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);

    layout.setHorizontalGroup(
        layout
            .createSequentialGroup()
            .addGroup(
                layout
                    .createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(destination)
                    .addComponent(fieldPane)));

    layout.setVerticalGroup(
        layout.createSequentialGroup().addComponent(destination).addComponent(fieldPane));
    // labelPane.add(destination);
    // labelPane.add(fieldPane);

    try {
      // Read from disk using FileInputStream
      FileInputStream f_in = new FileInputStream(LOG_DIRECTORY + "\\save.data");

      // Read object using ObjectInputStream
      ObjectInputStream obj_in = new ObjectInputStream(f_in);

      // Read an object
      directoryList = (directoryStorage) obj_in.readObject();
      ERROR_LOG_NAME = (String) obj_in.readObject();
      MOVE_LOG_NAME = (String) obj_in.readObject();

      if (ERROR_LOG_NAME instanceof String) {
        printer.changeErrorLogName(ERROR_LOG_NAME);
      }

      if (MOVE_LOG_NAME instanceof String) {
        printer.changeMoveLogName(MOVE_LOG_NAME);
      }

      if (directoryList instanceof directoryStorage) {
        System.out.println("found object");
        // directoryList = (directoryStorage) obj;

        Iterator<Directory> directories = directoryList.getDirectories();
        Directory d;
        while (directories.hasNext()) {
          d = directories.next();

          try {
            listModel.addElement(d.getDirectory().toRealPath());
          } catch (IOException x) {
            printer.printError(x.toString());
          }

          int index = list.getSelectedIndex();
          if (index == -1) {
            list.setSelectedIndex(0);
          }

          index = list.getSelectedIndex();
          Directory dir = directoryList.getDirectory(index);

          destButton.setEnabled(true);
          checkField.setValue(dir.getInterval());
          waitField.setValue(dir.getWaitInterval());
          checkField.setEditable(true);
          waitField.setEditable(true);

          // directoryList.addNewDirectory(d);
          // try {
          // listModel.addElement(d.getDirectory().toString());
          // } catch (IOException x) {
          // printer.printError(x.toString());
          // }

          // timer = new Timer();
          // timer.schedule(new CopyTask(d.directory, d.destination, d.getWaitInterval(), printer,
          // d.copy), 0, d.getInterval());
        }

      } else {
        System.out.println("did not find object");
      }
      obj_in.close();
    } catch (ClassNotFoundException x) {
      printer.printError(x.getLocalizedMessage());
      System.err.format("Unable to read");
    } catch (IOException y) {
      printer.printError(y.getLocalizedMessage());
    }

    // Layout the text fields in a panel.

    JPanel buttonPane = new JPanel();
    buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));

    buttonPane.add(fireButton);
    buttonPane.add(Box.createHorizontalStrut(5));
    buttonPane.add(new JSeparator(SwingConstants.VERTICAL));
    buttonPane.add(Box.createHorizontalStrut(5));
    buttonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    add(buttonPanel, BorderLayout.PAGE_START);
    add(listPane, BorderLayout.LINE_START);
    // add(destListScrollPane, BorderLayout.CENTER);

    add(fieldPane, BorderLayout.LINE_END);
    add(labelPane, BorderLayout.CENTER);
    add(buttonPane, BorderLayout.PAGE_END);
  }
  ConversionPanel(
      Converter myController, String myTitle, Unit[] myUnits, ConverterRangeModel myModel) {
    if (MULTICOLORED) {
      setOpaque(true);
      setBackground(new Color(0, 255, 255));
    }
    setBorder(
        BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder(myTitle),
            BorderFactory.createEmptyBorder(5, 5, 5, 5)));

    // Save arguments in instance variables.
    controller = myController;
    units = myUnits;
    title = myTitle;
    sliderModel = myModel;

    // Create the text field format, and then the text field.
    numberFormat = NumberFormat.getNumberInstance();
    numberFormat.setMaximumFractionDigits(2);
    NumberFormatter formatter = new NumberFormatter(numberFormat);
    formatter.setAllowsInvalid(false);
    formatter.setCommitsOnValidEdit(true); // seems to be a no-op --
    // aha -- it changes the value property but doesn't cause the result to
    // be parsed (that happens on focus loss/return, I think).
    //
    textField = new JFormattedTextField(formatter);
    textField.setColumns(10);
    textField.setValue(new Double(sliderModel.getDoubleValue()));
    textField.addPropertyChangeListener(this);

    // Add the combo box.
    unitChooser = new JComboBox();
    for (int i = 0; i < units.length; i++) { // Populate it.
      unitChooser.addItem(units[i].description);
    }
    unitChooser.setSelectedIndex(0);
    sliderModel.setMultiplier(units[0].multiplier);
    unitChooser.addActionListener(this);

    // Add the slider.
    slider = new JSlider(sliderModel);
    sliderModel.addChangeListener(this);

    // Make the text field/slider group a fixed size
    // to make stacked ConversionPanels nicely aligned.
    JPanel unitGroup =
        new JPanel() {
          public Dimension getMinimumSize() {
            return getPreferredSize();
          }

          public Dimension getPreferredSize() {
            return new Dimension(150, super.getPreferredSize().height);
          }

          public Dimension getMaximumSize() {
            return getPreferredSize();
          }
        };
    unitGroup.setLayout(new BoxLayout(unitGroup, BoxLayout.PAGE_AXIS));
    if (MULTICOLORED) {
      unitGroup.setOpaque(true);
      unitGroup.setBackground(new Color(0, 0, 255));
    }
    unitGroup.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
    unitGroup.add(textField);
    unitGroup.add(slider);

    // Create a subpanel so the combo box isn't too tall
    // and is sufficiently wide.
    JPanel chooserPanel = new JPanel();
    chooserPanel.setLayout(new BoxLayout(chooserPanel, BoxLayout.PAGE_AXIS));
    if (MULTICOLORED) {
      chooserPanel.setOpaque(true);
      chooserPanel.setBackground(new Color(255, 0, 255));
    }
    chooserPanel.add(unitChooser);
    chooserPanel.add(Box.createHorizontalStrut(100));

    // Put everything together.
    setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    add(unitGroup);
    add(chooserPanel);
    unitGroup.setAlignmentY(TOP_ALIGNMENT);
    chooserPanel.setAlignmentY(TOP_ALIGNMENT);
  }
  @Override
  public void installUI(JComponent c) {
    super.installUI(c);

    textFormattedField = (JFormattedTextField) c;

    textFormattedField.setFocusable(true);
    textFormattedField.setOpaque(false);
    textFormattedField.setMargin(new Insets(0, 0, 0, 0));
    textFormattedField.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
    textFormattedField.setFont(AdobeLookAndFeel.fontBold);
    textFormattedField.setForeground(AdobeLookAndFeel.colorText);
    textFormattedField.setSelectionColor(new Color(100, 100, 100));
    textFormattedField.setCaretColor(AdobeLookAndFeel.colorText);

    mouseAdapter =
        new MouseAdapter() {
          @Override
          public void mouseReleased(MouseEvent e) {
            textFormattedField.repaint();
          }

          @Override
          public void mousePressed(MouseEvent e) {
            textFormattedField.repaint();
          }

          @Override
          public void mouseClicked(MouseEvent e) {
            textFormattedField.repaint();
          }
        };
    textFormattedField.addMouseListener(mouseAdapter);

    keyAdapter =
        new KeyAdapter() {
          @Override
          public void keyPressed(KeyEvent e) {
            textFormattedField.repaint();
          }
        };
    textFormattedField.addKeyListener(keyAdapter);

    focusListener =
        new FocusAdapter() {
          @Override
          public void focusGained(FocusEvent e) {
            textFormattedField.repaint();
          }

          @Override
          public void focusLost(FocusEvent e) {
            textFormattedField.repaint();
          }
        };
    textFormattedField.addFocusListener(focusListener);

    propertyChangeListener =
        new PropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            textFormattedField.repaint();
          }
        };
    textFormattedField.addPropertyChangeListener(
        AccessibleContext.ACCESSIBLE_STATE_PROPERTY, propertyChangeListener);
  }
  private void initGui() {
    block1 = new JPanel();
    block2 = new JPanel();
    expResMinThreadsLabel = new JLabel();
    expResMaxThreadsLabel = new JLabel();
    expResGeomLabel = new JLabel();
    expResGeomCacheLabel = new JLabel();
    expResGeomDrainLabel = new JLabel();
    expResGeomPartLabel = new JLabel();
    expResFeatLabel = new JLabel();
    expResFeatCacheLabel = new JLabel();
    expResFeatDrainLabel = new JLabel();
    expResFeatPartLabel = new JLabel();

    DecimalFormat threeIntFormat = new DecimalFormat("###");
    threeIntFormat.setMaximumIntegerDigits(3);
    threeIntFormat.setMinimumIntegerDigits(1);
    expResMinThreadsText = new JFormattedTextField(threeIntFormat);
    expResMaxThreadsText = new JFormattedTextField(threeIntFormat);
    expResGeomDrainText = new JFormattedTextField(threeIntFormat);
    expResFeatDrainText = new JFormattedTextField(threeIntFormat);
    expResGeomPartText = new JFormattedTextField(threeIntFormat);
    expResFeatPartText = new JFormattedTextField(threeIntFormat);

    DecimalFormat cacheEntryFormat = new DecimalFormat("########");
    cacheEntryFormat.setMaximumIntegerDigits(8);
    cacheEntryFormat.setMinimumIntegerDigits(1);
    expResGeomCacheText = new JFormattedTextField(cacheEntryFormat);
    expResFeatCacheText = new JFormattedTextField(cacheEntryFormat);

    PopupMenuDecorator.getInstance()
        .decorate(
            expResMinThreadsText,
            expResMaxThreadsText,
            expResGeomDrainText,
            expResFeatDrainText,
            expResGeomPartText,
            expResFeatPartText,
            expResGeomCacheText,
            expResFeatCacheText);

    expResMinThreadsText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            checkNonNegative(expResMinThreadsText, 1);
          }
        });

    expResMaxThreadsText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            checkNonNegative(expResMaxThreadsText, 1);
          }
        });

    expResGeomCacheText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            checkNonNegative(expResGeomCacheText, 200000);
          }
        });

    expResFeatCacheText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            checkNonNegative(expResFeatCacheText, 200000);
          }
        });

    expResGeomDrainText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            checkNonNegativeRange(expResGeomDrainText, 85, 100);
          }
        });

    expResFeatDrainText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            checkNonNegativeRange(expResFeatDrainText, 85, 100);
          }
        });

    expResGeomPartText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            checkNonNegativeRange(expResGeomPartText, 10, 100);
          }
        });

    expResFeatPartText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            checkNonNegativeRange(expResFeatPartText, 10, 100);
          }
        });

    setLayout(new GridBagLayout());
    add(block1, GuiUtil.setConstraints(0, 0, 1.0, 0.0, GridBagConstraints.BOTH, 5, 0, 5, 0));
    block1.setBorder(BorderFactory.createTitledBorder(""));
    block1.setLayout(new GridBagLayout());
    {
      block1.add(
          expResMinThreadsLabel,
          GuiUtil.setConstraints(0, 0, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block1.add(
          expResMinThreadsText,
          GuiUtil.setConstraints(1, 0, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block1.add(
          expResMaxThreadsLabel,
          GuiUtil.setConstraints(0, 1, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block1.add(
          expResMaxThreadsText,
          GuiUtil.setConstraints(1, 1, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
    }

    add(block2, GuiUtil.setConstraints(0, 1, 1.0, 0.0, GridBagConstraints.BOTH, 5, 0, 5, 0));
    block2.setBorder(BorderFactory.createTitledBorder(""));
    block2.setLayout(new GridBagLayout());
    {
      block2.add(
          expResGeomLabel,
          GuiUtil.setConstraints(0, 0, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResGeomCacheText,
          GuiUtil.setConstraints(1, 0, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResGeomCacheLabel,
          GuiUtil.setConstraints(2, 0, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResGeomDrainText,
          GuiUtil.setConstraints(1, 1, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResGeomDrainLabel,
          GuiUtil.setConstraints(2, 1, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResGeomPartText,
          GuiUtil.setConstraints(1, 2, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResGeomPartLabel,
          GuiUtil.setConstraints(2, 2, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResFeatLabel,
          GuiUtil.setConstraints(0, 3, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResFeatCacheText,
          GuiUtil.setConstraints(1, 3, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResFeatCacheLabel,
          GuiUtil.setConstraints(2, 3, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResFeatDrainText,
          GuiUtil.setConstraints(1, 4, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResFeatDrainLabel,
          GuiUtil.setConstraints(2, 4, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResFeatPartText,
          GuiUtil.setConstraints(1, 5, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      block2.add(
          expResFeatPartLabel,
          GuiUtil.setConstraints(2, 5, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
    }
  }
  private void initGui() {
    srsComboBoxLabel = new JLabel();
    sridLabel = new JLabel();

    DecimalFormat tileFormat = new DecimalFormat("##########");
    tileFormat.setMaximumIntegerDigits(10);
    tileFormat.setMinimumIntegerDigits(1);
    sridText = new JFormattedTextField(tileFormat);

    srsNameLabel = new JLabel();
    gmlSrsNameText = new JTextField();
    descriptionLabel = new JLabel();
    descriptionText = new JTextField();
    newButton = new JButton();
    applyButton = new JButton();
    deleteButton = new JButton();
    checkButton = new JButton();
    checkButton.setEnabled(false);
    copyButton = new JButton();

    fileLabel = new JLabel();
    fileText = new JTextField();
    browseFileButton = new JButton();
    addFileButton = new JButton();
    replaceWithFileButton = new JButton();
    saveFileButton = new JButton();

    dbSrsTypeLabel = new JLabel();
    dbSrsTypeText = new JTextPane();
    dbSrsNameLabel = new JLabel();
    dbSrsNameText = new JTextPane();

    srsComboBoxFactory = SrsComboBoxFactory.getInstance(config);
    srsComboBox = srsComboBoxFactory.createSrsComboBox(false);

    PopupMenuDecorator.getInstance()
        .decorate(
            sridText, gmlSrsNameText, descriptionText, fileText, dbSrsTypeText, dbSrsNameText);

    sridText.addPropertyChangeListener(
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            if (sridText.getValue() != null) {
              if (((Number) sridText.getValue()).intValue() < 0) sridText.setValue(0);
              else if (((Number) sridText.getValue()).intValue() > Integer.MAX_VALUE)
                sridText.setValue(Integer.MAX_VALUE);
            }
          }
        });

    setLayout(new GridBagLayout());

    contentsPanel = new JPanel();
    contentsPanel.setBorder(BorderFactory.createTitledBorder(""));
    contentsPanel.setLayout(new GridBagLayout());
    add(contentsPanel, GuiUtil.setConstraints(0, 0, 1.0, 0.0, GridBagConstraints.BOTH, 5, 0, 5, 0));
    {
      JPanel srsPanel = new JPanel();
      srsPanel.setLayout(new GridBagLayout());

      gmlSrsNameText.setPreferredSize(gmlSrsNameText.getPreferredSize());
      descriptionText.setPreferredSize(gmlSrsNameText.getPreferredSize());
      srsComboBox.setPreferredSize(gmlSrsNameText.getPreferredSize());

      srsPanel.add(
          sridLabel,
          GuiUtil.setConstraints(
              0, 0, 0, 0, GridBagConstraints.BOTH, 0, BORDER_THICKNESS, 0, BORDER_THICKNESS));
      srsPanel.add(
          sridText,
          GuiUtil.setConstraints(
              1, 0, 1, 0, GridBagConstraints.HORIZONTAL, 0, BORDER_THICKNESS, 0, BORDER_THICKNESS));
      srsPanel.add(
          checkButton,
          GuiUtil.setConstraints(
              2, 0, 0, 0, GridBagConstraints.HORIZONTAL, 0, BORDER_THICKNESS, 0, BORDER_THICKNESS));

      srsPanel.add(
          srsNameLabel,
          GuiUtil.setConstraints(
              0,
              1,
              0,
              0,
              GridBagConstraints.BOTH,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              0,
              BORDER_THICKNESS));
      srsPanel.add(
          gmlSrsNameText,
          GuiUtil.setConstraints(
              1,
              1,
              2,
              1,
              1,
              0,
              GridBagConstraints.HORIZONTAL,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              0,
              BORDER_THICKNESS));

      srsPanel.add(
          descriptionLabel,
          GuiUtil.setConstraints(
              0,
              2,
              0,
              0,
              GridBagConstraints.BOTH,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              0,
              BORDER_THICKNESS));
      srsPanel.add(
          descriptionText,
          GuiUtil.setConstraints(
              1,
              2,
              2,
              1,
              1,
              0,
              GridBagConstraints.HORIZONTAL,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              0,
              BORDER_THICKNESS));

      dbSrsTypeText.setEditable(false);
      dbSrsTypeText.setBorder(sridText.getBorder());
      dbSrsTypeText.setBackground(srsPanel.getBackground());
      dbSrsTypeText.setMargin(sridText.getMargin());

      dbSrsNameText.setEditable(false);
      dbSrsNameText.setBorder(sridText.getBorder());
      dbSrsNameText.setBackground(srsPanel.getBackground());
      dbSrsNameText.setMargin(sridText.getMargin());

      srsPanel.add(
          dbSrsNameLabel,
          GuiUtil.setConstraints(
              0,
              3,
              0,
              0,
              GridBagConstraints.HORIZONTAL,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              0,
              BORDER_THICKNESS));
      srsPanel.add(
          dbSrsNameText,
          GuiUtil.setConstraints(
              1,
              3,
              2,
              1,
              1,
              0,
              GridBagConstraints.BOTH,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              0,
              BORDER_THICKNESS));
      srsPanel.add(
          dbSrsTypeLabel,
          GuiUtil.setConstraints(
              0,
              4,
              0,
              0,
              GridBagConstraints.HORIZONTAL,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              BORDER_THICKNESS));
      srsPanel.add(
          dbSrsTypeText,
          GuiUtil.setConstraints(
              1,
              4,
              2,
              1,
              1,
              0,
              GridBagConstraints.BOTH,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              BORDER_THICKNESS));

      Box buttonsPanel = Box.createHorizontalBox();
      buttonsPanel.add(applyButton);
      buttonsPanel.add(Box.createRigidArea(new Dimension(2 * BORDER_THICKNESS, 0)));
      buttonsPanel.add(newButton);
      buttonsPanel.add(Box.createRigidArea(new Dimension(2 * BORDER_THICKNESS, 0)));
      buttonsPanel.add(copyButton);
      buttonsPanel.add(Box.createRigidArea(new Dimension(2 * BORDER_THICKNESS, 0)));
      buttonsPanel.add(deleteButton);
      buttonsPanel.add(Box.createRigidArea(new Dimension(2 * BORDER_THICKNESS, 0)));

      GridBagConstraints c =
          GuiUtil.setConstraints(
              0,
              5,
              3,
              1,
              1,
              0,
              GridBagConstraints.NONE,
              BORDER_THICKNESS * 2,
              BORDER_THICKNESS,
              BORDER_THICKNESS,
              BORDER_THICKNESS);
      c.anchor = GridBagConstraints.CENTER;
      srsPanel.add(buttonsPanel, c);

      JPanel currentlySupportedContent = new JPanel();
      currentlySupportedContent.setBorder(BorderFactory.createEmptyBorder());
      currentlySupportedContent.setLayout(new GridBagLayout());
      currentlySupportedContent.add(
          srsComboBoxLabel,
          GuiUtil.setConstraints(0, 0, 0.0, 1.0, GridBagConstraints.BOTH, 0, 5, 0, 5));
      currentlySupportedContent.add(
          srsComboBox, GuiUtil.setConstraints(1, 0, 1.0, 1.0, GridBagConstraints.BOTH, 0, 5, 0, 5));

      contentsPanel.add(
          currentlySupportedContent,
          GuiUtil.setConstraints(0, 0, 1.0, 0.0, GridBagConstraints.BOTH, 0, 0, 5, 0));
      contentsPanel.add(
          srsPanel, GuiUtil.setConstraints(0, 1, 1.0, 0.0, GridBagConstraints.BOTH, 20, 0, 5, 0));
    }

    impExpPanel = new JPanel();
    impExpPanel.setBorder(BorderFactory.createTitledBorder(""));
    impExpPanel.setLayout(new GridBagLayout());
    add(impExpPanel, GuiUtil.setConstraints(0, 1, 1.0, 0.0, GridBagConstraints.BOTH, 5, 0, 5, 0));
    {
      JPanel browse = new JPanel();
      JPanel button = new JPanel();

      impExpPanel.add(
          browse, GuiUtil.setConstraints(0, 0, 1.0, 1.0, GridBagConstraints.BOTH, 0, 0, 0, 0));
      impExpPanel.add(
          button, GuiUtil.setConstraints(0, 1, 0.0, 1.0, GridBagConstraints.BOTH, 5, 0, 5, 0));
      fileText.setPreferredSize(fileText.getPreferredSize());

      browse.setLayout(new GridBagLayout());
      {
        browse.add(
            fileLabel,
            GuiUtil.setConstraints(0, 0, 1.0, 0.0, GridBagConstraints.HORIZONTAL, 5, 5, 0, 5));
        browse.add(
            fileText,
            GuiUtil.setConstraints(0, 1, 0.0, 0.0, GridBagConstraints.HORIZONTAL, 0, 5, 5, 5));
        browse.add(
            browseFileButton,
            GuiUtil.setConstraints(1, 1, 0.0, 0.0, GridBagConstraints.BOTH, 0, 5, 5, 5));
      }

      button.setLayout(new GridBagLayout());
      {
        button.add(
            addFileButton, GuiUtil.setConstraints(0, 0, 0, 0, GridBagConstraints.NONE, 5, 5, 5, 5));
        button.add(
            replaceWithFileButton,
            GuiUtil.setConstraints(1, 0, 0, 0, GridBagConstraints.NONE, 5, 5, 5, 5));
        button.add(
            saveFileButton,
            GuiUtil.setConstraints(2, 0, 0, 0, GridBagConstraints.NONE, 5, 20, 5, 5));
      }
    }

    // influence focus policy
    checkButton.setFocusCycleRoot(false);

    srsComboBoxListener =
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            displaySelectedValues();
          }
        };

    DropTarget dropTarget = new DropTarget(fileText, this);
    fileText.setDropTarget(dropTarget);
    impExpPanel.setDropTarget(dropTarget);

    srsComboBox.addActionListener(srsComboBoxListener);

    newButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (requestChange()) {
              DatabaseSrs refSys = DatabaseSrs.createDefaultSrs();
              refSys.setDescription(getNewRefSysDescription());
              refSys.setSupported(!dbPool.isConnected());

              config.getProject().getDatabase().addReferenceSystem(refSys);
              updateSrsComboBoxes(false);
              srsComboBox.setSelectedItem(refSys);

              displaySelectedValues();
            }
          }
        });

    copyButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (requestChange()) {
              DatabaseSrs orig = srsComboBox.getSelectedItem();
              DatabaseSrs copy = new DatabaseSrs(orig);
              copy.setDescription(getCopyOfDescription(orig));

              config.getProject().getDatabase().addReferenceSystem(copy);
              updateSrsComboBoxes(false);
              srsComboBox.setSelectedItem(copy);

              displaySelectedValues();
            }
          }
        });

    applyButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            setSettings();
            LOG.info("Settings successfully applied.");
          }
        });

    deleteButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            DatabaseSrs refSys = srsComboBox.getSelectedItem();
            int index = srsComboBox.getSelectedIndex();

            String text = Language.I18N.getString("pref.db.srs.dialog.delete.msg");
            Object[] args = new Object[] {refSys.getDescription()};
            String formattedMsg = MessageFormat.format(text, args);

            if (JOptionPane.showConfirmDialog(
                    getTopLevelAncestor(),
                    formattedMsg,
                    Language.I18N.getString("pref.db.srs.dialog.delete.title"),
                    JOptionPane.YES_NO_OPTION)
                == JOptionPane.YES_OPTION) {
              config.getProject().getDatabase().getReferenceSystems().remove(refSys);
              updateSrsComboBoxes(false);
              srsComboBox.setSelectedIndex(index < srsComboBox.getItemCount() ? index : index - 1);
              displaySelectedValues();
            }
          }
        });

    checkButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            int srid = 0;

            try {
              srid = Integer.parseInt(sridText.getText().trim());
            } catch (NumberFormatException nfe) {
              //
            }

            try {
              DatabaseSrs tmp = DatabaseSrs.createDefaultSrs();
              tmp.setSrid(srid);
              dbPool.getActiveDatabaseAdapter().getUtil().getSrsInfo(tmp);
              if (tmp.isSupported()) {
                LOG.all(LogLevel.INFO, "SRID " + srid + " is supported.");
                LOG.all(LogLevel.INFO, "Database name: " + tmp.getDatabaseSrsName());
                LOG.all(LogLevel.INFO, "SRS type: " + tmp.getType());
              } else LOG.all(LogLevel.WARN, "SRID " + srid + " is NOT supported.");
            } catch (SQLException sqlEx) {
              LOG.error("Error while checking user-defined SRSs: " + sqlEx.getMessage().trim());
            }
          }
        });

    browseFileButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            browseReferenceSystemFile(Language.I18N.getString("pref.db.srs.label.file"));
          }
        });

    addFileButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            importReferenceSystems(false);
          }
        });

    replaceWithFileButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            importReferenceSystems(true);
          }
        });

    saveFileButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            exportReferenceSystems();
          }
        });
  }