/**
	 * Returns the maximum frequency spinner.
	 * If the spinner doesn't exist it is created:
	 * <ul>
	 * <li>with the specified {@link #getMaxFrequencyModel() model},</li>
	 * <li>to have specified size (80x25 pixel),</li>
	 * <li>with the listener which updates the value of the {@link
	 * #getMinFrequencySpinner() minimum frequency spinner} to be at least
	 * {@code 0.01} smaller then the value of this spinner.</li></ul>
	 * @return the maximum frequency spinner
	 */
	public JSpinner getMaxFrequencySpinner() {
		if (maxFrequencySpinner == null) {
			maxFrequencySpinner = new JSpinner(getMaxFrequencyModel());

			Dimension spinnerSize = new Dimension(80,25);
			maxFrequencySpinner.setPreferredSize(spinnerSize);
			maxFrequencySpinner.setMinimumSize(spinnerSize);
			maxFrequencySpinner.setMaximumSize(spinnerSize);

			maxFrequencySpinner.addChangeListener(new ChangeListener() {

				@Override
				public void stateChanged(ChangeEvent e) {

					double value = ((Number) maxFrequencySpinner.getValue()).doubleValue();

					double otherValue = ((Number) getMinFrequencySpinner().getValue()).doubleValue();

					if ((value-0.01) < otherValue) {
						getMinFrequencySpinner().setValue(value - 0.01);
					}

				}

			});

			maxFrequencySpinner.setEditor(new JSpinner.NumberEditor(maxFrequencySpinner, "0.00"));
			maxFrequencySpinner.setFont(maxFrequencySpinner.getFont().deriveFont(Font.PLAIN));

		}
		return maxFrequencySpinner;
	}
  /**
   * Méthode de création du panelInit
   *
   * @return
   */
  private JPanel createPanelInit() {

    JPanel panRight = new JPanel();
    panRight.setLayout(new BoxLayout(panRight, BoxLayout.Y_AXIS));

    butListParty = new JButton("Liste des parties");
    butListParty.addActionListener(this);

    JPanel panCreate = new JPanel();
    panCreate.setLayout(new BoxLayout(panCreate, BoxLayout.X_AXIS));
    textCreate = new JTextField("", 40);
    textCreate.setMaximumSize(textCreate.getPreferredSize());
    butCreateParty = new JButton("Creation de parties ");
    butCreateParty.addActionListener(this);
    SpinnerModel model = new SpinnerNumberModel(3, 2, 8, 1);
    spinNbPlayer = new JSpinner(model);
    spinNbPlayer.setMaximumSize(spinNbPlayer.getPreferredSize());
    panCreate.add(new JLabel("Nouveau nom de partie : "));
    panCreate.add(textCreate);
    panCreate.add(Box.createHorizontalStrut(20));
    panCreate.add(new JLabel("Nombres de joueurs : "));
    panCreate.add(spinNbPlayer);
    panCreate.add(butCreateParty);

    JPanel panJoin = new JPanel();
    panJoin.setLayout(new BoxLayout(panJoin, BoxLayout.X_AXIS));
    textJoin = new JTextField("", 2);
    textJoin.setMaximumSize(textJoin.getPreferredSize());
    butJoinParty = new JButton("Rejoindre la partie ");
    butJoinParty.addActionListener(this);
    panJoin.add(new JLabel("Num Partie : "));
    panJoin.add(textJoin);
    panJoin.add(butJoinParty);

    panRight.add(butListParty);
    panRight.add(panCreate);
    panRight.add(panJoin);
    panRight.add(Box.createVerticalGlue());

    textInfoInit = new JTextArea(20, 100);
    textInfoInit.setLineWrap(true);

    JScrollPane scroll =
        new JScrollPane(
            textInfoInit,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    JPanel panAll = new JPanel();
    panAll.setLayout(new BoxLayout(panAll, BoxLayout.X_AXIS));
    panAll.add(scroll);
    panAll.add(panRight);

    return panAll;
  }
 private void configureSpinnerFloat(JSpinner spinner) {
   JSpinner.NumberEditor editor = (JSpinner.NumberEditor) spinner.getEditor();
   DecimalFormat format = editor.getFormat();
   format.setMinimumFractionDigits(3);
   format.setMinimumIntegerDigits(1);
   editor.getTextField().setHorizontalAlignment(SwingConstants.CENTER);
   Dimension d = spinner.getPreferredSize();
   d.width = 60;
   spinner.setPreferredSize(d);
   spinner.addChangeListener(this);
   spinner.setMaximumSize(d);
 }
  public JPanel getAdditionalCharacteristicsPanel(final DisplayObjectType displayObjectType) {
    JLabel translationFactorLabel = new JLabel("Verschiebungsfaktor: ");
    SpinnerModel spinnerModel = new SpinnerNumberModel(100, 0, 5000, 1);
    _translationFactorSpinner.setModel(spinnerModel);
    _translationFactorSpinner.setMaximumSize(new Dimension(60, 30));
    _translationFactorSpinner.setEnabled(_dotDefinitionDialogFrame.isEditable());
    JPanel translationPanel = new JPanel();
    translationPanel.setLayout(new BoxLayout(translationPanel, BoxLayout.X_AXIS));
    translationPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 10));
    translationPanel.add(translationFactorLabel);
    translationPanel.add(_translationFactorSpinner);

    JLabel joinByLineLabel = new JLabel("Verbindungslinie: ");
    _joinByLineCheckBox.setSelected(false);
    _joinByLineCheckBox.setEnabled(_dotDefinitionDialogFrame.isEditable());
    JPanel joinByLinePanel = new JPanel();
    joinByLinePanel.setLayout(new BoxLayout(joinByLinePanel, BoxLayout.X_AXIS));
    joinByLinePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
    joinByLinePanel.add(joinByLineLabel);
    joinByLinePanel.add(_joinByLineCheckBox);

    JPanel invisiblePanel = new JPanel();
    invisiblePanel.add(new JTextField());
    invisiblePanel.setVisible(false);

    JPanel thePanel = new JPanel();
    thePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
    thePanel.setLayout(new SpringLayout());
    thePanel.add(translationPanel);
    thePanel.add(joinByLinePanel);
    thePanel.add(invisiblePanel);
    SpringUtilities.makeCompactGrid(thePanel, 3, 5, 5);

    if (displayObjectType != null) {
      DOTPoint dotPoint = (DOTPoint) displayObjectType;
      _translationFactorSpinner.setValue(dotPoint.getTranslationFactor());
      _joinByLineCheckBox.setSelected(dotPoint.isJoinByLine());
    }
    addChangeListeners(); // Erst jetzt, denn sonst werden die Setzungen von
                          // _translationFactorSpinner und _joinByLineCheckBox schon verarbeitet!

    return thePanel;
  }
  private StaticPanel createStaticSpinnerPanel(
      PrimitiveForm primitiveForm,
      DOTProperty property,
      String labelText,
      SpinnerModel spinnerModel) {
    JLabel label = new JLabel(labelText);
    JSpinner spinner = new JSpinner(spinnerModel);
    spinner.setMaximumSize(new Dimension(200, 20));
    spinner.setEnabled(_dotDefinitionDialogFrame.isEditable());

    StaticPanel thePanel = new StaticPanel(primitiveForm, property);
    thePanel.setLayout(new SpringLayout());
    thePanel.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.BLACK));
    thePanel.add(label);
    thePanel.add(spinner);
    SpringUtilities.makeCompactGrid(thePanel, 2, 5, 5);

    thePanel.setValue(spinner);
    thePanel.addListener(spinner);

    return thePanel;
  }
  private void setUpA1(List<DataSet> dataSets, Box a1) {
    int[] shifts = params.getShifts();

    if (shifts.length != dataSets.get(0).getNumColumns()) {
      shifts = new int[dataSets.get(0).getNumColumns()];
      params.setShifts(shifts);
    }

    final int[] _shifts = shifts;

    for (int i = 0; i < dataSets.get(0).getNumColumns(); i++) {
      Node node = dataSets.get(0).getVariable(i);
      Box a5 = Box.createHorizontalBox();

      SpinnerModel shiftModel = new SpinnerNumberModel(_shifts[i], -50, 50, 1);
      JSpinner shiftSpinner = new JSpinner(shiftModel);
      shiftSpinner.setMaximumSize(shiftSpinner.getPreferredSize());
      final int nodeIndex = i;

      shiftSpinner.addChangeListener(
          new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
              JSpinner spinner = (JSpinner) e.getSource();
              SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
              int value = (Integer) model.getValue();
              _shifts[nodeIndex] = value;
              params.setShifts(_shifts);
            }
          });

      a5.add(new JLabel("    Shift for "));
      a5.add(new JLabel(node.getName()));
      a5.add(new JLabel(" is "));
      a5.add(shiftSpinner);
      a5.add(Box.createHorizontalGlue());
      a1.add(a5);
    }
  }
 /** @return spinner_rotation */
 private JSpinner getSpinner_rotation() {
   if (spinner_rotation == null) {
     spinner_rotation = new JSpinner();
     spinner_rotation.setMaximumSize(new Dimension(80, 27));
     spinner_rotation.setMinimumSize(new Dimension(80, 27));
     spinner_rotation.setPreferredSize(new Dimension(80, 27));
     spinner_rotation.setModel(
         new SpinnerNumberModel(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 1));
     spinner_rotation.setValue(TwoAxes3D.getRotation());
     spinner_rotation.addChangeListener(
         new ChangeListener() {
           @Override
           public void stateChanged(ChangeEvent e) {
             TwoAxes3D.setRotation((Double) spinner_rotation.getValue());
             fireActionEvent(
                 new ActionEvent(
                     TwoAxes3DSettingsPanel.this,
                     0,
                     SycamoreFiredActionEvents.UPDATE_AGREEMENTS_GRAPHICS.name()));
           }
         });
   }
   return spinner_rotation;
 }
  private JPanel buildMainContentPane() {
    JPanel backPanel = new JPanel();
    backPanel.setSize(600, 400);
    backPanel.setLayout(new BoxLayout(backPanel, BoxLayout.Y_AXIS));
    backPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
    // mainPanel.setBorder(BorderFactory.createEmptyBorder(0,0,20,0));
    final JTextArea textArea = new JTextArea("Type your troll text here");
    textArea.addKeyListener(
        new KeyListener() {

          @Override
          public void keyTyped(KeyEvent arg0) {}

          @Override
          public void keyReleased(KeyEvent arg0) {
            if (autoupdate) destinationGUI.setTextCenter(textArea.getText());
          }

          @Override
          public void keyPressed(KeyEvent arg0) {}
        });
    textArea.setPreferredSize(new Dimension(260, 200));
    textArea.setMaximumSize(new Dimension(260, 200));
    textArea.setMinimumSize(new Dimension(260, 200));
    mainPanel.add(textArea);

    JPanel settingsPanel = new JPanel();
    settingsPanel.setSize(150, 220);
    settingsPanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0));
    settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.PAGE_AXIS));

    // CheckBox - Mise à jour auto du texte
    JCheckBox autoUpdateCB = new JCheckBox("Mise à jour auto du texte");
    autoUpdateCB.setSelected(autoupdate);
    autoUpdateCB.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {
            autoupdate = !autoupdate;
          }
        });
    autoUpdateCB.setAlignmentX(LEFT_ALIGNMENT);
    settingsPanel.add(autoUpdateCB);

    // CheckBox - Mise à jour auto de la couleur du texte
    JCheckBox autoUpdateTextColorCB = new JCheckBox("Mise à jour auto de la couleur du texte");
    autoUpdateTextColorCB.setSelected(autoupdateTextColor);
    autoUpdateTextColorCB.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {
            autoupdateTextColor = !autoupdateTextColor;
          }
        });
    autoUpdateTextColorCB.setAlignmentX(LEFT_ALIGNMENT);
    settingsPanel.add(autoUpdateTextColorCB);

    // CheckBox - Mise à jour auto de la couleur d'arri�re plan
    JCheckBox autoUpdateBackgroundColorCB =
        new JCheckBox("Mise à jour auto de la couleur d'arrière-plan");
    autoUpdateBackgroundColorCB.setSelected(autoupdateBackgroundColor);
    autoUpdateBackgroundColorCB.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {
            autoupdateBackgroundColor = !autoupdateBackgroundColor;
          }
        });
    autoUpdateBackgroundColorCB.setAlignmentX(LEFT_ALIGNMENT);
    settingsPanel.add(autoUpdateBackgroundColorCB);

    // Checkbox - MAJ auto de la taille du texte
    JCheckBox autoUpdateTextSizeCB = new JCheckBox("Mise à jour auto de la taille du texte");
    autoUpdateTextSizeCB.setSelected(autoupdateTextSize);
    autoUpdateTextSizeCB.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {
            autoupdateTextSize = !autoupdateTextSize;
          }
        });
    autoUpdateTextSizeCB.setAlignmentX(LEFT_ALIGNMENT);
    settingsPanel.add(autoUpdateTextSizeCB);

    // Chekbox - fullscreen on second Screen
    JCheckBox fullscreenCB = new JCheckBox("Activer le plein écran sur le deuxième écran");
    fullscreenCB.setSelected(fullscreen);
    fullscreenCB.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {
            fullscreen = !fullscreen;
          }
        });
    fullscreenCB.setAlignmentX(LEFT_ALIGNMENT);
    settingsPanel.add(fullscreenCB);

    JPanel backgroundColorPanel = new JPanel();
    backgroundColorPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    final JPanel backgroundColorPreviewPanel = new JPanel();
    backgroundColorPreviewPanel.setMaximumSize(new Dimension(50, 25));
    backgroundColorPreviewPanel.setPreferredSize(new Dimension(50, 25));
    backgroundColorPreviewPanel.setBackground(backgroundColor);

    JButton backgroundColorButton = new JButton("Choisir la couleur d'arrière-plan");
    backgroundColorButton.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {
            Color newColor =
                JColorChooser.showDialog(colorChooser, "Couleur d'arrière-plan", backgroundColor);
            if (newColor != null) {
              backgroundColor = newColor;
              backgroundColorPreviewPanel.setBackground(backgroundColor);
              if (autoupdateBackgroundColor) destinationGUI.setBackgroundColor(backgroundColor);
            }
          }
        });
    backgroundColorPanel.add(backgroundColorPreviewPanel);
    backgroundColorPanel.add(backgroundColorButton);
    backgroundColorPanel.setAlignmentX(LEFT_ALIGNMENT);
    settingsPanel.add(backgroundColorPanel);

    JPanel textColorPanel = new JPanel();
    textColorPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    final JPanel textColorPreviewPanel = new JPanel();
    textColorPreviewPanel.setMaximumSize(new Dimension(50, 25));
    textColorPreviewPanel.setPreferredSize(new Dimension(50, 25));
    textColorPreviewPanel.setBackground(textColor);

    JButton textColorButton = new JButton("Choisir la couleur du texte");
    textColorButton.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {
            Color newColor = JColorChooser.showDialog(colorChooser, "Couleur du texte", textColor);
            if (newColor != null) {
              textColor = newColor;
              textColorPreviewPanel.setBackground(textColor);
              if (autoupdateTextColor) destinationGUI.setTextColor(textColor);
            }
          }
        });

    textColorPanel.add(textColorPreviewPanel);
    textColorPanel.add(textColorButton);
    textColorPanel.setAlignmentX(LEFT_ALIGNMENT);
    settingsPanel.add(textColorPanel);

    colorChooser = new JColorChooser();

    SpinnerModel textSizeSpinnerModel = new SpinnerNumberModel(textSize, 1, 300, 1);
    final JSpinner textSizeSpinner = new JSpinner(textSizeSpinnerModel);
    textSizeSpinner.addChangeListener(
        new ChangeListener() {
          @Override
          public void stateChanged(ChangeEvent arg0) {
            if ((int) textSizeSpinner.getValue() != textSize) {
              textSize = (int) textSizeSpinner.getValue();
              if (autoupdateTextSize) destinationGUI.setTextSize(textSize);
            }
          }
        });
    JPanel textSizePanel = new JPanel();
    textSizePanel.setMaximumSize(new Dimension(300, 60));
    textSizePanel.setPreferredSize(new Dimension(300, 30));
    textSizePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    textSizePanel.setAlignmentX(LEFT_ALIGNMENT);
    JLabel textSizeLabel = new JLabel("Taille du texte");
    textSizeSpinner.setMaximumSize(new Dimension(45, 20));
    textSizePanel.add(textSizeLabel);
    textSizePanel.add(textSizeSpinner);
    JLabel screenLabel = new JLabel("Second écran");
    Integer[] screens = {0, 1};
    JComboBox<Integer> screenComboBox = new JComboBox<Integer>(screens);
    screenComboBox.setSelectedIndex(Main.secondScreen);
    screenComboBox.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            JComboBox<Integer> cb = (JComboBox<Integer>) e.getSource();
            if (cb.getSelectedItem().equals(0)) {
              Main.mainScreen = 1;
              Main.secondScreen = 0;
            } else {
              Main.mainScreen = 0;
              Main.secondScreen = 1;
            }
          }
        });
    screenComboBox.setMaximumSize(new Dimension(45, 20));
    textSizePanel.add(screenLabel);
    textSizePanel.add(screenComboBox);

    settingsPanel.add(textSizePanel);
    mainPanel.add(settingsPanel);
    backPanel.add(mainPanel);

    // RAINBOW PANEL
    JPanel rainbowPanel = new JPanel();
    rainbowPanel.setMinimumSize(new Dimension(50, 40));
    rainbowPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 15, 10));
    final JButton rainbowButton = new JButton("Activer le Rainbow Mode");
    rainbowButton.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            // rainbow mode is already activated :
            // stopping it...
            if (destinationGUI.isRainbowEnabled()) {
              destinationGUI.stopTimer();
              destinationGUI.setTextColor(textColor);
              destinationGUI.setBackgroundColor(backgroundColor);
              rainbowButton.setText("Activer le Rainbow Mode");
            }
            // Rainbow Mode is stopped :
            // starting it...
            else {
              destinationGUI.startTimer();
              rainbowButton.setText("Désactiver le Rainbow Mode");
            }
          }
        });

    JLabel epilepticLabel = new JLabel("Mode épileptique");
    final JCheckBox epilepticCheckBox = new JCheckBox();
    epilepticCheckBox.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            destinationGUI.setEpileptic(epilepticCheckBox.isSelected());
          }
        });
    JLabel speedLabel = new JLabel("Vitesse");
    final JSlider speedSlider =
        new JSlider(SwingConstants.HORIZONTAL, SPEED_MIN, SPEED_MAX, SPEED_INIT);
    speedSlider.addChangeListener(
        new ChangeListener() {

          @Override
          public void stateChanged(ChangeEvent e) {
            if (!speedSlider.getValueIsAdjusting()) {
              destinationGUI.setSpeed(speedSlider.getValue());
            }
          }
        });
    destinationGUI.setSpeed(SPEED_INIT);
    speedSlider.setPreferredSize(new Dimension(100, 30));

    rainbowPanel.add(rainbowButton);
    rainbowPanel.add(speedLabel);
    rainbowPanel.add(speedSlider);
    rainbowPanel.add(epilepticLabel);
    rainbowPanel.add(epilepticCheckBox);
    backPanel.add(rainbowPanel);

    // BOTTOM PANEL
    JPanel bottomPanel = new JPanel();
    bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 30, 10));
    bottomPanel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
    JButton updateButton = new JButton("Mettre à jour les modifications");
    updateButton.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {

            destinationGUI.setTextCenter(textArea.getText().replaceAll("\n", "<br>"));
            destinationGUI.setTextColor(textColor);
            destinationGUI.setBackgroundColor(backgroundColor);
            destinationGUI.setTextSize(textSize);
          }
        });
    bottomPanel.add(updateButton);

    final JButton secondScreen = new JButton("Envoyer sur le second écran");
    secondScreen.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {

            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice[] gd = ge.getScreenDevices();
            // Ramener sur le premier ecran
            if (isOnSecondScreen) {
              secondScreen.setText("Envoyer sur le second écran");
              showDestGUIOnScreen(Main.mainScreen);
              isOnSecondScreen = false;
              if (wasFullscreen) {
                quitFullscreen();
                destinationGUI = new GUI();
                destinationGUI.setTextCenter(textArea.getText());
                destinationGUI.setTextColor(textColor);
                destinationGUI.setBackgroundColor(backgroundColor);
                destinationGUI.setTextSize(textSize);
              }
            }
            // Envoyer sur le deuxieme ecran
            else {
              if (Main.protection && gd.length <= 1) {
                System.out.println("Erreur : Pas de second écran trouve");
                return;
              }
              showDestGUIOnScreen(Main.secondScreen);
              secondScreen.setText("Ramener sur le premier écran");
              isOnSecondScreen = true;
              wasFullscreen = fullscreen;
            }
          }
        });

    bottomPanel.add(secondScreen);
    bottomPanel.setAlignmentX(CENTER_ALIGNMENT);

    destinationGUI.setTextSize(textSize);
    destinationGUI.setTextColor(textColor);
    destinationGUI.setBackgroundColor(backgroundColor);
    destinationGUI.setTextCenter(textArea.getText());

    backPanel.add(bottomPanel);
    return backPanel;
  }
Exemple #9
0
  public LingDisplay(final Ling.StoredGraphs storedGraphs) {
    this.storedGraphs = storedGraphs;

    if (storedGraphs.getNumGraphs() == 0) {
      workbench = new GraphWorkbench();
    } else {
      workbench = new GraphWorkbench(storedGraphs.getGraph(0));
    }

    subsetIndices = getStableIndices(storedGraphs);

    final SpinnerNumberModel model =
        new SpinnerNumberModel(subsetIndices.size() == 0 ? 0 : 1, 0, subsetIndices.size(), 1);
    model.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            int index = model.getNumber().intValue();
            workbench.setGraph(storedGraphs.getGraph(subsetIndices.get(index - 1)));
          }
        });

    spinner = new JSpinner();
    subsetCombo = new JComboBox(new String[] {"Show Stable", "Show Unstable", "Show All"});
    subsetCombo.setSelectedItem("Show Stable");
    spinner.setModel(model);
    totalLabel = new JLabel(" of " + subsetIndices.size());

    subsetCombo.setMaximumSize(subsetCombo.getPreferredSize());
    subsetCombo.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            resetDisplay();
          }
        });

    spinner.setPreferredSize(new Dimension(50, 20));
    spinner.setMaximumSize(spinner.getPreferredSize());
    Box b = Box.createVerticalBox();
    Box b1 = Box.createHorizontalBox();
    //        b1.add(Box.createHorizontalGlue());
    //        b1.add(Box.createHorizontalStrut(10));
    b1.add(subsetCombo);
    b1.add(Box.createHorizontalGlue());
    b1.add(new JLabel("DAG "));
    b1.add(spinner);
    b1.add(totalLabel);

    b.add(b1);

    Box b2 = Box.createHorizontalBox();
    JPanel graphPanel = new JPanel();
    graphPanel.setLayout(new BorderLayout());
    JScrollPane jScrollPane = new JScrollPane(workbench);
    //        jScrollPane.setPreferredSize(new Dimension(400, 400));
    graphPanel.add(jScrollPane);
    //        graphPanel.setBorder(new TitledBorder("DAG"));
    b2.add(graphPanel);
    b.add(b2);

    setLayout(new BorderLayout());
    //        add(menuBar(), BorderLayout.NORTH);
    add(b, BorderLayout.CENTER);
  }
  public DetectPolygonControlPanel(DetectBlackPolygonApp owner) {
    this.owner = owner;

    imageView = new JComboBox();
    imageView.addItem("Input");
    imageView.addItem("Binary");
    imageView.addItem("Black");
    imageView.addActionListener(this);
    imageView.setMaximumSize(imageView.getPreferredSize());

    selectZoom = new JSpinner(new SpinnerNumberModel(1, 0.1, 50, 1));
    selectZoom.addChangeListener(this);
    selectZoom.setMaximumSize(selectZoom.getPreferredSize());

    showCorners = new JCheckBox("Corners");
    showCorners.addActionListener(this);
    showCorners.setSelected(bShowCorners);
    showLines = new JCheckBox("Lines");
    showLines.setSelected(bShowLines);
    showLines.addActionListener(this);
    showContour = new JCheckBox("Contour");
    showContour.addActionListener(this);
    showContour.setSelected(bShowContour);

    threshold = new ThresholdControlPanel(owner);

    refineChoice = new JComboBox();
    for (PolygonRefineType n : PolygonRefineType.values()) {
      refineChoice.addItem(n.name());
    }
    refineChoice.setSelectedIndex(refineType.ordinal());
    refineChoice.addActionListener(this);
    refineChoice.setMaximumSize(refineChoice.getPreferredSize());

    spinnerMinContourSize =
        new JSpinner(new SpinnerNumberModel(config.minContourImageWidthFraction, 0.0, 0.2, 0.01));
    configureSpinnerFloat(spinnerMinContourSize);
    spinnerMinSides = new JSpinner(new SpinnerNumberModel(minSides, 3, 20, 1));
    spinnerMinSides.setMaximumSize(spinnerMinSides.getPreferredSize());
    spinnerMinSides.addChangeListener(this);
    spinnerMaxSides = new JSpinner(new SpinnerNumberModel(maxSides, 3, 20, 1));
    spinnerMaxSides.setMaximumSize(spinnerMaxSides.getPreferredSize());
    spinnerMaxSides.addChangeListener(this);

    spinnerMinEdge =
        new JSpinner(new SpinnerNumberModel(config.minimumEdgeIntensity, 0.0, 255.0, 1.0));
    spinnerMinEdge.setMaximumSize(spinnerMinEdge.getPreferredSize());
    spinnerMinEdge.addChangeListener(this);
    spinnerContourSplit =
        new JSpinner(new SpinnerNumberModel(config.contour2Poly_splitFraction, 0.0, 1.0, 0.01));
    configureSpinnerFloat(spinnerContourSplit);
    spinnerContourMinSplit =
        new JSpinner(
            new SpinnerNumberModel(config.contour2Poly_minimumSideFraction, 0.0, 1.0, 0.001));
    configureSpinnerFloat(spinnerContourMinSplit);
    spinnerContourSplit.addChangeListener(this);
    spinnerContourIterations =
        new JSpinner(new SpinnerNumberModel(config.contour2Poly_iterations, 1, 200, 1));
    spinnerContourIterations.setMaximumSize(spinnerContourIterations.getPreferredSize());
    spinnerContourIterations.addChangeListener(this);
    spinnerSplitPenalty =
        new JSpinner(new SpinnerNumberModel(config.splitPenalty, 0.0, 100.0, 1.0));
    configureSpinnerFloat(spinnerSplitPenalty);

    setConvex = new JCheckBox("Convex");
    setConvex.addActionListener(this);
    setConvex.setSelected(config.convex);
    setBorder = new JCheckBox("Image Border");
    setBorder.addActionListener(this);
    setBorder.setSelected(config.canTouchBorder);

    spinnerLineSamples = new JSpinner(new SpinnerNumberModel(configLine.lineSamples, 5, 100, 1));
    spinnerLineSamples.setMaximumSize(spinnerLineSamples.getPreferredSize());
    spinnerLineSamples.addChangeListener(this);
    spinnerCornerOffset = new JSpinner(new SpinnerNumberModel(configLine.cornerOffset, 0, 10, 1));
    spinnerCornerOffset.setMaximumSize(spinnerCornerOffset.getPreferredSize());
    spinnerCornerOffset.addChangeListener(this);
    spinnerSampleRadius = new JSpinner(new SpinnerNumberModel(configLine.sampleRadius, 0, 10, 1));
    spinnerSampleRadius.setMaximumSize(spinnerCornerOffset.getPreferredSize());
    spinnerSampleRadius.addChangeListener(this);
    spinnerRefineMaxIterations =
        new JSpinner(new SpinnerNumberModel(configLine.maxIterations, 0, 200, 1));
    spinnerRefineMaxIterations.setMaximumSize(spinnerRefineMaxIterations.getPreferredSize());
    spinnerRefineMaxIterations.addChangeListener(this);
    spinnerConvergeTol =
        new JSpinner(new SpinnerNumberModel(configLine.convergeTolPixels, 0.0, 2.0, 0.005));
    configureSpinnerFloat(spinnerConvergeTol);
    spinnerMaxCornerChange =
        new JSpinner(new SpinnerNumberModel(configLine.maxCornerChangePixel, 0.0, 50.0, 1.0));
    configureSpinnerFloat(spinnerMaxCornerChange);

    addLabeled(imageView, "View: ", this);
    addLabeled(selectZoom, "Zoom", this);
    addAlignLeft(showCorners, this);
    addAlignLeft(showLines, this);
    addAlignLeft(showContour, this);
    add(threshold);
    addLabeled(spinnerMinContourSize, "Min Contour Size: ", this);
    addLabeled(spinnerMinSides, "Minimum Sides: ", this);
    addLabeled(spinnerMaxSides, "Maximum Sides: ", this);
    addLabeled(spinnerMinEdge, "Edge Intensity: ", this);
    addAlignLeft(setConvex, this);
    addAlignLeft(setBorder, this);
    addCenterLabel("Contour", this);
    addLabeled(spinnerContourSplit, "Split Fraction: ", this);
    addLabeled(spinnerContourMinSplit, "Min Split: ", this);
    addLabeled(spinnerContourIterations, "Max Iterations: ", this);
    addLabeled(spinnerSplitPenalty, "Split Penalty: ", this);
    addCenterLabel("Refinement", this);
    addLabeled(refineChoice, "Refine: ", this);
    addLabeled(spinnerLineSamples, "Line Samples: ", this);
    addLabeled(spinnerCornerOffset, "Corner Offset: ", this);
    addLabeled(spinnerSampleRadius, "Sample Radius: ", this);
    addLabeled(spinnerRefineMaxIterations, "Iterations: ", this);
    addLabeled(spinnerConvergeTol, "Converge Tol Pixels: ", this);
    addLabeled(spinnerMaxCornerChange, "Max Corner Change: ", this);
    addVerticalGlue(this);
  }
  /** Construct a new font selector. */
  public FontSelector() {
    Dimension d;

    // Widgets are laid out horizontally.
    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

    // Set up font family names and a 12-point normal font for each family.
    myFontFamilies =
        GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

    // Set up combo box for font family name.
    myFontFamilyComboBox = new JComboBox(myFontFamilies);
    d = myFontFamilyComboBox.getPreferredSize();
    myFontFamilyComboBox.setMinimumSize(d);
    myFontFamilyComboBox.setMaximumSize(d);
    myFontFamilyComboBox.setPreferredSize(d);
    myFontFamilyComboBox.setEditable(false);
    myFontFamilyComboBox.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
              updateSelectedFont();
            }
          }
        });
    add(myFontFamilyComboBox);
    add(Box.createHorizontalStrut(GAP));

    // Set up combo box for font style.
    myFontStyleComboBox = new JComboBox(new String[] {"Plain", "Bold", "Italic", "Bold Italic"});
    d = myFontStyleComboBox.getPreferredSize();
    myFontStyleComboBox.setMinimumSize(d);
    myFontStyleComboBox.setMaximumSize(d);
    myFontStyleComboBox.setPreferredSize(d);
    myFontStyleComboBox.setEditable(false);
    myFontStyleComboBox.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
              updateSelectedFont();
            }
          }
        });
    add(myFontStyleComboBox);
    add(Box.createHorizontalStrut(GAP));

    // Set up spinner for font size.
    myFontSizeSpinner = new JSpinner(new SpinnerNumberModel(12, 1, 144, 1));
    d = myFontSizeSpinner.getPreferredSize();
    myFontSizeSpinner.setMinimumSize(d);
    myFontSizeSpinner.setMaximumSize(d);
    myFontSizeSpinner.setPreferredSize(d);
    myFontSizeSpinner.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            updateSelectedFont();
          }
        });
    add(myFontSizeSpinner);
    add(Box.createHorizontalStrut(GAP));

    // Set up text sample.
    myTextSample = new JLabel("Quick Brown Fox 123");
    d = myTextSample.getPreferredSize();
    myTextSample.setMinimumSize(d);
    myTextSample.setMaximumSize(d);
    myTextSample.setPreferredSize(d);
    add(myTextSample);

    // Set default selected font.
    setSelectedFont(new Font("SansSerif", Font.PLAIN, 12));
  }
  /** Builds the panel. */
  public void setup() {
    DataModelList dataModelList = null;

    for (Object parentModel : parentModels) {
      if (parentModel instanceof DataWrapper) {
        DataWrapper dataWrapper = (DataWrapper) parentModel;
        dataModelList = dataWrapper.getDataModelList();
      }
    }

    if (dataModelList == null) {
      throw new NullPointerException("Null data model list.");
    }

    for (DataModel model : dataModelList) {
      if (!(model instanceof DataSet)) {
        JOptionPane.showMessageDialog(
            JOptionUtils.centeringComp(),
            "For the shift search, all of the data in the data box must be in the form of data sets.");
        return;
      }
    }

    final List<DataSet> dataSets = new ArrayList<DataSet>();

    for (Object aDataModelList : dataModelList) {
      dataSets.add((DataSet) aDataModelList);
    }

    SpinnerModel maxVarsModel =
        new SpinnerNumberModel(
            Preferences.userRoot().getInt("shiftSearchMaxNumShifts", 3), 1, 50, 1);
    JSpinner maxVarsSpinner = new JSpinner(maxVarsModel);
    maxVarsSpinner.setMaximumSize(maxVarsSpinner.getPreferredSize());

    maxVarsSpinner.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            JSpinner spinner = (JSpinner) e.getSource();
            SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
            int value = (Integer) model.getValue();
            Preferences.userRoot().putInt("shiftSearchMaxNumShifts", value);
          }
        });

    SpinnerModel maxShiftModel =
        new SpinnerNumberModel(Preferences.userRoot().getInt("shiftSearchMaxShift", 2), 1, 50, 1);
    JSpinner maxShiftSpinner = new JSpinner(maxShiftModel);
    maxShiftSpinner.setMaximumSize(maxShiftSpinner.getPreferredSize());

    maxShiftSpinner.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            JSpinner spinner = (JSpinner) e.getSource();
            SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
            int value = (Integer) model.getValue();
            Preferences.userRoot().putInt("shiftSearchMaxShift", value);
          }
        });

    JButton searchButton = new JButton("Search");
    final JButton stopButton = new JButton("Stop");

    final JTextArea textArea = new JTextArea();
    JScrollPane textScroll = new JScrollPane(textArea);
    textScroll.setPreferredSize(new Dimension(500, 200));

    searchButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent actionEvent) {
            final Thread thread =
                new Thread() {
                  public void run() {
                    textArea.setText("");
                    doShiftSearch(dataSets, textArea);
                  }
                };

            thread.start();
          }
        });

    stopButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent actionEvent) {
            if (search != null) {
              search.stop();
            }
          }
        });

    JComboBox directionBox = new JComboBox(new String[] {"forward", "backward"});
    directionBox.setSelectedItem(params.isForwardSearch() ? "forward" : "backward");
    directionBox.setMaximumSize(directionBox.getPreferredSize());

    directionBox.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent actionEvent) {
            JComboBox source = (JComboBox) actionEvent.getSource();
            String selected = (String) source.getSelectedItem();
            params.setForwardSearch("forward".equals(selected));
          }
        });

    Box b1 = Box.createVerticalBox();

    Box b2 = Box.createHorizontalBox();
    b2.add(new JLabel("Maximum number of variables in shift set is: "));
    b2.add(maxVarsSpinner);
    b2.add(Box.createHorizontalGlue());
    b1.add(b2);

    Box b3 = Box.createHorizontalBox();
    b3.add(new JLabel("Maximum "));
    b3.add(directionBox);
    b3.add(new JLabel(" shift: "));
    b3.add(maxShiftSpinner);
    b3.add(Box.createHorizontalGlue());
    b1.add(b3);

    Box b4 = Box.createHorizontalBox();
    b4.add(new JLabel("Output:"));
    b4.add(Box.createHorizontalGlue());
    b1.add(b4);

    Box b5 = Box.createHorizontalBox();
    b5.add(textScroll);
    b1.add(b5);

    Box b6 = Box.createHorizontalBox();
    b6.add(searchButton);
    b6.add(stopButton);
    b1.add(b6);

    final Box a1 = Box.createVerticalBox();

    Box a2 = Box.createHorizontalBox();
    a2.add(new JLabel("Specify the shift (positive or negative) for each variable:"));
    a2.add(Box.createHorizontalGlue());
    a1.add(a2);

    a1.add(Box.createVerticalStrut(20));

    setUpA1(dataSets, a1);

    JTabbedPane tabbedPane = new JTabbedPane();
    tabbedPane.addTab("Shift", new JScrollPane(a1));
    tabbedPane.addTab("Search", new JScrollPane(b1));

    add(tabbedPane, BorderLayout.CENTER);

    tabbedPane.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent changeEvent) {
            System.out.println("a1 shown");
            a1.removeAll();
            setUpA1(dataSets, a1);
          }
        });
  }
  public NAOCameraFeatures() {
    super(NAME, INPUT_DIM);

    // create image processor
    imageProcessorRGB = new ImageProcessorRGB(IMAGE_WIDTH, IMAGE_HEIGHT, NUM_LEVELS);
    System.out.println(
        "Original input has " + (IMAGE_WIDTH * IMAGE_HEIGHT * BITS_PER_PIXEL) + " dimensions");
    System.out.println(
        "Feature vector has "
            + ImageProcessorRGB.getFeatureVectorLength(NUM_LEVELS)
            + " dimensions");

    // set interactor parameters
    setCycleTime(CYCLE_TIME_DEFAULT);
    setInnerFeedback(false);
    setActivateClusterThreshold(2);
    setIterationCountStop(0);

    // set topology parameters
    SOINNM topology = getTopology();
    topology.setNoiseLevel(0.0); // 0.0
    topology.setUseFixedThreshold(true);
    topology.setFixedThreshold(0.1);
    topology.setAgeDead(100);
    topology.setConnectNewNodes(true);
    topology.setLambda(30);
    topology.setEdgeMaxRemoval(true);
    topology.setNodeNumSignalsMinRemoval(true);
    topology.setReduceErrorInsertion(true);
    topology.setSmallClusterRemoval(true);
    topology.setC2Param(0.01);
    topology.setC1Param(0.1);
    topology.setClusterJoining(true);
    topology.setJoinTolerance(1.0);
    topology.setUseAbsoluteJoinTolerance(true);
    topology.setJoinToleranceAbsolute(0.1);
    topology.setJoiningIterationsMax(10);

    // initialise NAO
    try {
      BufferedReader bReader = new BufferedReader(new FileReader("NAOHostPort.txt"));
      host = bReader.readLine().trim();
      port = Integer.parseInt(bReader.readLine().trim());
      bReader.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
    video = new ALVideoDeviceProxy(host, port);
    video.setParam(18, 0); // camera: 0=front, 1=bottom
    video.subscribe(NAME, RESOLUTION, COLOUR_SPACE, FPS);

    // initial adjustment
    if (CAMERA_CALIBRATION) {
      System.out.println("Performing camera calibration...");
      video.setParam(11, 1); // auto exposition (0-1)
      video.setParam(12, 1); // auto white balance (0-1)
      video.setParam(22, 1); // auto exposure correction algorithm (0-1)
      try {
        video.setParam(13, 1); // auto gain (0-1)
        video.setParam(21, 1); // exposure correction (0-1)
        video.setParam(26, 1); // auto balance (0-1)
        video.setParam(27, 128); // auto balance target (0-255)
        video.setParam(28, 128); // auto balance stable range (0-255)		
      } catch (Exception e) {
        System.out.println("Laser head camera model detected!");
      }
      // wait
      try {
        Thread.sleep(CAMERA_CALIBRATION_TIME);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    // disable automatic adjustments
    if (CAMERA_DISABLE_ADJUSTMENTS) {
      System.out.println("Disabling automatic camera adjustments...");
      video.setParam(11, 0); // auto exposition (0-1)
      video.setParam(12, 0); // auto white balance (0-1)
      video.setParam(22, 0); // auto exposure correction algorithm (0-1)
      try {
        video.setParam(13, 0); // auto gain (0-1)
        video.setParam(21, 0); // exposure correction (0-1)
        video.setParam(26, 0); // auto balance (0-1)
      } catch (Exception e) {
        System.out.println("Laser head camera model detected!");
      }
      // wait
      try {
        Thread.sleep(CAMERA_DISABLE_ADJUSTMENTS_TIME);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    // set exposure and gain manually
    if (CAMERA_MANUAL_EXPOSURE_GAIN) {
      System.out.println("Setting exposure and gain parameters...");
      try {
        video.getParam(13); // cause exception for laser head model
        video.setParam(17, 512); // set exposure (0-4096), 512
        video.setParam(6, 32); // set gain (0-255), 32
      } catch (Exception e) {
        System.out.println("Laser head camera model detected!");
        video.setParam(17, 96); // set exposure (0-512), 96
        video.setParam(6, 48); // set gain (0-255), 48
      }
    }

    // set white balance manually
    if (CAMERA_MANUAL_WHITE_BALANCE) {
      System.out.println("Setting white balance parameters...");
      try {
        video.setParam(4, 80); // red chroma (0-255), 80
        video.setParam(5, 160); // blue chroma (0-255), 160
        video.setParam(25, 64); // auto white balance green gain (0-255), 64
        video.setParam(29, 96); // balance blue (0-255), 96
        video.setParam(30, 96); // balance red (0-255), 96
        video.setParam(31, 96); // balance gain blue (0-255), 96
        video.setParam(32, 96); // balance gain red (0-255), 96
      } catch (Exception e) {
        System.out.println("Laser head camera model detected!");
      }
    }

    // start head movement
    if (MOVE_HEAD) {
      System.out.println("Starting head movement...");
      headMovement = new HeadMovement();
      headMovement.start();
    }

    // create frame
    frame = new JFrame(NAME);
    frame.setSize(600, 600);
    frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    frame.addWindowListener(
        new WindowAdapter() {
          public void windowClosing(WindowEvent evt) {
            shutdown();
          }
        });
    frame.setLocation(0, 0);
    frame.setVisible(true);

    // create panel
    panel = new JPanel();
    panel.setLayout(new BorderLayout());
    frame.add(panel);

    // create top panel
    JPanel pnTop = new JPanel();
    pnTop.setLayout(new BorderLayout());
    panel.add(pnTop, BorderLayout.PAGE_START);

    // create panel for input and output
    pnIO = new JPanel();
    pnIO.setLayout(new FlowLayout(FlowLayout.LEFT));
    pnIO.setBorder(BorderFactory.createTitledBorder("Input/Output"));

    ImagePanel ipInput = new ImagePanel(IMAGE_BLANK);
    ppInput = new PatternPanel(ipInput, "Input", "");
    pnIO.add(ppInput);

    ImagePanel ipOutput = new ImagePanel(IMAGE_BLANK);
    ppOutput = new PatternPanel(ipOutput, "Output", "");
    pnIO.add(ppOutput);

    pnTop.add(pnIO, BorderLayout.LINE_START);

    // create panel for controls
    JPanel pnControls = new JPanel();
    pnControls.setLayout(new BoxLayout(pnControls, BoxLayout.Y_AXIS));
    pnControls.setBorder(BorderFactory.createTitledBorder("Controls"));
    pnTop.add(pnControls);

    // create panel for interactor
    JPanel pnInteractor = new JPanel();
    pnInteractor.setLayout(new BoxLayout(pnInteractor, BoxLayout.X_AXIS));
    pnControls.add(pnInteractor);

    spCycleTime = new JSpinner(new SpinnerNumberModel((int) CYCLE_TIME_DEFAULT, 100, 1000, 100));
    spCycleTime.setMinimumSize(new Dimension(75, 25));
    spCycleTime.setMaximumSize(new Dimension(75, 25));
    pnInteractor.add(spCycleTime);
    JButton btCycleTime = new JButton("Set Cycle Time");
    btCycleTime.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            setCycleTime(Long.parseLong(spCycleTime.getValue().toString()));
          }
        });
    pnInteractor.add(btCycleTime);

    JPanel pnCycleStatus = new JPanel();
    pnCycleStatus.setLayout(new BoxLayout(pnCycleStatus, BoxLayout.Y_AXIS));
    pnInteractor.add(pnCycleStatus);

    lbCycleTime = new JLabel("Cycle Time: " + getCycleTime() + " ms");
    pnCycleStatus.add(lbCycleTime);

    lbCycleDuration = new JLabel("Cycle Duration: - ms");
    pnCycleStatus.add(lbCycleDuration);

    JPanel pnLearnRecall = new JPanel();
    pnLearnRecall.setLayout(new BoxLayout(pnLearnRecall, BoxLayout.X_AXIS));
    pnControls.add(pnLearnRecall);

    cbLearn = new JCheckBox("Learn");
    cbLearn.setSelected(true);
    pnLearnRecall.add(cbLearn);

    cbRecall = new JCheckBox("Recall");
    cbRecall.setSelected(true);
    cbRecall.setEnabled(false);
    pnLearnRecall.add(cbRecall);

    // create panel for topology
    JPanel pnTopology = new JPanel();
    pnTopology.setLayout(new GridLayout(1, 2));
    pnControls.add(pnTopology);

    JPanel pnTopologyStatus = new JPanel();
    pnTopologyStatus.setLayout(new BoxLayout(pnTopologyStatus, BoxLayout.Y_AXIS));
    pnTopology.add(pnTopologyStatus);

    lbNumNodes = new JLabel("Number of Nodes: " + getTopology().getNodeSet().size());
    pnTopologyStatus.add(lbNumNodes);

    lbNumEdges = new JLabel("Number of Edges: " + getTopology().getEdgeSet().size());
    pnTopologyStatus.add(lbNumEdges);

    lbNumClusters = new JLabel("Number of Clusters: " + getTopology().getClusterSet().size());
    pnTopologyStatus.add(lbNumClusters);

    JPanel pnTopologyControls = new JPanel();
    pnTopologyControls.setLayout(new BoxLayout(pnTopologyControls, BoxLayout.Y_AXIS));
    pnTopology.add(pnTopologyControls);

    fcSaveLoad = new JFileChooser();
    fcSaveLoad.setSelectedFile(new File(System.getProperty("user.dir") + "/" + NAME + ".xml"));

    JButton btClear = new JButton("Clear topology");
    btClear.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            getTopology().clear();
          }
        });
    pnTopologyControls.add(btClear);

    JButton btSave = new JButton("Save topology");
    btSave.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (fcSaveLoad.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
              fileSave = fcSaveLoad.getSelectedFile();
            }
          }
        });
    pnTopologyControls.add(btSave);

    JButton btLoad = new JButton("Load topology");
    btLoad.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (fcSaveLoad.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
              fileLoad = fcSaveLoad.getSelectedFile();
            }
          }
        });
    pnTopologyControls.add(btLoad);

    JButton btInsert = new JButton("Insert topology");
    btInsert.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (fcSaveLoad.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
              fileInsert = fcSaveLoad.getSelectedFile();
            }
          }
        });
    pnTopologyControls.add(btInsert);

    // create panel for clusters
    pnClusters = new JPanel();
    pnClusters.setBorder(BorderFactory.createTitledBorder("Clusters"));
    pnClusters.setLayout(new WrapLayout(WrapLayout.LEFT));
    JScrollPane spClusters = new JScrollPane(pnClusters);
    panel.add(spClusters);

    // update panel
    panel.updateUI();
  }
  private JToolBar makeToolBar() {
    JToolBar tool = new JToolBar();
    tool.setFloatable(false);

    // Setup the buttons
    save.setRequestFocusEnabled(false);
    tool.add(save);
    tool.addSeparator();

    JButton button;

    button = addToolButton("GameInformationFrame.CUT"); // $NON-NLS-1$
    tool.add(button);
    button = addToolButton("GameInformationFrame.COPY"); // $NON-NLS-1$
    tool.add(button);
    button = addToolButton("GameInformationFrame.PASTE"); // $NON-NLS-1$
    tool.add(button);

    tool.addSeparator();

    button = new JButton(undoManager.getUndoAction());
    button.setText("");
    button.setToolTipText(Messages.getString("GameInformationFrame.UNDO")); // $NON-NLS-1$
    tool.add(button);
    button = new JButton(undoManager.getRedoAction());
    button.setText("");
    button.setToolTipText(Messages.getString("GameInformationFrame.REDO")); // $NON-NLS-1$
    tool.add(button);

    tool.addSeparator();

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    String[] fontNames = ge.getAvailableFontFamilyNames();
    cbFonts = new JComboBox<String>(fontNames);
    cbFonts.setRequestFocusEnabled(false);
    cbFonts.setMaximumSize(cbFonts.getPreferredSize());
    cbFonts.setEditable(true);
    ActionListener lst =
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (fFamilyChange) {
              fFamilyChange = false;
              return;
            }
            editor.grabFocus();
            setSelectionAttribute(StyleConstants.Family, cbFonts.getSelectedItem().toString());
          }
        };

    cbFonts.addActionListener(lst);
    tool.add(cbFonts);
    tool.addSeparator();
    sSizes = new JSpinner(new SpinnerNumberModel(12, 1, 100, 1));
    sSizes.setRequestFocusEnabled(false);
    sSizes.setMaximumSize(sSizes.getPreferredSize());
    sSizes.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent arg0) {
            if (fSizeChange) {
              fSizeChange = false;
              return;
            }
            setSelectionAttribute(StyleConstants.Size, sSizes.getValue());
            editor.grabFocus();
          }
        });
    tool.add(sSizes);
    tool.addSeparator();

    tbBold = addToggleButton("GameInformationFrame.BOLD"); // $NON-NLS-1$
    tbBold.setRequestFocusEnabled(false);
    tool.add(tbBold);
    tbItalic = addToggleButton("GameInformationFrame.ITALIC"); // $NON-NLS-1$
    tbItalic.setRequestFocusEnabled(false);
    tool.add(tbItalic);
    tbUnderline = addToggleButton("GameInformationFrame.UNDERLINE"); // $NON-NLS-1$
    tbUnderline.setRequestFocusEnabled(false);
    tool.add(tbUnderline);

    tool.addSeparator();

    tbLeft = addToggleButton("GameInformationFrame.ALIGN_LEFT"); // $NON-NLS-1$
    tbLeft.setRequestFocusEnabled(false);
    tbLeft.setSelected(true);
    tool.add(tbLeft);
    tbCenter = addToggleButton("GameInformationFrame.ALIGN_CENTER"); // $NON-NLS-1$
    tbCenter.setRequestFocusEnabled(false);
    tool.add(tbCenter);
    tbRight = addToggleButton("GameInformationFrame.ALIGN_RIGHT"); // $NON-NLS-1$
    tbRight.setRequestFocusEnabled(false);
    tool.add(tbRight);

    tool.addSeparator();

    JButton butFontColor =
        new JButton(LGM.getIconForKey("GameInformationFrame.FONTCOLOR")); // $NON-NLS-1$
    butFontColor.setRequestFocusEnabled(false);
    butFontColor.setActionCommand("GameInformationFrame.FONTCOLOR"); // $NON-NLS-1$
    butFontColor.addActionListener(this);
    butFontColor.setToolTipText(
        Messages.getString("GameInformationFrame.FONTCOLOR")); // $NON-NLS-1$
    tool.add(butFontColor);
    JButton but = new JButton(LGM.getIconForKey("GameInformationFrame.COLOR")); // $NON-NLS-1$
    but.setRequestFocusEnabled(false);
    but.setActionCommand("GameInformationFrame.COLOR"); // $NON-NLS-1$
    but.addActionListener(this);
    but.setToolTipText(Messages.getString("GameInformationFrame.COLOR")); // $NON-NLS-1$
    tool.add(but);

    return tool;
  }
  /**
   * This method is called from within the constructor to initialize the form. WARNING: Do NOT
   * modify this code. The content of this method is always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {
    java.awt.GridBagConstraints gridBagConstraints;

    panEdit = new javax.swing.JPanel();
    spnPointValue = new javax.swing.JSpinner();
    jLabel5 = new javax.swing.JLabel();
    labGwk = new javax.swing.JLabel();
    splitButton = new javax.swing.JButton();
    badGeomButton = new javax.swing.JToggleButton();
    jPanel2 = new javax.swing.JPanel();
    badGeomCorrectButton = new javax.swing.JButton();
    jPanel3 = new javax.swing.JPanel();
    lblPointValue = new javax.swing.JLabel();
    lblRoute = new javax.swing.JLabel();
    panAdd = new AddPanel();
    jLabel3 = new javax.swing.JLabel();
    panError = new javax.swing.JPanel();
    lblError = new javax.swing.JLabel();

    setEnabled(false);
    setOpaque(false);
    setLayout(new java.awt.CardLayout());

    panEdit.setOpaque(false);
    panEdit.setLayout(new java.awt.GridBagLayout());

    spnPointValue.setModel(new javax.swing.SpinnerNumberModel(0.0d, 0.0d, 0.0d, 1.0d));
    spnPointValue.setEditor(new javax.swing.JSpinner.NumberEditor(spnPointValue, "###"));
    spnPointValue.setMaximumSize(new java.awt.Dimension(100, 28));
    spnPointValue.setMinimumSize(new java.awt.Dimension(100, 28));
    spnPointValue.setPreferredSize(new java.awt.Dimension(100, 28));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 1;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
    panEdit.add(spnPointValue, gridBagConstraints);

    jLabel5.setIcon(
        new javax.swing.ImageIcon(
            getClass()
                .getResource(
                    "/de/cismet/cids/custom/objecteditors/wrrl_db_mv/station.png"))); // NOI18N
    jLabel5.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.jLabel5.text")); // NOI18N
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
    panEdit.add(jLabel5, gridBagConstraints);

    labGwk.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
    labGwk.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.labGwk.text_1")); // NOI18N
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 6;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    gridBagConstraints.weightx = 1.0;
    gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
    panEdit.add(labGwk, gridBagConstraints);

    splitButton.setIcon(
        new javax.swing.ImageIcon(
            getClass()
                .getResource(
                    "/de/cismet/cids/custom/objecteditors/wrrl_db_mv/sql-join-left.png"))); // NOI18N
    splitButton.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.splitButton.text")); // NOI18N
    splitButton.setToolTipText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.splitButton.toolTipText")); // NOI18N
    splitButton.addActionListener(
        new java.awt.event.ActionListener() {

          @Override
          public void actionPerformed(final java.awt.event.ActionEvent evt) {
            splitButtonActionPerformed(evt);
          }
        });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 2;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
    panEdit.add(splitButton, gridBagConstraints);

    badGeomButton.setIcon(
        new javax.swing.ImageIcon(
            getClass()
                .getResource(
                    "/de/cismet/cids/custom/objecteditors/wrrl_db_mv/exclamation.png"))); // NOI18N
    badGeomButton.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.badGeomButton.text")); // NOI18N
    badGeomButton.setToolTipText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.badGeomButton.toolTipText")); // NOI18N
    badGeomButton.addActionListener(
        new java.awt.event.ActionListener() {

          @Override
          public void actionPerformed(final java.awt.event.ActionEvent evt) {
            badGeomButtonActionPerformed(evt);
          }
        });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 3;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
    panEdit.add(badGeomButton, gridBagConstraints);

    jPanel2.setMaximumSize(new java.awt.Dimension(32, 0));
    jPanel2.setMinimumSize(new java.awt.Dimension(32, 0));
    jPanel2.setOpaque(false);
    jPanel2.setPreferredSize(new java.awt.Dimension(32, 0));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 4;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    panEdit.add(jPanel2, gridBagConstraints);

    badGeomCorrectButton.setIcon(
        new javax.swing.ImageIcon(
            getClass()
                .getResource(
                    "/de/cismet/cids/custom/objecteditors/wrrl_db_mv/node-delete.png"))); // NOI18N
    badGeomCorrectButton.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.badGeomCorrectButton.text")); // NOI18N
    badGeomCorrectButton.setToolTipText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.badGeomCorrectButton.toolTipText")); // NOI18N
    badGeomCorrectButton.addActionListener(
        new java.awt.event.ActionListener() {

          @Override
          public void actionPerformed(final java.awt.event.ActionEvent evt) {
            badGeomCorrectButtonActionPerformed(evt);
          }
        });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 4;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
    panEdit.add(badGeomCorrectButton, gridBagConstraints);

    jPanel3.setMaximumSize(new java.awt.Dimension(32, 0));
    jPanel3.setMinimumSize(new java.awt.Dimension(32, 0));
    jPanel3.setOpaque(false);
    jPanel3.setPreferredSize(new java.awt.Dimension(32, 0));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 3;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    panEdit.add(jPanel3, gridBagConstraints);

    lblPointValue.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    lblPointValue.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.lblPointValue.text_1")); // NOI18N
    lblPointValue.setBorder(javax.swing.BorderFactory.createEtchedBorder());
    lblPointValue.setMaximumSize(new java.awt.Dimension(100, 28));
    lblPointValue.setMinimumSize(new java.awt.Dimension(100, 28));
    lblPointValue.setPreferredSize(new java.awt.Dimension(100, 28));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 1;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
    panEdit.add(lblPointValue, gridBagConstraints);

    lblRoute.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
    lblRoute.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.lblRoute.text_1")); // NOI18N
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 5;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0);
    panEdit.add(lblRoute, gridBagConstraints);

    add(panEdit, "edit");

    panAdd.setOpaque(false);
    panAdd.setLayout(new java.awt.GridBagLayout());

    jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    jLabel3.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.jLabel3.text")); // NOI18N
    panAdd.add(jLabel3, new java.awt.GridBagConstraints());

    add(panAdd, "add");

    panError.setOpaque(false);
    panError.setLayout(new java.awt.GridBagLayout());

    lblError.setText(
        org.openide.util.NbBundle.getMessage(
            StationEditor.class, "StationEditor.lblError.text")); // NOI18N
    panError.add(lblError, new java.awt.GridBagConstraints());

    add(panError, "error");
  } // </editor-fold>//GEN-END:initComponents
  private JToolBar makeToolBar() {
    JToolBar tool = new JToolBar();
    tool.setFloatable(false);

    // Setup the buttons
    save.setRequestFocusEnabled(false);
    tool.add(save);

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    String[] fontNames = ge.getAvailableFontFamilyNames();
    tool.addSeparator();
    cbFonts = new JComboBox(fontNames);
    cbFonts.setRequestFocusEnabled(false);
    cbFonts.setMaximumSize(cbFonts.getPreferredSize());
    cbFonts.setEditable(true);
    ActionListener lst =
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (fFamilyChange) {
              fFamilyChange = false;
              return;
            }
            editor.grabFocus();
            setSelectionAttribute(StyleConstants.Family, cbFonts.getSelectedItem().toString());
          }
        };

    cbFonts.addActionListener(lst);
    tool.add(cbFonts);
    tool.addSeparator();
    sSizes = new JSpinner(new SpinnerNumberModel(12, 1, 100, 1));
    sSizes.setRequestFocusEnabled(false);
    sSizes.setMaximumSize(sSizes.getPreferredSize());
    sSizes.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent arg0) {
            if (fSizeChange) {
              fSizeChange = false;
              return;
            }
            setSelectionAttribute(StyleConstants.Size, sSizes.getValue());
            editor.grabFocus();
          }
        });
    tool.add(sSizes);
    tool.addSeparator();

    tbBold = new JToggleButton(LGM.getIconForKey("GameInformationFrame.BOLD")); // $NON-NLS-1$
    tbBold.setRequestFocusEnabled(false);
    lst =
        new ActionListener() {
          public void actionPerformed(ActionEvent arg0) {
            setSelectionAttribute(StyleConstants.Bold, tbBold.isSelected());
          }
        };
    tbBold.addActionListener(lst);
    tool.add(tbBold);
    tbItalic = new JToggleButton(LGM.getIconForKey("GameInformationFrame.ITALIC")); // $NON-NLS-1$
    tbItalic.setRequestFocusEnabled(false);
    lst =
        new ActionListener() {
          public void actionPerformed(ActionEvent arg0) {
            setSelectionAttribute(StyleConstants.Italic, tbItalic.isSelected());
          }
        };
    tbItalic.addActionListener(lst);
    tool.add(tbItalic);
    tbUnderline =
        new JToggleButton(LGM.getIconForKey("GameInformationFrame.UNDERLINED")); // $NON-NLS-1$
    tbUnderline.setRequestFocusEnabled(false);
    lst =
        new ActionListener() {
          public void actionPerformed(ActionEvent arg0) {
            setSelectionAttribute(StyleConstants.Underline, tbUnderline.isSelected());
          }
        };
    tbUnderline.addActionListener(lst);
    tool.add(tbUnderline);

    tool.addSeparator();
    JButton butFontColor =
        new JButton(LGM.getIconForKey("GameInformationFrame.FONTCOLOR")); // $NON-NLS-1$
    butFontColor.setRequestFocusEnabled(false);
    butFontColor.setActionCommand("GameInformationFrame.FONTCOLOR"); // $NON-NLS-1$
    butFontColor.addActionListener(this);
    tool.add(butFontColor);
    JButton but = new JButton(LGM.getIconForKey("GameInformationFrame.COLOR")); // $NON-NLS-1$
    but.setRequestFocusEnabled(false);
    but.setActionCommand("GameInformationFrame.COLOR"); // $NON-NLS-1$
    but.addActionListener(this);
    tool.add(but);
    return tool;
  }
  private JComponent getButtonPanel() {
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

    choiceType = new JComboBox<PersonTypeItem>();
    choiceType.setMaximumSize(
        new Dimension(Short.MAX_VALUE, (int) choiceType.getPreferredSize().getHeight()));
    DefaultComboBoxModel<PersonTypeItem> personTypeModel = new DefaultComboBoxModel<>();
    personTypeModel.addElement(
        new PersonTypeItem(resourceMap.getString("primaryRole.choice.text"), null)); // $NON-NLS-1$
    for (int i = 1; i < Person.T_NUM; ++i) {
      personTypeModel.addElement(
          new PersonTypeItem(Person.getRoleDesc(i, campaign.getFaction().isClan()), i));
    }
    personTypeModel.addElement(
        new PersonTypeItem(Person.getRoleDesc(0, campaign.getFaction().isClan()), 0));
    // Add "none" for generic AsTechs
    choiceType.setModel(personTypeModel);
    choiceType.setSelectedIndex(0);
    choiceType.addActionListener(
        e -> {
          personnelFilter.setPrimaryRole(((PersonTypeItem) choiceType.getSelectedItem()).id);
          updatePersonnelTable();
        });
    panel.add(choiceType);

    choiceExp = new JComboBox<PersonTypeItem>();
    choiceExp.setMaximumSize(
        new Dimension(Short.MAX_VALUE, (int) choiceType.getPreferredSize().getHeight()));
    DefaultComboBoxModel<PersonTypeItem> personExpModel = new DefaultComboBoxModel<>();
    personExpModel.addElement(
        new PersonTypeItem(resourceMap.getString("experience.choice.text"), null)); // $NON-NLS-1$
    for (int i = 0; i < 5; ++i) {
      personExpModel.addElement(new PersonTypeItem(SkillType.getExperienceLevelName(i), i));
    }
    choiceExp.setModel(personExpModel);
    choiceExp.setSelectedIndex(0);
    choiceExp.addActionListener(
        e -> {
          personnelFilter.setExpLevel(((PersonTypeItem) choiceExp.getSelectedItem()).id);
          updatePersonnelTable();
        });
    panel.add(choiceExp);

    choiceSkill = new JComboBox<String>();
    choiceSkill.setMaximumSize(
        new Dimension(Short.MAX_VALUE, (int) choiceSkill.getPreferredSize().getHeight()));
    DefaultComboBoxModel<String> personSkillModel = new DefaultComboBoxModel<>();
    personSkillModel.addElement(choiceNoSkill);
    for (String skill : SkillType.getSkillList()) {
      personSkillModel.addElement(skill);
    }
    choiceSkill.setModel(personSkillModel);
    choiceSkill.setSelectedIndex(0);
    choiceSkill.addActionListener(
        e -> {
          if (choiceNoSkill.equals(choiceSkill.getSelectedItem())) {
            personnelFilter.setSkill(null);
            ((SpinnerNumberModel) skillLevel.getModel()).setMaximum(10);
            buttonSpendXP.setEnabled(false);
          } else {
            String skillName = (String) choiceSkill.getSelectedItem();
            personnelFilter.setSkill(skillName);
            int maxSkillLevel = SkillType.getType(skillName).getMaxLevel();
            int currentLevel = (Integer) skillLevel.getModel().getValue();
            ((SpinnerNumberModel) skillLevel.getModel()).setMaximum(maxSkillLevel);
            if (currentLevel > maxSkillLevel) {
              skillLevel.getModel().setValue(Integer.valueOf(maxSkillLevel));
            }
            buttonSpendXP.setEnabled(true);
          }
          updatePersonnelTable();
        });
    panel.add(choiceSkill);

    panel.add(Box.createRigidArea(new Dimension(10, 10)));
    panel.add(new JLabel(resourceMap.getString("targetSkillLevel.text"))); // $NON-NLS-1$

    skillLevel = new JSpinner(new SpinnerNumberModel(10, 0, 10, 1));
    skillLevel.setMaximumSize(
        new Dimension(Short.MAX_VALUE, (int) skillLevel.getPreferredSize().getHeight()));
    skillLevel.addChangeListener(
        e -> {
          personnelFilter.setMaxSkillLevel((Integer) skillLevel.getModel().getValue());
          updatePersonnelTable();
        });
    panel.add(skillLevel);

    allowPrisoners = new JCheckBox(resourceMap.getString("allowPrisoners.text")); // $NON-NLS-1$
    allowPrisoners.setHorizontalAlignment(SwingConstants.LEFT);
    allowPrisoners.setMaximumSize(
        new Dimension(Short.MAX_VALUE, (int) allowPrisoners.getPreferredSize().getHeight()));
    allowPrisoners.addChangeListener(
        e -> {
          personnelFilter.setAllowPrisoners(allowPrisoners.isSelected());
          updatePersonnelTable();
        });
    JPanel allowPrisonersPanel = new JPanel(new GridLayout(1, 1));
    allowPrisonersPanel.setAlignmentY(JComponent.LEFT_ALIGNMENT);
    allowPrisonersPanel.add(allowPrisoners);
    allowPrisonersPanel.setMaximumSize(
        new Dimension(Short.MAX_VALUE, (int) allowPrisonersPanel.getPreferredSize().getHeight()));
    panel.add(allowPrisonersPanel);

    panel.add(Box.createVerticalGlue());

    matchedPersonnelLabel = new JLabel(""); // $NON-NLS-1$
    matchedPersonnelLabel.setMaximumSize(
        new Dimension(Short.MAX_VALUE, (int) matchedPersonnelLabel.getPreferredSize().getHeight()));
    panel.add(matchedPersonnelLabel);

    JPanel buttons = new JPanel(new FlowLayout());
    buttons.setMaximumSize(
        new Dimension(Short.MAX_VALUE, (int) buttons.getPreferredSize().getHeight()));

    buttonSpendXP = new JButton(resourceMap.getString("spendXP.text")); // $NON-NLS-1$
    buttonSpendXP.setEnabled(false);
    buttonSpendXP.addActionListener(e -> spendXP());
    buttons.add(buttonSpendXP);

    JButton button = new JButton(resourceMap.getString("close.text")); // $NON-NLS-1$
    button.addActionListener(e -> setVisible(false));
    buttons.add(button);

    panel.add(buttons);

    panel.setMaximumSize(new Dimension((int) panel.getPreferredSize().getWidth(), Short.MAX_VALUE));
    panel.setMinimumSize(new Dimension((int) panel.getPreferredSize().getWidth(), 300));

    return panel;
  }
  @Analyzer(
      name = "Event Data Attribute Visualizer",
      names = {"Log"})
  public JComponent analyze(LogReader log) {
    /*
     * this plugin takes a log, shows a list of available data-attributes
     * and a list of cases After selecting a data-attribute (and possibly a
     * case) a graph is made of the value of the data-attribute against
     * either time or against the sequence of events.
     *
     * input: log with data attributes gui-input: select a data-attribute,
     * choose time or event-sequence, and possibly a case
     *
     * internally : if not caseselected -> scatterplot of values against
     * time/event-number else show graph for value against time/event-number
     *
     * createGraph : check number / string
     */
    mylog = log;
    mainPanel = new JPanel();
    mainPanel.setLayout(new BorderLayout());

    chartPanel = new JPanel();
    chartPanel.setLayout(new BoxLayout(chartPanel, BoxLayout.PAGE_AXIS));

    optionsPanel = new JPanel();
    optionsPanel.setLayout(new SpringLayout());

    JLabel attributelabel = new JLabel("Select attributes to use");
    attributeslist = new JList(getAttributes());
    attributeslist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    attributeslist.setLayoutOrientation(JList.VERTICAL);
    optionsPanel.add(attributelabel);
    optionsPanel.add(attributeslist);

    JLabel xlabel = new JLabel("Chart type");
    String[] xvalues = new String[4];
    xvalues[0] = " Attribute values against event sequence";
    xvalues[1] = "Attribute values against timestamps";
    xvalues[2] = "Average attribute values against event sequence";
    xvalues[3] = "Average attribute values against timestamps";
    xbox = new JComboBox(xvalues);
    xbox.setMaximumSize(xbox.preferredSize());
    xbox.setSelectedIndex(1);

    xbox.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            JComboBox cb = (JComboBox) e.getSource();
            if (cb.getSelectedIndex() == 3) {
              BSpinner.setVisible(true);
            } else {
              BSpinner.setVisible(false);
            }
          };
        });

    optionsPanel.add(xlabel);
    optionsPanel.add(xbox);

    JLabel timelabel = new JLabel("show time by ");
    String[] timevalues = new String[4];
    timevalues[0] = "second";
    timevalues[1] = "minute";
    timevalues[2] = "hour";
    timevalues[3] = "day";
    timebox = new JComboBox(timevalues);
    timebox.setMaximumSize(timebox.preferredSize());
    timebox.setSelectedIndex(1);
    optionsPanel.add(timelabel);
    optionsPanel.add(timebox);

    SpinnerModel Bmodel = new SpinnerNumberModel(10, 2, 1000000, 1);
    BSpinner = new JSpinner(Bmodel);
    JLabel BLabel = new JLabel("Select histogram barsize");
    JLabel B2Label = new JLabel("used for average against timestamps");
    BSpinner.setMaximumSize(BSpinner.preferredSize());
    BSpinner.setVisible(false);
    optionsPanel.add(BLabel);
    optionsPanel.add(B2Label);
    optionsPanel.add(BSpinner);

    JButton updatebutton = new JButton("update");
    updatebutton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {

            Object[] sels = attributeslist.getSelectedValues();
            String[] els = new String[sels.length];
            for (int i = 0; i < sels.length; i++) {
              els[i] = sels[i].toString();
            }

            long timesize = 1000;
            switch (timebox.getSelectedIndex()) {
              case 0:
                timesize = 1000;
                break;
              case 1:
                timesize = 1000 * 60;
                break;
              case 2:
                timesize = 1000 * 60 * 60;
                break;
              case 3:
                timesize = 1000 * 60 * 60 * 24;
                break;
            }

            String xname = null;
            JFreeChart mychart = null;
            if (xbox.getSelectedIndex() == 0) {
              data = getDataAttributes(els, false, timesize);
              xname = "Event sequence";
              mychart =
                  ChartFactory.createScatterPlot(
                      "Scatterplot of all values",
                      xname,
                      "attribute value",
                      data,
                      PlotOrientation.VERTICAL,
                      true,
                      true,
                      false);
            } else if (xbox.getSelectedIndex() == 1) {
              data = getDataAttributes(els, true, timesize);
              xname = "Time(" + timebox.getSelectedItem() + ") since beginning of the process";
              mychart =
                  ChartFactory.createScatterPlot(
                      "Scatterplot of all values",
                      xname,
                      "attribute value",
                      data,
                      PlotOrientation.VERTICAL,
                      true,
                      true,
                      false);
            } else if (xbox.getSelectedIndex() == 2) {
              xname = "Event sequence";
              data = getHistrogrammedDataAttributes(els, 1, 1);
              mychart =
                  ChartFactory.createXYLineChart(
                      "Average values",
                      xname,
                      "attribute value",
                      data,
                      PlotOrientation.VERTICAL,
                      true,
                      true,
                      false);
              mychart.setBackgroundPaint(Color.white);
              XYPlot plot = mychart.getXYPlot();

              plot.setBackgroundPaint(Color.white);
              plot.setDomainGridlinePaint(Color.white);
              plot.setRangeGridlinePaint(Color.white);

              DeviationRenderer renderer = new DeviationRenderer(true, true);
              renderer.setSeriesStroke(
                  0, new BasicStroke(3.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
              renderer.setSeriesStroke(0, new BasicStroke(2.0f));
              renderer.setSeriesStroke(1, new BasicStroke(2.0f));
              renderer.setSeriesStroke(2, new BasicStroke(2.0f));
              renderer.setSeriesStroke(3, new BasicStroke(2.0f));
              renderer.setSeriesFillPaint(0, Color.red);
              renderer.setSeriesFillPaint(1, Color.blue);
              renderer.setSeriesFillPaint(2, Color.green);
              renderer.setSeriesFillPaint(3, Color.orange);
              plot.setRenderer(renderer);
              // change the auto tick unit selection to integer units
              // only...
              NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
              // yAxis.setAutoRangeIncludesZero(false);
              yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

              NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();
              xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
            } else {
              xname = "Time(" + timebox.getSelectedItem() + "s) since beginning of the process";
              data =
                  getHistrogrammedDataAttributes(
                      els, ((Integer) BSpinner.getValue()) * timesize, timesize);
              mychart =
                  ChartFactory.createXYLineChart(
                      "Average values",
                      xname,
                      "attribute value",
                      data,
                      PlotOrientation.VERTICAL,
                      true,
                      true,
                      false);
              mychart.setBackgroundPaint(Color.white);
              XYPlot plot = mychart.getXYPlot();

              plot.setBackgroundPaint(Color.white);
              plot.setDomainGridlinePaint(Color.white);
              plot.setRangeGridlinePaint(Color.white);

              DeviationRenderer renderer = new DeviationRenderer(true, true);
              renderer.setSeriesStroke(
                  0, new BasicStroke(3.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
              renderer.setSeriesStroke(0, new BasicStroke(2.0f));
              renderer.setSeriesStroke(1, new BasicStroke(2.0f));
              renderer.setSeriesStroke(2, new BasicStroke(2.0f));
              renderer.setSeriesStroke(3, new BasicStroke(2.0f));
              renderer.setSeriesFillPaint(0, Color.red);
              renderer.setSeriesFillPaint(1, Color.blue);
              renderer.setSeriesFillPaint(2, Color.green);
              renderer.setSeriesFillPaint(3, Color.orange);
              plot.setRenderer(renderer);
              // change the auto tick unit selection to integer units
              // only...
              NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
              // yAxis.setAutoRangeIncludesZero(false);
              yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
            }

            ChartPanel mychartpanel = new ChartPanel(mychart);
            mychartpanel.setBackground(Color.white);
            chartPanel.removeAll();
            chartPanel.add(mychartpanel);
            chartPanel.updateUI();
          };
        });
    optionsPanel.add(updatebutton);

    JSplitPane splitPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, optionsPanel, chartPanel);

    SpringUtils.makeCompactGrid(
        optionsPanel,
        10,
        1, // rows, cols
        6,
        2, // initX, initY
        6,
        2); // xPad, yPad

    mainPanel.add(splitPanel, BorderLayout.CENTER);
    return mainPanel;
  }