- /*
- *
- */
- package framework.ui;
- import java.awt.Color;
- import java.awt.Component;
- import java.awt.event.ActionEvent;
- import java.awt.event.FocusEvent;
- import java.awt.event.FocusListener;
- import java.awt.event.KeyEvent;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import javax.swing.AbstractAction;
- import javax.swing.Action;
- import javax.swing.BorderFactory;
- import javax.swing.JButton;
- import javax.swing.JCheckBox;
- import javax.swing.JComboBox;
- import javax.swing.JEditorPane;
- import javax.swing.JFileChooser;
- import javax.swing.JLabel;
- import javax.swing.JMenuItem;
- import javax.swing.JOptionPane;
- import javax.swing.JPanel;
- import javax.swing.JScrollPane;
- import javax.swing.ListSelectionModel;
- import javax.swing.event.ListSelectionEvent;
- import javax.swing.event.ListSelectionListener;
- import javax.swing.table.DefaultTableModel;
- import javax.swing.table.TableCellRenderer;
- import javax.swing.table.TableModel;
- import org.jdesktop.swingx.JXTable;
- import org.jfree.ui.ExtensionFileFilter;
- import framework.data.Current;
- import framework.data.Result;
- import framework.data.ResultIOManager;
- import framework.data.Tuple;
- import framework.data.Data.DataObject;
- import framework.exceptions.NonFittingResultException;
- import framework.exceptions.UnsupportedFileVersionException;
- import framework.visualization.PlotContainer;
- import framework.visualization.PlotData;
- import framework.visualization.Plotter;
- import framework.visualization.VisualizationFrame;
- /**
- * This class implements a base framework tab that provides OM result management
- * functionality for the static Current class, including the ability to start
- * visualization of results as well as result import and export.
- *
- * @author Rene Glebke, Matthias Hannen
- */
- public final class VisualizationTab extends Tab implements FocusListener {
- /** Table listing the attributes of the dataset. */
- private JXTable attributesTable = null;
- /** Table listing the selected data. */
- private JXTable dataTable = null;
- /** The table model for the algorithm parameters table. */
- private final DefaultTableModel algoParamTableModel = new DefaultTableModel(new String[] { "Parameter", "Value" },
- 0) {
- };
- /** The table model for the result attributes table. */
- private final DefaultTableModel attributesTableModel = new DefaultTableModel(new String[] { "Attribute" }, 0) {
- };
- /** The table model for the data table. */
- private DefaultTableModel dataTableModel = new DefaultTableModel(new String[] { "No data selected..." }, 0) {
- };
- /** Combobox listing the currently available results. */
- private JComboBox resultChooser;
- /** Combobox listing the currently available results for the combined XYPlot. */
- private JComboBox resultChooser2;
- /** Combox listing the currently available evaluation results. */
- private JComboBox evalChooser;
- /** Combobox listing the available types of Plots. */
- public static JComboBox vizTypeChooser;
- /** ComboBox to activate plotting a combined XYPlot. */
- private JCheckBox combinedPlotCB;
- /** Little legend for the dataTable. */
- private JEditorPane legend = new JEditorPane();
- /** The extended plotter. */
- private Plotter plotter = new Plotter();
- public boolean sameDataset = false;
- /**
- * Creates the result management and visualization tab.
- *
- * @param title The title of the tab
- */
- public VisualizationTab(String title) {
- super(title, getHelp("help/visualization.html"));
- String[] labelItem = { "No results..." };
- String[] vizTypes = { "Select Plottype", "XYPlot", "BoxPlot" };
- JPanel mainPanel = new JPanel();
- JPanel mainPanel2 = new JPanel();
- JPanel resultPanel = new JPanel();
- JPanel visualizationPanel = new JPanel();
- JPanel dataPanel = new JPanel();
- JXTable algoParamTable = new JXTable(algoParamTableModel);
- attributesTable = new JXTable(attributesTableModel);
- dataTable = new JXTable(dataTableModel)
- {
- // Overwriting the default renderer to get coloring of specific rows
- public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
- Component c = super.prepareRenderer(renderer, row, column);
- int convertedRow = dataTable.convertRowIndexToModel(row);
- int classLabelPos = 0;
- TableModel dataTableModel = this.dataModel;
- if (dataTableModel.getColumnCount() > 1) {
- // Get the column of the classlabel
- if (sameDataset) {
- classLabelPos = dataTableModel.getColumnCount() - 3;
- }
- else {
- classLabelPos = dataTableModel.getColumnCount() - 2;
- }
- // Coloring the row red, if the classlabel marks an outlier
- if ((Double)dataTableModel.getValueAt(convertedRow, classLabelPos) != 0) {
- c.setBackground(Color.red);
- }
- // Coloring the row light red, if only the first result marks an outlier
- if ((Double)dataTableModel.getValueAt(convertedRow, classLabelPos + 1) != 0) {
- c.setBackground(new Color (255, 200, 200));
- }
- if (sameDataset) {
- if ((Double)dataTableModel.getValueAt(convertedRow, classLabelPos + 2) !=0) {
- // Coloring the row light green, if both results mark an outlier
- if ((Double)dataTableModel.getValueAt(convertedRow, classLabelPos + 1) != 0) {
- c.setBackground(new Color(204,255,204));
- }
- //Coloring the row orange, if only the second result marks an outlier
- else {
- c.setBackground(new Color(255,230,102));
- }
- }
- // Coloring the row green, if the second result and the classlabel mark an outlier
- if ((Double)dataTableModel.getValueAt(convertedRow, classLabelPos + 2) != 0 && (Double)dataTableModel.getValueAt(convertedRow, classLabelPos) != 0) {
- c.setBackground(Color.green);
- }
- }
- // Coloring the row green, if the first result and the classlabel mark an outlier
- if ((Double)dataTableModel.getValueAt(convertedRow, classLabelPos + 1) != 0 && (Double)dataTableModel.getValueAt(convertedRow, classLabelPos) != 0){
- c.setBackground(Color.green);
- }
- // Set the backgroundcolor for selected rows
- if (isRowSelected(row) && isColumnSelected(column)) {
- c.setBackground(new Color(150,150,255));
- }
- }
- return c;
- }
- };
- JScrollPane algoParamTablePane = new JScrollPane(algoParamTable);
- JScrollPane attributesTablePane = new JScrollPane(attributesTable);
- JScrollPane dataTablePane = new JScrollPane(dataTable);
- resultChooser = new JComboBox(labelItem);
- resultChooser2 = new JComboBox(labelItem);
- vizTypeChooser = new JComboBox(vizTypes);
- evalChooser = new JComboBox(labelItem);
- JButton loadResult = new JButton(loadOMResult);
- JButton saveResult = new JButton(saveOMResult);
- JButton deleteResult = new JButton(deleteOMResult);
- JButton createPlot = new JButton(createPlotFrame);
- JButton createEvalFrame = new JButton(createEvalOverview);
- JButton dispData = new JButton(showDataTable);
- JButton deleteEval = new JButton(deleteEvalResult);
- JButton extendPlotter = new JButton(loadExtendedPlotter);
- JButton showEvalPlotFrame = new JButton(showEvalPlot);
- combinedPlotCB = new JCheckBox("Create combined Plot");
- JLabel resultChooserLabel = new JLabel();
- JLabel evalChooserLabel = new JLabel();
- JLabel algoParamTableLabel = new JLabel();
- JLabel attributesTableLabel = new JLabel();
- JLabel dataTableLabel = new JLabel();
- JPanel[] panels = { mainPanel, mainPanel2, resultPanel, visualizationPanel, dataPanel };
- JEditorPane[] editorPanes = { legend };
- JScrollPane[] scrollPanes = { algoParamTablePane, attributesTablePane, dataTablePane };
- JLabel[] labels = { resultChooserLabel, algoParamTableLabel, resultChooserLabel, attributesTableLabel,
- dataTableLabel, evalChooserLabel };
- JButton[] buttons = { loadResult, saveResult, deleteResult, createPlot, createEvalFrame, dispData, deleteEval, extendPlotter, showEvalPlotFrame };
- arrangeGui(panels, editorPanes, scrollPanes, labels, buttons);
- // create menu of tab in the main window
- getMenu().add(new JMenuItem(loadOMResult));
- getMenu().add(new JMenuItem(loadExtendedPlotter));
- // Create elements of the tab.
- // Panels
- resultPanel.setBorder(BorderFactory.createTitledBorder("Outlier mining results"));
- visualizationPanel.setBorder(BorderFactory.createTitledBorder("Visualization options"));
- visualizationPanel.addFocusListener(this);
- dataPanel.setBorder(BorderFactory.createTitledBorder("Data of selected Attributes"));
- // Editorpanes
- legend.setEditable(false);
- legend.setContentType("text/html");
- legend.setBackground(VisualizationTab.this.getBackground());
- // Tables
- algoParamTableLabel.setText("Algorithm parameters:");
- algoParamTableLabel.setLabelFor(algoParamTable);
- algoParamTable.setEditable(false);
- algoParamTable.setRowSelectionAllowed(false);
- algoParamTable.setCellSelectionEnabled(false);
- attributesTableLabel.setText("Select Attributes to visualize:");
- attributesTableLabel.setLabelFor(attributesTable);
- attributesTable.setEditable(false);
- attributesTable.setRowSelectionAllowed(true);
- attributesTable.setColumnSelectionAllowed(false);
- ListSelectionModel listSM = attributesTable.getSelectionModel();
- SharedListSelectionHandler listSH = new SharedListSelectionHandler();
- listSM.addListSelectionListener(listSH);
- attributesTable.setSelectionModel(listSM);
- dataTableLabel.setText("Data of selected Attributes:");
- dataTableLabel.setLabelFor(dataTable);
- dataTable.setEditable(false);
- dataTable.setHorizontalScrollEnabled(true);
- // Comboboxes
- resultChooserLabel.setText("Available mining results:");
- resultChooserLabel.setLabelFor(resultChooser);
- resultChooser.addActionListener(resultChooserAL);
- resultChooser.addFocusListener(this);
- evalChooserLabel.setText("Available evaluation results:");
- evalChooserLabel.setLabelFor(evalChooser);
- evalChooser.addActionListener(evalChooserAL);
- resultChooser2.setEnabled(false);
- vizTypeChooser.addActionListener(vizTypeChooserAL);
- vizTypeChooser.setEnabled(false);
- // Checkboxes
- combinedPlotCB.setMnemonic(KeyEvent.VK_C);
- combinedPlotCB.setEnabled(false);
- // Add the main panel
- add(mainPanel);
- }
- /** Action to load OM results. */
- private final Action loadOMResult = new AbstractAction("Load result from file") {
- {
- setEnabled(false);
- }
- public void actionPerformed(ActionEvent e) {
- // Create a file chooser so we can open the supported files
- JFileChooser fileChooser = new JFileChooser();
- ExtensionFileFilter filter = new ExtensionFileFilter("Outlier mining result (*.omr)", ".omr");
- fileChooser.addChoosableFileFilter(filter);
- fileChooser.setAcceptAllFileFilterUsed(false);
- System.gc();
- int option = fileChooser.showOpenDialog(Application.getWindow().frame);
- // If the user didn't abort loading, try to load the result
- if (option == JFileChooser.APPROVE_OPTION) {
- String fileName = fileChooser.getSelectedFile().getPath();
- try {
- // Invoke the ResultIOManager to load the result
- ResultIOManager.loadResult(fileName);
- // Update the corresponding controls so the loaded result
- // becomes available
- updateAvailableResults();
- } catch (FileNotFoundException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame, "Cannot access selected file.",
- "File access error", JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- } catch (IOException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame,
- "Cannot load contents of selected file.", "Load error", JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- } catch (ClassNotFoundException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame,
- "Internal loading error. Try reloading or updating the program.", "Class error",
- JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- } catch (UnsupportedFileVersionException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame,
- "The format of the selected file is not supported\nby this version of the OM framework.",
- "File version error", JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- } catch (NonFittingResultException e1) {
- String errorCount = "Rows in current dataset: " + Current.data.getdataCount() + ", rows in file: "
- + e1.getRowCount() + "\n" + "Attributes in current dataset: "
- + Current.data.getAttributes().size() + ", attributes in file: " + e1.getAttributeCount();
- JOptionPane.showMessageDialog(Application.getWindow().frame,
- "The result in the selected file does not fit the current dataset.\nPlease load the appropriate dataset first.\n"
- + errorCount, "Unfitting result", JOptionPane.ERROR_MESSAGE);
- }
- }
- }
- };
- /** Action to save the current OM results. */
- private final Action saveOMResult = new AbstractAction("Save result") {
- {
- setEnabled(false);
- }
- public void actionPerformed(ActionEvent e) {
- boolean saved = false;
- // Create a file chooser so we can save into the supported files
- JFileChooser fileChooser = new JFileChooser();
- ExtensionFileFilter filter = new ExtensionFileFilter(
- "Outlier mining result (result + algorithm parameters) (*.omr)", ".omr");
- ExtensionFileFilter filter2 = new ExtensionFileFilter("Comma-separated values (result only) (*.csv)",
- ".csv");
- ExtensionFileFilter filter3 = new ExtensionFileFilter("Comma-separated values (result + dataset) (*.csv)",
- ".csv");
- fileChooser.addChoosableFileFilter(filter);
- fileChooser.addChoosableFileFilter(filter2);
- fileChooser.addChoosableFileFilter(filter3);
- fileChooser.setFileFilter(filter);
- fileChooser.setAcceptAllFileFilterUsed(false);
- while (!saved) {
- int option = fileChooser.showSaveDialog(Application.getWindow().frame);
- // If the user didn't abort the dialog, try to save or export the
- // result
- int overwrite = JOptionPane.NO_OPTION;
- if (option == JFileChooser.APPROVE_OPTION) {
- String fileName = fileChooser.getSelectedFile().getPath();
- if (fileChooser.getSelectedFile().exists()) {
- overwrite = JOptionPane.showConfirmDialog(Application.getWindow().frame, "Do you want to overwirte the exisiting File?", "", JOptionPane.YES_NO_OPTION);
- }
- else {
- overwrite = JOptionPane.YES_OPTION;
- }
- if (overwrite == JOptionPane.YES_OPTION) {
- saved = true;
- if (fileChooser.getFileFilter().equals(filter)) {
- // Save into the proprietary OMR format
- if (!fileName.endsWith(".omr")) {
- fileName = fileName + ".omr";
- }
- try {
- // Invoke the ResultIOManager to save the result
- ResultIOManager.saveResult(resultChooser.getSelectedIndex(), fileName);
- } catch (FileNotFoundException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame, "Cannot access selected file.",
- "File access error", JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- } catch (IOException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame,
- "Error saving contents into selected file.", "Save error", JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- }
- } else {
- // Export the result (optionally also the dataset) into CSV
- // format
- if (!fileName.endsWith(".csv")) {
- fileName = fileName + ".csv";
- }
- try {
- // Invoke ResultIOManager for export. If the full
- // dataset is written is dependant on the selected file
- // filter
- ResultIOManager.exportResultToCSV(resultChooser.getSelectedIndex(), fileName, fileChooser
- .getFileFilter().equals(filter3));
- } catch (FileNotFoundException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame, "Cannot access selected file.",
- "File access error", JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- } catch (IOException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame,
- "Error saving contents into selected file.", "Save error", JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- }
- }
- }
- }
- else {
- saved = true;
- }
- }
- }
- };
- /** Action to remove the currently selected result [in the resultChooser ComboBox] and suggests garbage collection. */
- private final Action deleteOMResult = new AbstractAction("Delete result") {
- {
- setEnabled(false);
- }
- public void actionPerformed(ActionEvent e) {
- if (resultChooser.getSelectedIndex() != -1) {
- if (JOptionPane.showConfirmDialog(resultChooser,
- "Are you sure you want to delete the selected mining result?", "Confirm deletion",
- JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
- // Remove the currently-selected result
- Current.results.remove(resultChooser.getSelectedIndex());
- // Update the display of available results
- updateAvailableResults();
- // Suggest garbage collection
- System.gc();
- }
- }
- }
- };
- /** Action to delete the currently selected evaluation result [in the evalChooser ComboBox] and suggests garbage collection. */
- private final Action deleteEvalResult = new AbstractAction("Delete eval. result") {
- {
- setEnabled(false);
- }
- public void actionPerformed(ActionEvent e) {
- if (evalChooser.getSelectedIndex() != -1) {
- if (JOptionPane.showConfirmDialog(evalChooser,
- "Are you sure you want to delete the selected evaluation result?", "Confirm deletion",
- JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
- // Remove the currently-selected result
- Current.results.get(resultChooser.getSelectedIndex()).delEvaluation(evalChooser.getSelectedIndex());
- // Update the display of available results
- updateAvailableResults();
- // Suggest garbage collection
- System.gc();
- }
- }
- }
- };
- /** Action to create new frame containing the selected plot. */
- private final Action createPlotFrame = new AbstractAction("Create Plot") {
- {
- setEnabled(false);
- }
- public void actionPerformed(ActionEvent e) {
- // Title of the plot
- String title = null;
- boolean run = true;
- // Collect data for the plot
- if (combinedPlotCB.isSelected()) {
- sameDataset = checkDatasets(resultChooser.getSelectedIndex(), getResultIndex(resultChooser2.getSelectedItem()));
- if (sameDataset) {
- title = "Algo 1: " + resultChooser.getSelectedItem().toString() + "\n" + "Algo 2: "
- + resultChooser2.getSelectedItem().toString();
- }
- else {
- JOptionPane.showMessageDialog(VisualizationTab.this, "The selected results are not produced with the same dataset", "Not the same dataset", JOptionPane.ERROR_MESSAGE);
- combinedPlotCB.setSelected(false);
- run = false;
- }
- } else {
- title = "Algo: " + resultChooser.getSelectedItem().toString();
- }
- if (run) {
- // Parameters need to be final for creation of the task in background
- final String ref_title = title;
- // Start calculation of plot in a task in background so the gui is still available
- Task<VisualizationFrame> t = new Task<VisualizationFrame>("Preparing results for visualization...") {
- protected VisualizationFrame doInBackground() throws Exception {
- List<PlotData> data = new ArrayList<PlotData>();
- int visType = vizTypeChooser.getSelectedIndex();
- // Create the plot
- if (combinedPlotCB.isSelected()) {
- visType = Plotter.VIS_TYPE_CXYPLOT;
- data.add(new PlotData("Result 1", Current.results.get(resultChooser.getSelectedIndex())));
- data.add(new PlotData("Result 2", Current.results.get(getResultIndex(resultChooser2.getSelectedItem()))));
- }
- else {
- data.add(new PlotData("Result", Current.results.get(resultChooser.getSelectedIndex())));
- }
- for (int i = 0; i < attributesTable.getSelectedRowCount(); i++) {
- int convertedRow = attributesTable.convertRowIndexToModel(attributesTable.getSelectedRows()[i]);
- data.add(new PlotData(attributesTableModel.getValueAt(convertedRow, 0).toString(), Current.results.get(resultChooser.getSelectedIndex()), attributesTableModel.getValueAt(convertedRow, 0).toString(),true));
- }
- if (visType < 4) {
- plotter.createPlot(ref_title, visType, data);
- }
- else {
- plotter.createPlot(ref_title, data, vizTypeChooser.getSelectedIndex() - 3);
- }
- // Finally create the frame
- VisualizationFrame frame = new VisualizationFrame(plotter.plotContainer, ref_title);
- return frame;
- }
- // Preparations done. Show the frame.
- protected void done(VisualizationFrame frame) {
- frame.setLocationRelativeTo(Application.getWindow().frame);
- frame.setVisible(true);
- }
- };
- // Execute task...
- t.execute();
- }
- }
- };
- private final Action showEvalPlot = new AbstractAction("View plot of eval.") {
- {
- setEnabled(false);
- }
- public void actionPerformed(ActionEvent e) {
- Tuple<String, Tuple<Double, PlotContainer>> evalResult = Current.results.get(resultChooser.getSelectedIndex()).getEvaluation(evalChooser.getSelectedIndex());
- VisualizationFrame frame = new VisualizationFrame(evalResult.second.second, evalResult.first);
- frame.setLocationRelativeTo(Application.getWindow().frame);
- frame.setVisible(true);
- }
- };
- /** This action updates the displayed algorithm parameters when the selection in the combo box has changed. */
- private final Action resultChooserAL = new AbstractAction("Update the displayed algorithm parameters") {
- public void actionPerformed(ActionEvent e) {
- if (Current.results.size() > 0) {
- saveOMResult.setEnabled(true);
- deleteOMResult.setEnabled(true);
- updateAlgoParamTable();
- updateAttributesTable();
- updateResultChooser2();
- updateEvalChooser();
- }
- }
- };
- /**
- * This action checks if the result of an evaluation contains a plot and activates
- * the button to show the plot, if there is one.
- */
- private final Action evalChooserAL = new AbstractAction("Open a VisualizationFrame") {
- public void actionPerformed(ActionEvent e) {
- if (evalChooser.getSelectedIndex() != -1) {
- showEvalPlot.setEnabled(evalChooser.getSelectedItem().toString().contains("Result: Plot")
- || evalChooser.getSelectedItem().toString().contains("Result 2: Plot"));
- }
- }
- };
- /** Action enables/disables the checkbox and the second resultChooser to create a combined xy-plot and enables/disables the attributesTable so the user is only able to select rows if he chooses a plot-type. */
- private final Action vizTypeChooserAL = new AbstractAction("Activate Checkbox if necessary") {
- public void actionPerformed(ActionEvent e) {
- if (vizTypeChooser.getSelectedIndex() == Plotter.VIS_TYPE_XYPLOT && resultChooser.getItemCount() > 1) {
- combinedPlotCB.setEnabled(true);
- } else {
- combinedPlotCB.setEnabled(false);
- combinedPlotCB.setSelected(false);
- }
- checkVisType(attributesTable.getSelectedRowCount());
- }
- };
- /** Action create a frame with a barplot of the evaluation results. */
- private final Action createEvalOverview = new AbstractAction("Evaluation overview") {
- {
- setEnabled(false);
- }
- public void actionPerformed(ActionEvent e) {
- plotter.createPlot("Overview of evaluation results", Plotter.VIS_TYPE_BARPLOT, null);
- VisualizationFrame frame = new VisualizationFrame(plotter.plotContainer, "Overview of evaluation results");
- frame.setLocationRelativeTo(Application.getWindow().frame);
- frame.setVisible(true);
- }
- };
- /** Action to show the data of the selected attributes [in the attributesTable] and the current OM results in the dataTable in the VisualizationTab. */
- private final Action showDataTable = new AbstractAction("Show selected data") {
- {
- setEnabled(false);
- }
- public void actionPerformed(ActionEvent e) {
- if (resultChooser2.isEnabled()) {
- sameDataset = checkDatasets(resultChooser.getSelectedIndex(), getResultIndex(resultChooser2.getSelectedItem()));
- }
- final boolean ref_sameData = sameDataset;
- // Create a task, because it could take a while to collect the data
- Task<DefaultTableModel> t = new Task<DefaultTableModel>("Getting data of selected Attributes...") {
- protected DefaultTableModel doInBackground() throws Exception {
- // Fill the tablemodel
- DefaultTableModel tableModel = updateDataTable();
- return tableModel;
- }
- protected void done(DefaultTableModel tableModel) {
- // Link the filled tablemodel to the table and activate the legend
- if (!ref_sameData && resultChooser2.isEnabled()) {
- JOptionPane.showMessageDialog(VisualizationTab.this, "The selected results are not produced with the same dataset.\n So only the result of\n " + resultChooser.getSelectedItem() + "\n will be shown.", "Not the same dataset", JOptionPane.INFORMATION_MESSAGE);
- }
- dataTable.setModel(tableModel);
- legend.setText(Tab.getHelp("help/VisualizationTabMinihelp.html"));
- }
- };
- // Execute task...
- t.execute();
- }
- };
- /** This action loads a jar-file to extend the plotter used in the visualization. */
- private final Action loadExtendedPlotter = new AbstractAction("Extend the Plotter") {
- public void actionPerformed(ActionEvent e) {
- // Create a file chooser so we can open the supported files
- JFileChooser fileChooser = new JFileChooser();
- File currentWorkPath = new File(System.getProperty("user.dir"));
- fileChooser.setCurrentDirectory(currentWorkPath);
- ExtensionFileFilter filter = new ExtensionFileFilter("Jar Files including classes (*.jar)", ".jar");
- fileChooser.addChoosableFileFilter(filter);
- fileChooser.setAcceptAllFileFilterUsed(false);
- int option = fileChooser.showOpenDialog(Application.getWindow().frame);
- // If the user didn't abort loading, try to load the file
- if (option == JFileChooser.APPROVE_OPTION) {
- File file = fileChooser.getSelectedFile();
- String fileName = file.getPath();
- try {
- plotter.addPlotType(fileName);
- } catch (FileNotFoundException e1) {
- JOptionPane.showMessageDialog(Application.getWindow().frame, "Cannot access selected file.",
- "File access error", JOptionPane.ERROR_MESSAGE);
- e1.printStackTrace();
- }
- }
- }
- };
- /**
- * Updates the whole tab if the tab gains the focus.
- *
- * @param e The event.
- *
- * @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
- */
- public void focusGained(FocusEvent e) {
- // save the selected item
- Object item = resultChooser.getSelectedItem();
- updateAvailableResults();
- // set the selected item before the update again
- resultChooser.setSelectedItem(item);
- }
- /**
- * Focus lost.
- *
- * @param e The event
- *
- * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
- */
- public void focusLost(FocusEvent e) {
- // do nothing
- }
- /**
- * Class to implement the ListSelectionListener.
- *
- * @author Matthias Hannen
- */
- class SharedListSelectionHandler implements ListSelectionListener {
- /**
- * Value changed.
- *
- * @param e The event
- *
- * @see
- * javax.swing.event.ListSelectionListener#valueChanged(javax.swing.
- * event.ListSelectionEvent)
- */
- public void valueChanged(ListSelectionEvent e) {
- ListSelectionModel lSM = (ListSelectionModel) e.getSource();
- int indexCount = 0;
- if (!(lSM.isSelectionEmpty())) {
- indexCount = attributesTable.getSelectedRowCount();
- }
- checkVisType(indexCount);
- // Activate the button, if attributes are selected
- showDataTable.setEnabled(indexCount > 0);
- // If no data is shown in the table...
- if (dataTable.getColumnCount() == 1) {
- if (indexCount > 0) {
- // Show a little hint in the table
- dataTableModel = new DefaultTableModel(new String[] { "Press 'Show selected data' to display data of selected Attributes" }, 0);
- dataTable.setModel(dataTableModel);
- }
- else {
- // If no attributes are selected, reset the table.
- dataTableModel = new DefaultTableModel(new String[] { "No data selected..." }, 0);
- dataTable.setModel(dataTableModel);
- legend.setText("");
- }
- }
- }
- }
- /**
- * Updates the content of the combobox displaying the available results.
- */
- private void updateResultChooser() {
- // Remove all items
- resultChooser.removeAllItems();
- // Get the available results
- for (int i = 0; i < Current.results.size(); i++) {
- resultChooser.addItem((i + 1) + " - " + Current.results.get(i).algorithm);
- }
- // Set the selection to the last item
- resultChooser.setSelectedIndex(resultChooser.getItemCount() - 1);
- }
- /**
- * Update the content of the second combobox displaying the available results for
- * combined XYPlots and the dataTable.
- */
- private void updateResultChooser2() {
- // If more than one result is there
- if (resultChooser.getItemCount() > 1) {
- // Remove all items
- resultChooser2.removeAllItems();
- // Get the available results except the one selected in the first resultChooser
- for (int i = 0; i < Current.results.size(); i++) {
- if (i != resultChooser.getSelectedIndex()) {
- resultChooser2.addItem((i + 1) + " - " + Current.results.get(i).algorithm);
- }
- }
- } else {
- // Remove all items, if there is just one result
- resultChooser2.removeAllItems();
- resultChooser2.addItem("No results...");
- }
- // Set the selection to the last item
- resultChooser2.setSelectedIndex(resultChooser2.getItemCount() - 1);
- }
- /**
- * Updates the content of the combobox displaying the available evaluation results for the selected result
- * in the resultChooser.
- */
- private void updateEvalChooser() {
- // If a result is selected ...
- if (resultChooser.getSelectedIndex() != -1) {
- int algo = resultChooser.getSelectedIndex();
- // Remove all items
- evalChooser.removeAllItems();
- // If there is a evaluation result
- if (Current.results.get(algo).getNumberEvaluations() > 0) {
- // Activate the button to delete it
- deleteEvalResult.setEnabled(true);
- // Get the result
- for (int i = 0; i < Current.results.get(algo).getNumberEvaluations(); i++) {
- Tuple<String, Tuple<Double, PlotContainer>> evalResult = Current.results.get(algo).getEvaluation(i);
- if (evalResult.second.first != null && evalResult.second.second != null) {
- evalChooser.addItem(i + 1 + " - " + evalResult.first + " - Result 1: " + evalResult.second.first + " - Result 2: Plot");
- }
- else {
- if (evalResult.second.first != null) {
- evalChooser.addItem(i + 1 + " - " + evalResult.first + " - Result: " + evalResult.second.first);
- }
- else {
- evalChooser.addItem(i + 1 + " - " + evalResult.first + " - Result: Plot");
- }
- }
- }
- } else {
- // If there is no evaluation result, rest the combobox
- evalChooser.removeAllItems();
- evalChooser.addItem("No results...");
- deleteEvalResult.setEnabled(false);
- }
- // Set selection to the last item
- evalChooser.setSelectedIndex(evalChooser.getItemCount() - 1);
- }
- }
- /**
- * Updates the displayed algorithm parameters.
- */
- private void updateAlgoParamTable() {
- // Remove all the old parameters
- for (int i = algoParamTableModel.getRowCount() - 1; i >= 0; i--) {
- algoParamTableModel.removeRow(i);
- }
- // Iterate through the parameters of the selected result and add them to
- // the table
- if (resultChooser.getSelectedIndex() != -1) {
- for (Map.Entry<String, Double> entry : Current.results.get(resultChooser.getSelectedIndex()).parameters
- .entrySet()) {
- algoParamTableModel.addRow(new Object[] { entry.getKey(), entry.getValue() });
- }
- }
- }
- /**
- * Update the displayed attributes.
- */
- private void updateAttributesTable() {
- // Remove all rows
- for (int i = attributesTableModel.getRowCount() - 1; i >= 0; i--) {
- attributesTableModel.removeRow(i);
- }
- // If a result is selected
- if (resultChooser.getSelectedIndex() != -1) {
- // Get the attributes of the result
- for (int i = 0; i < Current.results.get(resultChooser.getSelectedIndex()).data.getAttributes().size(); i++) {
- attributesTableModel.addRow(new Object[] { Current.results.get(resultChooser.getSelectedIndex()).data
- .getAttributes().get(i).toString() });
- }
- }
- // Set the dataTable to the default content
- showDataTable.setEnabled(false);
- dataTableModel = new DefaultTableModel(new String[] { "No data selected..." }, 0);
- dataTable.setModel(dataTableModel);
- legend.setText("");
- }
- /**
- * Update this displayed data of selected attributes.
- *
- * @return the default table model
- */
- private DefaultTableModel updateDataTable() {
- // Count of selected attributes
- int dim = attributesTable.getSelectedRowCount();
- // The row that will be added to the dataTable
- Double[] newRow = new Double[dim+2];
- // Count of elements in one new row
- int rowCount = 0;
- // Vars for the second result, if available
- Result result2 = null;
- Iterator<Map.Entry<DataObject, Float>> it = null;
- Entry<DataObject, Float> currentEntry2 = null;
- // New tablemodel to fill
- DefaultTableModel tableModel = new DefaultTableModel();
- // Just to be sure...
- if (Current.results.size() > 0) {
- if (dim > 0) {
- // Add the Columns
- for (int i = 0; i < dim; i++) {
- int convertedRow = attributesTable.convertRowIndexToModel(attributesTable.getSelectedRows()[i]);
- tableModel.addColumn(attributesTableModel.getValueAt(convertedRow, 0).toString());
- rowCount++;
- }
- // Those columns will be in every table
- tableModel.addColumn("ClassLabel");
- tableModel.addColumn("Result");
- // If there is a second result, add a column for it and set result2 to iterate through it
- if (sameDataset) {
- newRow = new Double[dim+3];
- tableModel.addColumn("Result 2");
- result2 = Current.results.get(getResultIndex(resultChooser2.getSelectedItem()));
- it = result2.iterator();
- }
- // Just to be sure... again?! WTH?! ... Never mind ;)
- if (resultChooser.getSelectedIndex() != -1) {
- // Get the first result
- Result result = Current.results.get(resultChooser.getSelectedIndex());
- // Iterate through the first result
- for (Entry<DataObject, Float> currentEntry : result) {
- // Fill the new row with the data of the attributes
- for (int i = 0; i < rowCount; i++) {
- int convertedRow = attributesTable.convertRowIndexToModel(attributesTable.getSelectedRows()[i]);
- newRow[i] = currentEntry.getKey().get(attributesTableModel.getValueAt(convertedRow, 0).toString());
- }
- // Add the classlabel to the new row
- newRow[rowCount] = currentEntry.getKey().getclassLabel();
- // Add the first result to the new row
- newRow[rowCount+1] = currentEntry.getValue().doubleValue();
- // Iterate through the second result and add it to the new row... if it exists
- if (sameDataset && it.hasNext()) {
- currentEntry2 = it.next();
- newRow[rowCount+2] = currentEntry2.getValue().doubleValue();
- }
- // Finally add the new row to the tablemodel
- tableModel.addRow(newRow);
- }
- }
- }
- }
- // return the filled tablemodel and it will be linked with the dataTable
- return tableModel;
- }
- /**
- * Loads the available OM results into the result manager. Call this method
- * whenever a result is added, edited or removed or if any other changes
- * have been made to the Current working set.
- */
- private void updateAvailableResults() {
- // Activate the load button, if data is already loaded
- loadOMResult.setEnabled(Current.data != null);
- // If there are results available
- if (Current.results.size() > 0) {
- //Update the whole tab
- updateResultChooser();
- updateResultChooser2();
- updateAlgoParamTable();
- updateAttributesTable();
- updateEvalChooser();
- // Enable/disable buttons
- vizTypeChooser.setEnabled(true);
- combinedPlotCB.setSelected(false);
- combinedPlotCB.setEnabled(false);
- resultChooser2.setEnabled(false);
- attributesTable.setEnabled(true);
- // Clear the selection in the attributesTable
- attributesTable.clearSelection();
- // Reset the vizTypeChooser
- vizTypeChooser.setSelectedIndex(0);
- // Activate resultChooser2, if there is more than one result
- if (Current.results.size() > 1) {
- resultChooser2.setEnabled(true);
- }
- // Disable the button for the evaluation overview. Will be enabled, if there is a eval result
- createEvalOverview.setEnabled(false);
- // Search for evaluation results
- for (int algo = 0; algo < resultChooser.getItemCount(); algo++) {
- for (int i = 0; i < Current.results.get(algo).getNumberEvaluations(); i++) {
- if (Current.results.get(algo).getEvaluation(i).second.first != null) {
- // Activate the button for the overview, if there are any evaluation results...
- createEvalOverview.setEnabled(true);
- }
- }
- }
- } else {
- // No results there... Reset everything to the default
- for (int i = algoParamTableModel.getRowCount() - 1; i >= 0; i--) {
- algoParamTableModel.removeRow(i);
- }
- for (int i = attributesTableModel.getRowCount() - 1; i >= 0; i--) {
- attributesTableModel.removeRow(i);
- }
- attributesTable.setEnabled(false);
- dataTableModel = new DefaultTableModel(new String[] { "No data selected..." }, 0);
- dataTable.setModel(dataTableModel);
- legend.setText("");
- resultChooser.removeAllItems();
- resultChooser.addItem("No results...");
- evalChooser.removeAllItems();
- evalChooser.addItem("No results...");
- vizTypeChooser.setSelectedIndex(0);
- vizTypeChooser.setEnabled(false);
- combinedPlotCB.setSelected(false);
- combinedPlotCB.setEnabled(false);
- resultChooser2.removeAllItems();
- resultChooser2.addItem("No results...");
- resultChooser2.setEnabled(false);
- deleteOMResult.setEnabled(false);
- saveOMResult.setEnabled(false);
- createEvalOverview.setEnabled(false);
- showDataTable.setEnabled(false);
- deleteEvalResult.setEnabled(false);
- }
- sameDataset = false;
- }
- /**
- * Checks the selected type of visualization and if the count of selected attributes is right for the type,
- * it activates the button to create a plot.
- *
- * @param indexCount Count of selected Attributes in the attributesTable
- */
- private void checkVisType(int indexCount) {
- if (vizTypeChooser.getSelectedIndex() == Plotter.VIS_TYPE_XYPLOT) {
- createPlotFrame.setEnabled(indexCount == 2);
- }
- else if (vizTypeChooser.getSelectedIndex() == Plotter.VIS_TYPE_BOXPLOT) {
- createPlotFrame.setEnabled(indexCount > 0);
- }
- else if (vizTypeChooser.getSelectedIndex() > 2) {
- int index = vizTypeChooser.getSelectedIndex() - 3;
- boolean max_infinity = (plotter.plotTypes.get(index).allowedAttrCountMax == 0);
- if (plotter.plotTypes.get(index).neededAttrCountMin > 0) {
- if (plotter.plotTypes.get(index).allowedAttrCountMax >= plotter.plotTypes.get(index).neededAttrCountMin || max_infinity) {
- createPlotFrame.setEnabled(indexCount >= plotter.plotTypes.get(index).neededAttrCountMin
- && (indexCount <= plotter.plotTypes.get(index).allowedAttrCountMax
- || max_infinity));
- }
- }
- }
- else {
- createPlotFrame.setEnabled(false);
- }
- }
- /**
- * Checks if 2 results are produced with the same dataset.
- *
- * @param index1 The index of the first result.
- * @param index2 The index of the second result.
- * @return True or false.
- */
- private boolean checkDatasets(int index1, int index2) {
- return Current.results.get(index1).data.equals(Current.results.get(index2).data);
- }
- /**
- * Converts the index of an item in the resultChooser2 to the index of the result represented by the item.
- *
- * @param item Item of the resultChooser2
- * @return Index of the result represented by the item.
- */
- private int getResultIndex(Object item) {
- int i = 0;
- for (i = 0; i < resultChooser.getItemCount() && !item.equals(resultChooser.getItemAt(i)); i++);
- return i;
- }
- /**
- * Arrange gui.
- *
- * @param panels the panels
- * @param scrollPanes the scroll panes
- * @param labels the labels
- * @param buttons the buttons
- * @param editorPanes the editor panes
- */
- private void arrangeGui(JPanel[] panels, JEditorPane[] editorPanes, JScrollPane[] scrollPanes, JLabel[] labels, JButton[] buttons) {
- // Layout of the tab... just blabla for the ui which eclipse formats
- // like a stupid moron
- // swing...stupid brainfuck
- // If you understand it, you are lucky. But you don't need to... so stop crying about missing comments!
- javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(panels[0]);
- panels[0].setLayout(mainPanelLayout);
- mainPanelLayout.setHorizontalGroup(mainPanelLayout.createParallelGroup(
- javax.swing.GroupLayout.Alignment.LEADING).addGroup(
- mainPanelLayout.createSequentialGroup().addContainerGap().addGroup(
- mainPanelLayout.createSequentialGroup().addComponent(panels[2]).addComponent(panels[3]).addComponent(panels[4]))));
- mainPanelLayout.setVerticalGroup(mainPanelLayout.createParallelGroup(
- javax.swing.GroupLayout.Alignment.LEADING).addGroup(
- mainPanelLayout.createParallelGroup().addComponent(panels[2]).addComponent(panels[3]).addComponent(panels[4])));
- javax.swing.GroupLayout dataPanelLayout = new javax.swing.GroupLayout(panels[4]);
- panels[4].setLayout(dataPanelLayout);
- dataPanelLayout.setHorizontalGroup(dataPanelLayout.createParallelGroup(
- javax.swing.GroupLayout.Alignment.LEADING).addGroup(
- dataPanelLayout.createSequentialGroup().addContainerGap().addGroup(
- dataPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(scrollPanes[2],
- javax.swing.GroupLayout.Alignment.LEADING, 0, 450, Short.MAX_VALUE).addGroup(dataPanelLayout.createSequentialGroup().addComponent(buttons[5]).addComponent(editorPanes[0])))));
- dataPanelLayout.setVerticalGroup(dataPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(
- dataPanelLayout.createSequentialGroup().addComponent(scrollPanes[2],
- javax.swing.GroupLayout.PREFERRED_SIZE, 475, javax.swing.GroupLayout.PREFERRED_SIZE).addGroup(dataPanelLayout.createParallelGroup().addComponent(buttons[5]).addComponent(editorPanes[0]))));
- javax.swing.GroupLayout resultPanelLayout = new javax.swing.GroupLayout(panels[2]);
- panels[2].setLayout(resultPanelLayout);
- resultPanelLayout
- .setHorizontalGroup(resultPanelLayout
- .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(
- resultPanelLayout
- .createSequentialGroup()
- .addContainerGap()
- .addGroup(
- resultPanelLayout
- .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
- false)
- .addComponent(labels[0])
- .addGroup(
- resultPanelLayout
- .createSequentialGroup()
- .addGap(10, 10, 10)
- .addGroup(
- resultPanelLayout
- .createParallelGroup(
- javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(
- resultPanelLayout
- .createParallelGroup(
- javax.swing.GroupLayout.Alignment.TRAILING,
- false)
- .addComponent(
- scrollPanes[0],
- javax.swing.GroupLayout.Alignment.LEADING,
- 0,
- 0,
- Short.MAX_VALUE)
- .addComponent(
- resultChooser,
- javax.swing.GroupLayout.Alignment.LEADING,
- 0,
- javax.swing.GroupLayout.DEFAULT_SIZE,
- Short.MAX_VALUE).addGroup(resultPanelLayout.createParallelGroup().addComponent(labels[5]).addComponent(evalChooser)
- .addGroup(resultPanelLayout.createSequentialGroup().addComponent(buttons[4]).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(buttons[8]).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(buttons[6]))
- .addGroup(
- javax.swing.GroupLayout.Alignment.LEADING,
- resultPanelLayout
- .createSequentialGroup()
- .addComponent(
- buttons[0])
- .addPreferredGap(
- javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(
- buttons[1])
- .addPreferredGap(
- javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(
- buttons[2]))
- .addComponent(labels[1]))))))));
- resultPanelLayout.setVerticalGroup(resultPanelLayout.createParallelGroup(
- javax.swing.GroupLayout.Alignment.LEADING).addGroup(resultPanelLayout.createSequentialGroup().addGroup(
- resultPanelLayout.createSequentialGroup().addComponent(labels[0]).addPreferredGap(
- javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(resultChooser,
- javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
- javax.swing.GroupLayout.PREFERRED_SIZE)).addGroup(resultPanelLayout.createSequentialGroup().addComponent(labels[5]).addPreferredGap(
- javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(evalChooser,
- javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
- javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addGroup(resultPanelLayout.createParallelGroup().addComponent(buttons[4]).addComponent(buttons[8]).addComponent(buttons[6])).addPreferredGap(
- javax.swing.LayoutStyle.ComponentPlacement.RELATED).addGroup(
- resultPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(
- buttons[0]).addComponent(buttons[1]).addComponent(buttons[2])).addPreferredGap(
- javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(labels[1]).addPreferredGap(
- javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(scrollPanes[0],
- javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))));
- panels[3].setBorder(javax.swing.BorderFactory.createTitledBorder("Visualization options"));
- javax.swing.GroupLayout visualizationPanelLayout = new javax.swing.GroupLayout(panels[3]);
- panels[3].setLayout(visualizationPanelLayout);
- visualizationPanelLayout
- .setHorizontalGroup(visualizationPanelLayout
- .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(
- visualizationPanelLayout
- .createSequentialGroup()
- .addContainerGap()
- .addGroup(
- visualizationPanelLayout
- .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
- false)
- .addComponent(vizTypeChooser)
- .addComponent(buttons[7])
- .addComponent(labels[3])
- .addGroup(
- visualizationPanelLayout
- .createSequentialGroup()
- .addGap(10, 10, 10)
- .addGroup(
- visualizationPanelLayout
- .createParallelGroup(
- javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(
- visualizationPanelLayout
- .createParallelGroup(
- javax.swing.GroupLayout.Alignment.TRAILING,
- false)
- .addComponent(
- scrollPanes[1],
- javax.swing.GroupLayout.Alignment.LEADING,
- 0,
- 225,
- Short.MAX_VALUE)
- .addComponent(
- combinedPlotCB)
- .addComponent(
- resultChooser2)))).addComponent(buttons[3], javax.swing.GroupLayout.DEFAULT_SIZE,
- javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))));
- visualizationPanelLayout.setVerticalGroup(visualizationPanelLayout.createParallelGroup(
- javax.swing.GroupLayout.Alignment.LEADING).addGroup(
- visualizationPanelLayout.createSequentialGroup().addComponent(vizTypeChooser).addContainerGap(5,
- 5).addComponent(buttons[7]).addContainerGap(10, 10).addComponent(labels[3])
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(
- scrollPanes[1], javax.swing.GroupLayout.PREFERRED_SIZE, 275,
- javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(
- javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(combinedPlotCB)
- .addComponent(resultChooser2).addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
- Short.MAX_VALUE).addComponent(buttons[3])));
- }
- }