package de.wwwu.awolf.view.panels; import de.wwwu.awolf.model.Line; import de.wwwu.awolf.presenter.Presenter; import de.wwwu.awolf.presenter.algorithms.Algorithm; import de.wwwu.awolf.presenter.data.DataProvider; import de.wwwu.awolf.view.MainFrame; import de.wwwu.awolf.view.custom.ButtonGroupAtLeastTwo; import javax.swing.*; import javax.swing.border.TitledBorder; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileSystemView; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import java.awt.*; import java.io.File; import java.io.Serializable; import java.util.List; import java.util.*; /** * Created by * Armin Wolf * on 02.08.17. */ public class EvaluationPanel extends JPanel { private final MainFrame view; private JTable table; private JTableHeader header; private JButton start; private JButton clearTable; private JButton exportData; private JRadioButton evalTypeOne; //1: Alg - N: Data private JRadioButton evalTypeTwo; //N: Alg - 1: Data private ButtonGroup radiobuttonGroup; private ButtonGroup checkboxGroup; private ButtonGroupAtLeastTwo checkboxAtLeastOne; private JCheckBox lms; //1: Alg - N: Data private JCheckBox rm; //N: Alg - 1: Data private JCheckBox ts; //1: Alg - N: Data private JPanel comp; private JPanel algorithmPanel; private JPanel leftSidePanel; private JPanel datasetCount; private JComboBox datasetCountChoice; private JComboBox datasetType; private JLabel datasetCountLabel; private DefaultTableModel model; private int currentRowOfTypes; private JPanel buttonPanel; private PlotPanel plotPanel; private Map colorMap; private String[] selections = {"Approximationsgüte", "Least Median of Squares", "Repeated-Median", "Theil-Sen"}; /** * Konstruktor * * @param view View */ public EvaluationPanel(MainFrame view) { super(); this.view = view; this.setLayout(new BorderLayout()); this.currentRowOfTypes = 0; this.colorMap = new HashMap<>(); this.colorMap.put(Algorithm.Type.LMS, Color.ORANGE); this.colorMap.put(Algorithm.Type.RM, Color.RED); this.colorMap.put(Algorithm.Type.TS, Color.MAGENTA); this.colorMap.put(Algorithm.Type.NAIV_LMS, Color.BLUE); this.colorMap.put(Algorithm.Type.NAIV_RM, Color.GREEN); this.colorMap.put(Algorithm.Type.NAIV_TS, Color.CYAN); init(); addListener(); addComponents(); } /** * Initialisiere die Komponenten */ private void init() { datasetCountLabel = new JLabel("Größe des Datensatzes"); Integer[] choice = {50, 100, 200, 500, 1000, 1500}; datasetCountChoice = new JComboBox(choice); String[] datatypes = {"Punktwolke", "Gerade", "Kreis und Gerade", "Import von CSV-Datei"}; datasetType = new JComboBox<>(datatypes); start = new JButton("Start"); clearTable = new JButton("Löschen"); exportData = new JButton("Datenexport"); clearTable.setEnabled(false); exportData.setEnabled(false); evalTypeOne = new JRadioButton("Algorithmus evaluieren"); evalTypeTwo = new JRadioButton("Algorithmen vergleichen"); lms = new JCheckBox("Least Median of Squares"); rm = new JCheckBox("Repeated Median"); ts = new JCheckBox("Theil-Sen"); radiobuttonGroup = new ButtonGroup(); checkboxGroup = new ButtonGroup(); checkboxAtLeastOne = new ButtonGroupAtLeastTwo(); buttonPanel = new JPanel(new FlowLayout()); leftSidePanel = new JPanel(new BorderLayout()); comp = new JPanel(new GridLayout(0, 1)); plotPanel = new PlotPanel(); model = new DefaultTableModel() { @Override public boolean isCellEditable(int row, int column) { //all cells false return false; } }; table = new JTable(model); UIManager.put("TableHeader.font", new Font("SansSerif", Font.BOLD, 14)); UIManager.put("TableHeader.foreground", Color.WHITE); header = table.getTableHeader(); header.setBackground(Color.GRAY); algorithmPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); datasetCount = new JPanel(new FlowLayout(FlowLayout.LEFT)); } /** * Hinzufügen der Komponenten zum ContentPane */ private void addComponents() { evalTypeOne.setSelected(true); lms.setSelected(true); checkboxGroup.add(lms); checkboxGroup.add(rm); checkboxGroup.add(ts); radiobuttonGroup.add(evalTypeOne); radiobuttonGroup.add(evalTypeTwo); buttonPanel.add(start); buttonPanel.add(clearTable); buttonPanel.add(exportData); algorithmPanel.add(lms); algorithmPanel.add(rm); algorithmPanel.add(ts); datasetCount.add(datasetCountLabel); datasetCount.add(datasetCountChoice); datasetCount.add(datasetType); comp.add(evalTypeOne); comp.add(evalTypeTwo); comp.add(algorithmPanel); comp.add(datasetCount); comp.setBorder(new TitledBorder("Konfiguration")); //Tabelle table.setDragEnabled(true); JScrollPane scrollPane = new JScrollPane(table); scrollPane.setWheelScrollingEnabled(true); scrollPane.setBorder(new TitledBorder("Ergebnisse")); //Plot plotPanel.createPlot(new LinkedList<>()); plotPanel.setBorder(new TitledBorder("Plot")); leftSidePanel.add(comp, BorderLayout.NORTH); leftSidePanel.add(scrollPane, BorderLayout.CENTER); this.add(leftSidePanel, BorderLayout.CENTER); this.add(buttonPanel, BorderLayout.SOUTH); } /** * Hinzufügen der Listener */ private void addListener() { start.addActionListener(e -> { int type; int alg; int n; if (radiobuttonGroup.isSelected(evalTypeOne.getModel())) { type = 0; } else { type = 1; } alg = checkSelection(); n = (Integer) datasetCountChoice.getSelectedItem(); String datatyp = (String) datasetType.getSelectedItem(); if ("Import von CSV-Datei".equals(datatyp)) { SwingUtilities.invokeLater(() -> { File file = null; JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); chooser.setPreferredSize(new Dimension(800, 700)); chooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Value, (*.csv)", "csv", "text")); chooser.setMultiSelectionEnabled(false); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { //Logging.logInfo ("Datei "+chooser.getSelectedFile()+ " ausgewählt."); file = chooser.getSelectedFile(); final File input = file; Thread t = new Thread(() -> ((Presenter) view.getPresenter()).startEvaluation(type, alg, input)); t.start(); } }); } else { ((Presenter) view.getPresenter()).startEvaluation(type, n, alg, DataProvider.DataType.values()[datasetType.getSelectedIndex()]); } clearTable.setEnabled(true); exportData.setEnabled(true); }); evalTypeOne.addActionListener(e -> { checkboxAtLeastOne.remove(lms); checkboxAtLeastOne.remove(rm); checkboxAtLeastOne.remove(ts); lms.setSelected(true); checkboxGroup.add(lms); checkboxGroup.add(rm); checkboxGroup.add(ts); }); evalTypeTwo.addActionListener(e -> { checkboxGroup.remove(lms); checkboxGroup.remove(rm); checkboxGroup.remove(ts); checkboxAtLeastOne.addAll(lms, rm, ts); lms.setSelected(true); rm.setSelected(true); }); clearTable.addActionListener(e -> { SwingUtilities.invokeLater(() -> { int n = model.getDataVector().size(); for (int i = 0; i < n; i++) { model.removeRow(0); currentRowOfTypes--; } this.revalidate(); clearTable.setEnabled(false); exportData.setEnabled(false); }); }); exportData.addActionListener(e -> { SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> { File file = null; JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); chooser.setPreferredSize(new Dimension(800, 700)); chooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Value, (*.csv)", "csv", "text")); chooser.setMultiSelectionEnabled(false); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { file = chooser.getSelectedFile(); String filename = file.getAbsolutePath().contains(".csv") ? file.getAbsolutePath() : file.getAbsolutePath().concat(".csv"); final File input = new File(filename); Thread t = new Thread(() -> ((Presenter) view.getPresenter()).startDatasetExportEvaluation(input)); t.start(); } }); }); }); } /** * Fügt der Tabelle eine Spalte hinzu * * @param data Daten der Spalte * @param col Spalte * @param isLabel true, falls es sich um die Approximations Überschriften handelt */ public void addColumn(final List data, final int col, final boolean isLabel) { if (isLabel) { addBlankRows(data.size()); } for (int i = 0; i < data.size(); i++) { int row = currentRowOfTypes - data.size() + i; model.setValueAt(data.get(i), row, col); } this.repaint(); this.revalidate(); } /** * Fügt der Tabelle eine Zeile hinzu * * @param tableEntries Daten der Tabelle */ public void addRow(Map> tableEntries) { SwingUtilities.invokeLater(() -> { Set types = tableEntries.keySet(); List columnlabels = new ArrayList<>(); types.forEach(type -> { columnlabels.add(" "); }); model.setColumnIdentifiers(columnlabels.toArray()); tableEntries.entrySet().forEach(row -> { model.addRow(row.getValue().keySet().toArray()); model.addRow(row.getValue().values().toArray()); }); this.repaint(); this.revalidate(); }); } /** *

* Visualisierung der Ausgleichsgerade * * @param lines the lines * @param alg identifizierung des Alg. */ public void drawLines(final List lines, final Algorithm.Type alg) { for (Line line : lines) { plotPanel.addLineToPlot(line.getM(), line.getB(), colorMap.get(alg), alg.name()); } } /** * Hilfsmethode * * @param n Anzahl der leeren Zeilen */ private void addBlankRows(int n) { for (int i = 0; i < n; i++) { String[] tmp = {"", "", "", "",}; model.addRow(tmp); } } /** * Hilfsmethode * * @param val Anzahl der Zeilen die noch hinzugefügt werden */ public void setCurrentRow(int val) { this.currentRowOfTypes += val; } /** * @return Kodierung welche Algorithmen ausgewählt wurden */ private int checkSelection() { if (lms.isSelected() && rm.isSelected() && ts.isSelected()) { return 6; } else if (!lms.isSelected() && rm.isSelected() && ts.isSelected()) { return 5; } else if (lms.isSelected() && !rm.isSelected() && ts.isSelected()) { return 4; } else if (lms.isSelected() && rm.isSelected() && !ts.isSelected()) { return 3; } else if (!lms.isSelected() && !rm.isSelected() && ts.isSelected()) { return 2; } else if (!lms.isSelected() && rm.isSelected() && !ts.isSelected()) { return 1; } else if (lms.isSelected() && !rm.isSelected() && !ts.isSelected()) { return 0; } else { throw new IllegalStateException("Mindestens ein Algortihmus muss selektiert werden"); } } }