From 92f8820361b6b76891f4a5e61c108a9f04fd8b7c Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Fri, 8 Sep 2017 21:23:02 +0200 Subject: [PATCH] latex export funktioniert :D --- .../Evaluation/EvaluateAlgorithms.java | 219 +++++++++++++++--- .../Presenter/Generator/DatasetGenerator.java | 14 +- .../ImportExport/EvalResultLatexExport.java | 85 +++++++ src/main/java/Presenter/Presenter.java | 40 +++- src/main/java/View/MainFrame.java | 46 +++- .../java/View/Panels/EvaluationPanel.java | 204 +++++++++++++--- src/main/java/View/Panels/MenuPanel.java | 4 +- src/main/java/View/PlotDialog.java | 5 +- .../View/custom/ButtonGroupAtLeastOne.java | 78 +++++++ .../java/View/custom/ColorColumnRenderer.java | 38 +++ 10 files changed, 647 insertions(+), 86 deletions(-) create mode 100644 src/main/java/Presenter/ImportExport/EvalResultLatexExport.java create mode 100644 src/main/java/View/custom/ButtonGroupAtLeastOne.java create mode 100644 src/main/java/View/custom/ColorColumnRenderer.java diff --git a/src/main/java/Presenter/Evaluation/EvaluateAlgorithms.java b/src/main/java/Presenter/Evaluation/EvaluateAlgorithms.java index 23d97c1..34123a0 100644 --- a/src/main/java/Presenter/Evaluation/EvaluateAlgorithms.java +++ b/src/main/java/Presenter/Evaluation/EvaluateAlgorithms.java @@ -7,8 +7,10 @@ import Presenter.Algorithms.*; import Presenter.Generator.DatasetGenerator; import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedList; import java.util.Observable; +import javax.swing.JOptionPane; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -38,19 +40,36 @@ public class EvaluateAlgorithms extends Observable { private int iterations; private int alg; - - public EvaluateAlgorithms(int type, int iterations, int alg){ + /** + * Konstruktor zur Evaluation + * @param type Typ der Evaluation + * @param n Größe des Datensatzes + * @param alg 0 = lms, + * 1 = rm, + * 2 = ts, + * 3 = lms, rm, + * 4 = lms, ts, + * 5 = rm, ts, + * 6 = lms, rm, ts, + */ + public EvaluateAlgorithms(int type, int n, int alg, String datasettyp){ this.arrangement = new LineModel(); generator = new DatasetGenerator(); - arrangement.setLines(generator.generateDataCloud()); + switch (datasettyp){ + case "Punktwolke": + arrangement.setLines(generator.generateDataCloud(n)); + break; + case "Gerade": + arrangement.setLines(generator.generateDataLines(n)); + break; + case "Kreis und Gerade": + arrangement.setLines(generator.generateCircle(n)); + break; + } this.type = type; - this.iterations = iterations; + this.iterations = n; this.alg = alg; - setChanged(); - String[] msg = {"eval-dataset-generated"}; - notifyObservers(msg); - IntersectionCounter counter = new IntersectionCounter(); counter.run(arrangement.getLines(), new Interval(-99999, 99999)); counter.calculateIntersectionAbscissas(arrangement); @@ -58,68 +77,193 @@ public class EvaluateAlgorithms extends Observable { public void run() throws InterruptedException { - ArrayList result = new ArrayList<>(); + setChanged(); + String[] msg = {"eval-dataset-generated"}; + notifyObservers(msg); + ArrayList result; + ArrayList> multipleResults = new ArrayList<>(); switch (type){ case 0: - for (int i=0;i(); + //der alg der gewählt wurde if (alg == 0) { startLMS(); result = getScaleDependentMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]); + sendPlotLineResults(lmsRes,0); } else if (alg == 1) { startRM(); result = getScaleDependentMeasure(arrangement.getLines(), rmRes[0], rmRes[1]); + sendPlotLineResults(rmRes,1); } else { startTS(); result = getScaleDependentMeasure(arrangement.getLines(), tsRes[0], tsRes[1]); + sendPlotLineResults(tsRes,2); } - } + sendTableApproximationTypes(); + sendTableApproximationData(result, alg); break; case 1: + result = new ArrayList<>(); + ArrayList lineRes; + switch (alg){ + case 3: + startLMS(); + startRM(); + + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]); + multipleResults.add(result); + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]); + multipleResults.add(result); + result = fillPseudoResults(); + multipleResults.add(result); + + lineRes = new ArrayList<>(); + lineRes.add(lmsRes); + lineRes.add(rmRes); + sendPloteLineResults(lineRes, new Integer[]{0,1}); + break; + case 4: + startLMS(); + startTS(); + + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]); + multipleResults.add(result); + result = fillPseudoResults(); + multipleResults.add(result); + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]); + multipleResults.add(result); + + lineRes = new ArrayList<>(); + lineRes.add(lmsRes); + lineRes.add(tsRes); + sendPloteLineResults(lineRes, new Integer[]{0,2}); + break; + case 5: + startRM(); + startTS(); + + result = fillPseudoResults(); + multipleResults.add(result); + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]); + multipleResults.add(result); + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]); + multipleResults.add(result); + + lineRes = new ArrayList<>(); + lineRes.add(rmRes); + lineRes.add(tsRes); + sendPloteLineResults(lineRes, new Integer[]{1,2}); + break; + case 6: + startLMS(); + startRM(); + startTS(); + + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]); + multipleResults.add(result); + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]); + multipleResults.add(result); + result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]); + multipleResults.add(result); + + lineRes = new ArrayList<>(); + lineRes.add(lmsRes); + lineRes.add(rmRes); + lineRes.add(tsRes); + sendPloteLineResults(lineRes, new Integer[]{0,1,2}); + break; + } + + sendTableApproximationData(multipleResults); break; } - //createGlobalResult(result); + + } - public void createGlobalResult(ArrayList result){ + public void sendTableApproximationData(ArrayList result, int col){ + ArrayList tableInput = new ArrayList<>(); + tableInput.add("eval-d"); + tableInput.add(""+col); + for (int i=0;i> result){ ArrayList tableInput = new ArrayList<>(); - for (int i=0;i tableInput = new ArrayList<>(); + tableInput.add("eval-t"); + tableInput.add(""+0); + for (int i=0;i lines = new ArrayList<>(); lines.add("lines-res"); + lines.add(""+alg); //lms res - lines.add(lmsRes[0]+""); - lines.add(lmsRes[1]+""); -// -// //rm res -// lines.add(rmRes[0]+""); -// lines.add(rmRes[1]+""); -// -// //ts res -// lines.add(tsRes[0]+""); -// lines.add(tsRes[1]+""); + lines.add(res[0]+""); + lines.add(res[1]+""); setChanged(); notifyObservers(lines.stream().toArray(String[]::new)); } + public void sendPloteLineResults(ArrayList res, Integer[] algs){ + ArrayList lines = new ArrayList<>(); + lines.add("lines-res-mult"); + for (int i=0;i { LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(arrangement.getLines(), arrangement.getNodes()); @@ -188,6 +332,15 @@ public class EvaluateAlgorithms extends Observable { return ret; } + private ArrayList fillPseudoResults(){ + ArrayList result = new ArrayList<>(); + result.add(" "); + result.add(" "); + result.add(" "); + result.add(" "); + return result; + } + public LinkedList getData(){ return arrangement.getLines(); diff --git a/src/main/java/Presenter/Generator/DatasetGenerator.java b/src/main/java/Presenter/Generator/DatasetGenerator.java index d00363f..54399ad 100644 --- a/src/main/java/Presenter/Generator/DatasetGenerator.java +++ b/src/main/java/Presenter/Generator/DatasetGenerator.java @@ -34,13 +34,13 @@ public class DatasetGenerator extends Observable{ } - public LinkedList generateDataCloud(){ + public LinkedList generateDataCloud(int size){ LinkedList lines = new LinkedList<>(); m = 1 + random.nextDouble(); b = random.nextDouble(); - for (int i=1;i<101;i++){ + for (int i=1;i<(size+1);i++){ double y = (random.nextGaussian() * 100) % 100; double signal = m * i + b; signal *= -1; @@ -57,9 +57,9 @@ public class DatasetGenerator extends Observable{ return lines; } - public LinkedList generateDataLines(){ + public LinkedList generateDataLines(int size){ LinkedList lines = new LinkedList<>(); - return generateDataLines(lines, 100); + return generateDataLines(lines, size); } private LinkedList generateDataLines(LinkedList lines, int n){ @@ -100,13 +100,13 @@ public class DatasetGenerator extends Observable{ } - public LinkedList generateCircle() { + public LinkedList generateCircle(int size) { LinkedList lines = new LinkedList<>(); double from = 0; double to = Math.PI * 5; //obere Grenze für die neuen Punkte - int n = 200 + lines.size(); + int n = size/2 + lines.size(); //calculate the distance between every two points double distance = (to - from) / ((double) n); @@ -129,7 +129,7 @@ public class DatasetGenerator extends Observable{ } - return generateDataLines(lines,200); + return generateDataLines(lines,size/2); } } diff --git a/src/main/java/Presenter/ImportExport/EvalResultLatexExport.java b/src/main/java/Presenter/ImportExport/EvalResultLatexExport.java new file mode 100644 index 0000000..cbb6cac --- /dev/null +++ b/src/main/java/Presenter/ImportExport/EvalResultLatexExport.java @@ -0,0 +1,85 @@ +package Presenter.ImportExport; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import javax.swing.table.DefaultTableModel; + +/** + * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. + * + * @Author: Armin Wolf + * @Email: a_wolf28@uni-muenster.de + * @Date: 08.09.2017. + */ +public class EvalResultLatexExport { + + private DefaultTableModel model; + private File file; + + public EvalResultLatexExport(DefaultTableModel model, File file ) { + this.model = model; + this.file = file; + } + + /** + * e.g. Source: https://en.wikibooks.org/wiki/LaTeX/Tables + * \begin{tabular}{l*{3}{c}} + * Team & P & W & D & L & F & A & Pts \\\hline + * Manchester United & 6 & 4 & 0 & 2 & 10 & 5 & 12 \\ + * Celtic & 6 & 3 & 0 & 3 & 8 & 9 & 9 \\ + * Benfica & 6 & 2 & 1 & 3 & 7 & 8 & 7 \\ + * FC Copenhagen & 6 & 2 & 1 & 3 & 5 & 8 & 7 \\ + * \end{tabular} + * + * + * @return + */ + private String createOutputData(){ + String split = "&"; + StringBuilder doc = new StringBuilder(); + doc.append("\\begin{tabular}{l*{3}{c}}"+"\r\n"); + doc.append("Approximationsgüte"+split+"LMS"+split+"RM"+split+"TS"+"\\\\\\hline"+"\r\n"); + + for (int i=0;i{ + JOptionPane.showMessageDialog(null,"Export war Erfolgreich!"); + }); + + + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + bufferedWriter.close(); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + +} diff --git a/src/main/java/Presenter/Presenter.java b/src/main/java/Presenter/Presenter.java index d2068aa..f5840fb 100644 --- a/src/main/java/Presenter/Presenter.java +++ b/src/main/java/Presenter/Presenter.java @@ -11,6 +11,7 @@ import Presenter.Evaluation.EvaluateAlgorithms; import Presenter.Generator.DatasetGenerator; import Presenter.ImportExport.DataExporter; import Presenter.ImportExport.DataImporter; +import Presenter.ImportExport.EvalResultLatexExport; import View.MainFrame; import javax.swing.*; @@ -19,6 +20,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Observable; import java.util.Observer; +import javax.swing.table.DefaultTableModel; /** @@ -40,6 +42,7 @@ public class Presenter implements Observer { private Thread lmsThread; private Thread importThread; private Thread exportThread; + private Thread exportResultThread; private Thread generatorThread; private Thread evalThread; @@ -57,12 +60,24 @@ public class Presenter implements Observer { SwingUtilities.invokeLater(() -> getView().addEvalDataset(eval.getData())); } - if (result[0] == "eval"){ + if (result[0] == "eval-d"){ + SwingUtilities.invokeLater(() -> getView().appendEvalResult(result,Integer.parseInt(result[1]),false)); + } + + if (result[0] == "eval-ds"){ SwingUtilities.invokeLater(() -> getView().appendEvalResult(result)); } + if (result[0] == "eval-t"){ + SwingUtilities.invokeLater(() -> getView().appendEvalResult(result,Integer.parseInt(result[1]),true)); + } + if (result[0] == "lines-res"){ - SwingUtilities.invokeLater(() -> getView().drawLineResult(result)); + SwingUtilities.invokeLater(() -> getView().drawLineResult(result, Integer.parseInt(result[1]))); + } + + if (result[0] == "lines-res-mult"){ + SwingUtilities.invokeLater(() -> getView().drawLineResults(result)); } if (result[0] == "lms"){ @@ -289,12 +304,27 @@ public class Presenter implements Observer { } } + public void startResultExport(DefaultTableModel model, File file){ + if (exportResultThread == null || !exportResultThread.isAlive()){ + exportResultThread = new Thread(()->{ + EvalResultLatexExport exporter = new EvalResultLatexExport(model, file); + exporter.writeFile(); + }); + exportResultThread.start(); + try { + exportResultThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + public void generateDataset(){ if (generatorThread == null || !generatorThread.isAlive()){ generatorThread = new Thread(() -> { DatasetGenerator generator = new DatasetGenerator(); generator.addObserver(this); - getModel().setLines(generator.generateCircle()); + getModel().setLines(generator.generateCircle(100)); calculateIntersections(); getView().enableFunctionality(); }); @@ -307,12 +337,12 @@ public class Presenter implements Observer { } } - public void startEvaluation(){ + public void startEvaluation(int typ, int n, int alg, String datasettyp){ if (evalThread == null || !evalThread.isAlive()){ evalThread = new Thread(() ->{ try { - eval = new EvaluateAlgorithms(0,1,0); + eval = new EvaluateAlgorithms(typ,n,alg,datasettyp); eval.addObserver(this); eval.run(); } catch (InterruptedException e) { diff --git a/src/main/java/View/MainFrame.java b/src/main/java/View/MainFrame.java index 0a931af..d4534d0 100644 --- a/src/main/java/View/MainFrame.java +++ b/src/main/java/View/MainFrame.java @@ -5,6 +5,8 @@ import Model.Line; import Presenter.Presenter; import View.Panels.*; +import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.LinkedList; import javax.imageio.ImageIO; import javax.swing.*; @@ -143,7 +145,7 @@ public class MainFrame extends JFrame { evaluationDialog = new JDialog(); evaluationDialog.setTitle("Evaluation"); evaluationDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); - evaluationDialog.setSize(1600,800); + evaluationDialog.setSize(1800,800); evaluationDialog.setLocationRelativeTo(null); evaluationPanel = new EvaluationPanel(this); @@ -158,19 +160,51 @@ public class MainFrame extends JFrame { } + public void appendEvalResult(Object[] res,int col, boolean isApprCol){ + SwingUtilities.invokeLater(() -> { + Object[] tmp = Arrays.asList(res).subList(2,res.length).toArray(); + if (isApprCol){ + evaluationPanel.setCurrentRow(tmp.length); + evaluationPanel.addColumn(tmp, col,true); + } else { + evaluationPanel.addColumn(tmp, col+1, false); + } + evaluationPanel.repaint(); + evaluationPanel.revalidate(); + }); + } public void appendEvalResult(Object[] res){ SwingUtilities.invokeLater(() -> { Object[] tmp = Arrays.asList(res).subList(1,res.length).toArray(); - evaluationPanel.appendData(tmp); + evaluationPanel.addRow(tmp); evaluationPanel.repaint(); evaluationPanel.revalidate(); }); } - public void drawLineResult(Object[] res){ + public void drawLineResult(Object[] res, int alg){ + SwingUtilities.invokeLater(() -> { + Object[] result = Arrays.asList(res).subList(2,res.length).toArray(); + evaluationPanel.drawLines(result, alg); + evaluationPanel.repaint(); + evaluationPanel.revalidate(); + }); + } + + public void drawLineResults(Object[] res){ SwingUtilities.invokeLater(() -> { Object[] result = Arrays.asList(res).subList(1,res.length).toArray(); - evaluationPanel.drawLines(result); + ArrayList algs = new ArrayList<>(); + + for (int i=0;i< (result.length+1) / 3;i++){ + String name = (String) result[(3*i)]; + String m = (String) result[(3*i)+1]; + String b = (String) result[(3*i)+2]; + Double[] tmp = {Double.parseDouble(name), Double.parseDouble(m), Double.parseDouble(b)}; + algs.add(tmp); + } + + evaluationPanel.drawLines(algs); evaluationPanel.repaint(); evaluationPanel.revalidate(); }); @@ -372,7 +406,9 @@ public class MainFrame extends JFrame { if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){ //System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt."); file = chooser.getSelectedFile(); - final File input = file; + String filename = file.getAbsolutePath().concat(".csv"); + File withExtension = new File(filename); + final File input = withExtension; Thread t = new Thread(() -> this.getPresenter().startExport(input)); t.start(); } diff --git a/src/main/java/View/Panels/EvaluationPanel.java b/src/main/java/View/Panels/EvaluationPanel.java index ad8ebf7..338ac18 100644 --- a/src/main/java/View/Panels/EvaluationPanel.java +++ b/src/main/java/View/Panels/EvaluationPanel.java @@ -4,25 +4,39 @@ import Model.Line; import View.MainFrame; import View.PlotDialog; +import View.custom.ButtonGroupAtLeastOne; +import java.io.File; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import javax.swing.*; +import javax.swing.border.LineBorder; import javax.swing.border.TitledBorder; +import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.DefaultTableModel; import java.awt.*; - +import javax.swing.table.JTableHeader; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; +import View.custom.ColorColumnRenderer; /** - * Created by armin on 02.08.17. + * 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 latexExport; private JRadioButton evalTypeOne; //1: Alg - N: Data private JRadioButton evalTypeTwo; //N: Alg - 1: Data private ButtonGroup radiobuttonGroup; private ButtonGroup checkboxGroup; + private ButtonGroupAtLeastOne checkboxAtLeastOne; private JCheckBox lms; //1: Alg - N: Data private JCheckBox rm; //N: Alg - 1: Data @@ -33,37 +47,46 @@ public class EvaluationPanel extends JPanel{ private JPanel leftSidePanel; private JPanel datasetCount; private JComboBox datasetCountChoice; + private JComboBox datasetType; private JLabel datasetCountLabel; private JSplitPane splitPane; private DefaultTableModel model; + private int currentRowOfTypes; private JPanel buttonPanel; private PlotDialog plotDialog; + private String[] selections = { "Approximationsgüte","Least Median of Squares","Repeated-Median","Theil-Sen"}; public EvaluationPanel(MainFrame view){ super(); this.view = view; this.setLayout(new BorderLayout()); - this.setBorder(new TitledBorder("Evaluation der Algorithmen")); + this.currentRowOfTypes = 0; init(); + addListener(); addComponents(); + } private void init(){ - datasetCountLabel = new JLabel("Anzahl der Datensätze"); - Integer[] choice = {1,2,3,4,5,6,7,8,9,10}; + 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"}; + datasetType = new JComboBox<>(datatypes); start = new JButton("Start"); - evalTypeOne = new JRadioButton("1 Algorithmus - N Datensätze"); - evalTypeTwo = new JRadioButton("N Algorithmen - 1 Datensatz"); + latexExport = new JButton("LaTex Export"); + 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 ButtonGroupAtLeastOne(); buttonPanel = new JPanel(new FlowLayout()); leftSidePanel = new JPanel(new BorderLayout()); comp = new JPanel(new GridLayout(0,1)); @@ -76,6 +99,11 @@ public class EvaluationPanel extends JPanel{ } }; 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); + splitPane = new JSplitPane(); algorithmPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); datasetCount = new JPanel(new FlowLayout(FlowLayout.LEFT)); @@ -84,24 +112,16 @@ public class EvaluationPanel extends JPanel{ private void addComponents(){ evalTypeOne.setSelected(true); + lms.setSelected(true); checkboxGroup.add(lms); checkboxGroup.add(rm); checkboxGroup.add(ts); - evalTypeOne.addActionListener(e -> { - checkboxGroup.add(lms); - checkboxGroup.add(rm); - checkboxGroup.add(ts); - }); - - evalTypeTwo.addActionListener(e -> { - checkboxGroup.remove(lms); - checkboxGroup.remove(rm); - checkboxGroup.remove(ts); - }); radiobuttonGroup.add(evalTypeOne); radiobuttonGroup.add(evalTypeTwo); + buttonPanel.add(start); + buttonPanel.add(latexExport); algorithmPanel.add(lms); algorithmPanel.add(rm); @@ -109,21 +129,19 @@ public class EvaluationPanel extends JPanel{ datasetCount.add(datasetCountLabel); datasetCount.add(datasetCountChoice); + datasetCount.add(datasetType); comp.add(evalTypeOne); comp.add(evalTypeTwo); comp.add(algorithmPanel); comp.add(datasetCount); - start.addActionListener(e -> { - view.getPresenter().startEvaluation(); - }); comp.setBorder(new TitledBorder("Konfiguration")); //Tabelle - String[] selections = { "Approximationsgüte","Theil-Sen", "Repeated-Median", "Least Median of Squares"}; + model.setColumnIdentifiers(selections); table.setDragEnabled(true); JScrollPane scrollPane = new JScrollPane(table); @@ -148,26 +166,118 @@ public class EvaluationPanel extends JPanel{ this.add(splitPane, BorderLayout.CENTER); this.add(buttonPanel, BorderLayout.SOUTH); + + TableColumn tm = table.getColumnModel().getColumn(0); + tm.setCellRenderer(new ColorColumnRenderer(Color.lightGray, Color.blue)); } + 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(); + view.getPresenter().startEvaluation(type,n,alg,datatyp); + }); - public void appendData(Object[] row){ - model.addRow(row); + 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); + }); + + latexExport.addActionListener(e -> { + SwingUtilities.invokeLater(() -> { + File file = null; + JFileChooser chooser = new JFileChooser(); + chooser.setPreferredSize(new Dimension(800,700)); + File workingDirectory = new File(System.getProperty("user.dir")); + chooser.setCurrentDirectory(workingDirectory); + chooser.setFileFilter(new FileNameExtensionFilter("LaTeX-Datei", "tex", "text")); + + chooser.setMultiSelectionEnabled(false); + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + + if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){ + //System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt."); + file = chooser.getSelectedFile(); + String filename = file.getAbsolutePath().concat(".tex"); + File withExtension = new File(filename); + final File input = withExtension; + view.getPresenter().startResultExport(model, input); + } + }); + }); + } + + public void addColumn(Object[] data, int col, boolean b){ + if (b){ + addBlankRows(data.length); + } + for (int i=0;i alg){ + Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA}; + String[] name = {"LMS","RM", "TS"}; + + for (Double[] o : alg){ + Double m = o[1]; + Double b = o[1]; + int i = o[0].intValue(); plotDialog.addLineToPlot(m,b,color[i],name[i]); } } + public void drawLines(Object[] results, int alg){ + String[] castedResults = Arrays.copyOf(results, results.length, String[].class); + Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA}; + String[] name = {"LMS","RM", "TS"}; + + Double m = Double.parseDouble(castedResults[0]); + Double b = Double.parseDouble(castedResults[1]); + plotDialog.addLineToPlot(m,b,color[alg],name[alg]); + } + public void setDualPoints(LinkedList points){ plotDialog = new PlotDialog(); plotDialog.setBorder(new TitledBorder("Plot")); @@ -176,4 +286,36 @@ public class EvaluationPanel extends JPanel{ plotDialog.repaint(); plotDialog.revalidate(); } + + private void addBlankRows(int n){ + for (int i=0;i points) { - datapoints = new XYSeriesCollection(); ArrayList coordinates = new ArrayList<>(); series = new XYSeries("points"); diff --git a/src/main/java/View/custom/ButtonGroupAtLeastOne.java b/src/main/java/View/custom/ButtonGroupAtLeastOne.java new file mode 100644 index 0000000..2622ec0 --- /dev/null +++ b/src/main/java/View/custom/ButtonGroupAtLeastOne.java @@ -0,0 +1,78 @@ +package View.custom; + +import java.util.HashSet; +import java.util.Set; +import javax.swing.AbstractButton; +import javax.swing.ButtonGroup; +import javax.swing.ButtonModel; + +/** + * Source: https://stackoverflow.com/questions/14892515/how-to-enforce-at-least-one-checkbox-in-a-group-is-selected + * + * A ButtonGroup for check-boxes enforcing that at least two remains selected. + * + * When the group has exactly two buttons, deselecting the last selected one + * automatically selects the other. + * + * When the group has more buttons, deselection of the last selected one is denied. + */ +public class ButtonGroupAtLeastOne extends ButtonGroup { + + private final Set selected = new HashSet<>(); + + @Override + public void setSelected(ButtonModel model, boolean b) { + if (b && !this.selected.contains(model) ) { + select(model, true); + } else if (!b && this.selected.contains(model)) { + if (this.buttons.size() == 3 && this.selected.size() == 2) { + select(model, false); + + AbstractButton otherOne = this.buttons.get(0).getModel() == model ? + this.buttons.get(1) : this.buttons.get(0); + + AbstractButton otherTwo = this.buttons.get(1).getModel() == model ? + this.buttons.get(2) : this.buttons.get(1); + + AbstractButton otherThree = this.buttons.get(2).getModel() == model ? + this.buttons.get(1) : this.buttons.get(2); + + + select(otherOne.getModel(), true); + select(otherTwo.getModel(), true); + select(otherThree.getModel(), true); + } else if (this.selected.size() > 2) { + this.selected.remove(model); + model.setSelected(false); + } + } + } + + private void select(ButtonModel model, boolean b) { + if (b) { + this.selected.add(model); + } else { + this.selected.remove(model); + } + model.setSelected(b); + } + + @Override + public boolean isSelected(ButtonModel m) { + return this.selected.contains(m); + } + + public void addAll(AbstractButton... buttons) { + for (AbstractButton button : buttons) { + add(button); + } + } + + @Override + public void add(AbstractButton button) { + if (button.isSelected()) { + this.selected.add(button.getModel()); + } + super.add(button); + } +} \ No newline at end of file diff --git a/src/main/java/View/custom/ColorColumnRenderer.java b/src/main/java/View/custom/ColorColumnRenderer.java new file mode 100644 index 0000000..6d2605f --- /dev/null +++ b/src/main/java/View/custom/ColorColumnRenderer.java @@ -0,0 +1,38 @@ +package View.custom; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +/** + * Source: http://esus.com/creating-a-jtable-with-a-different-background-color-per-column/ + * + * Applied background and foreground color to single column of a JTable + * in order to distinguish it apart from other columns. + */ +public class ColorColumnRenderer extends DefaultTableCellRenderer { + + Color bkgndColor, fgndColor; + + public ColorColumnRenderer(Color bkgnd, Color foregnd) { + super(); + bkgndColor = bkgnd; + fgndColor = foregnd; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, + boolean hasFocus, int row, int column) { + Component cell = super.getTableCellRendererComponent + (table, value, isSelected, hasFocus, row, column); + + cell.setBackground(bkgndColor); + cell.setForeground(fgndColor); + cell.setFont(new Font("SansSerif", Font.BOLD, 12)); + this.setHorizontalAlignment(JLabel.CENTER); + + return cell; + } +} \ No newline at end of file