From 97c326ab534047dd72a0f7e1992ae36176dda909 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Wed, 21 Jun 2017 17:41:40 +0200 Subject: [PATCH] RM fertig, Tests fehlen noch --- src/main/java/App.java | 17 ++ .../LeastMedianOfSquaresEstimator.java | 4 +- .../Algorithms/RepeatedMedianEstimator.java | 183 +++++++++++++++++- src/main/java/Presenter/Presenter.java | 43 ++-- src/main/java/View/MainFrame.java | 74 ++++--- .../{SidePanel.java => Panels/LMSPanel.java} | 13 +- .../java/View/{ => Panels}/MenuPanel.java | 2 +- .../java/View/{ => Panels}/OutputPanel.java | 10 +- src/main/java/View/Panels/RMPanel.java | 114 +++++++++++ src/main/java/View/PlotDialog.java | 13 +- 10 files changed, 412 insertions(+), 61 deletions(-) rename src/main/java/View/{SidePanel.java => Panels/LMSPanel.java} (91%) rename src/main/java/View/{ => Panels}/MenuPanel.java (97%) rename src/main/java/View/{ => Panels}/OutputPanel.java (92%) create mode 100644 src/main/java/View/Panels/RMPanel.java diff --git a/src/main/java/App.java b/src/main/java/App.java index 121b5b8..72e8791 100644 --- a/src/main/java/App.java +++ b/src/main/java/App.java @@ -1,7 +1,9 @@ import Model.Arrangement; import Presenter.Presenter; import View.MainFrame; +import java.awt.Font; import javax.swing.SwingUtilities; +import javax.swing.UIManager; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -12,12 +14,27 @@ import javax.swing.SwingUtilities; */ public class App { + private static void setUIFont(javax.swing.plaf.FontUIResource f) + { + java.util.Enumeration keys = UIManager.getDefaults().keys(); + while (keys.hasMoreElements()) + { + Object key = keys.nextElement(); + Object value = UIManager.get(key); + if (value instanceof javax.swing.plaf.FontUIResource) + { + UIManager.put(key, f); + } + } + } public static void main(String[] args) { SwingUtilities.invokeLater(() -> { MainFrame view = new MainFrame(); view.setPresenter(new Presenter(new Arrangement(), view)); + setUIFont (new javax.swing.plaf.FontUIResource(new Font("Verdana",Font.PLAIN, 12))); + }); } diff --git a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java index 18a47d3..3b96ccd 100644 --- a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java +++ b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java @@ -139,7 +139,9 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit setChanged(); double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * -0.5; double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * 0.5; - notifyObservers(new Line(m, b)); + Line result = new Line(m, b); + result.setId("lms"); + notifyObservers(result); } } diff --git a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java index 420d43e..f99f5be 100644 --- a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java +++ b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java @@ -3,10 +3,12 @@ package Presenter.Algorithms; import Model.Line; import Model.Slab; import Presenter.InversionCounter; +import Presenter.Presenter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; +import java.util.Observable; import java.util.concurrent.ThreadLocalRandom; /** @@ -16,8 +18,9 @@ import java.util.concurrent.ThreadLocalRandom; * @Email: a_wolf28@uni-muenster.de * @Date: 28.05.2017. */ -public class RepeatedMedianEstimator implements Algorithm { +public class RepeatedMedianEstimator extends Observable implements Algorithm { + private Presenter presenter; private LinkedList set; private HashMap> linePairs; private HashMap medianIntersections = new HashMap<>(); @@ -45,8 +48,9 @@ public class RepeatedMedianEstimator implements Algorithm { private Double thetaHigh; - public RepeatedMedianEstimator(LinkedList set) { + public RepeatedMedianEstimator(LinkedList set, Presenter presenter) { this.set = set; + this.presenter = presenter; interval = new Slab(-10000, 10000); n = set.size(); beta = 0.5; @@ -109,10 +113,16 @@ public class RepeatedMedianEstimator implements Algorithm { } - System.out.println( - "Ergebnis: " + thetaLow * (-1) + " * x + " + ( - (linesInCenterSlab.get(0).getM() * (thetaLow * (-1))) + linesInCenterSlab.get(0) - .getB())); + if (presenter != null) { + setChanged(); + double m = thetaLow * (-1); + double b = ( + (linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0) + .getB()); + Line result = new Line(m, b); + result.setId("rm"); + notifyObservers(result); + } } /** @@ -167,7 +177,7 @@ public class RepeatedMedianEstimator implements Algorithm { else accessIndex = (int) i; - System.out.println(accessIndex); + //System.out.println(accessIndex); return intersections.get(accessIndex); } @@ -262,7 +272,7 @@ public class RepeatedMedianEstimator implements Algorithm { } } - System.out.println("Linie: "+line.getId()+"\tLeft: "+left+"\t Center: "+center+"\t Right: "+right); + //System.out.println("Linie: "+line.getId()+"\tLeft: "+left+"\t Center: "+center+"\t Right: "+right); countLeftSlab.set(index, left); countCenterSlab.set(index, center); countRightSlab.set(index, right); @@ -322,6 +332,163 @@ public class RepeatedMedianEstimator implements Algorithm { interval.setLower(thetaHigh - 0.1); } } + + + /******************************************************************************************************************* + * Getter und Setter Methoden + ******************************************************************************************************************/ + public LinkedList getSet() { + return set; + } + + public void setSet(LinkedList set) { + this.set = set; + } + + public HashMap> getLinePairs() { + return linePairs; + } + + public void setLinePairs(HashMap> linePairs) { + this.linePairs = linePairs; + } + + public HashMap getMedianIntersections() { + return medianIntersections; + } + + public void setMedianIntersections(HashMap medianIntersections) { + this.medianIntersections = medianIntersections; + } + + public HashMap> getIntersectionAbscissas() { + return intersectionAbscissas; + } + + public void setIntersectionAbscissas( + HashMap> intersectionAbscissas) { + this.intersectionAbscissas = intersectionAbscissas; + } + + public Slab getInterval() { + return interval; + } + + public void setInterval(Slab interval) { + this.interval = interval; + } + + public ArrayList getCountLeftSlab() { + return countLeftSlab; + } + + public void setCountLeftSlab(ArrayList countLeftSlab) { + this.countLeftSlab = countLeftSlab; + } + + public ArrayList getCountCenterSlab() { + return countCenterSlab; + } + + public void setCountCenterSlab(ArrayList countCenterSlab) { + this.countCenterSlab = countCenterSlab; + } + + public ArrayList getCountRightSlab() { + return countRightSlab; + } + + public void setCountRightSlab(ArrayList countRightSlab) { + this.countRightSlab = countRightSlab; + } + + public ArrayList getLinesInLeftSlab() { + return linesInLeftSlab; + } + + public void setLinesInLeftSlab(ArrayList linesInLeftSlab) { + this.linesInLeftSlab = linesInLeftSlab; + } + + public ArrayList getLinesInCenterSlab() { + return linesInCenterSlab; + } + + public void setLinesInCenterSlab(ArrayList linesInCenterSlab) { + this.linesInCenterSlab = linesInCenterSlab; + } + + public ArrayList getLinesInRightSlab() { + return linesInRightSlab; + } + + public void setLinesInRightSlab(ArrayList linesInRightSlab) { + this.linesInRightSlab = linesInRightSlab; + } + + public Double getR() { + return r; + } + + public void setR(Double r) { + this.r = r; + } + + public Integer getN() { + return n; + } + + public void setN(Integer n) { + this.n = n; + } + + public Double getK() { + return k; + } + + public void setK(Double k) { + this.k = k; + } + + public Double getkLow() { + return kLow; + } + + public void setkLow(Double kLow) { + this.kLow = kLow; + } + + public Double getkHigh() { + return kHigh; + } + + public void setkHigh(Double kHigh) { + this.kHigh = kHigh; + } + + public Double getBeta() { + return beta; + } + + public void setBeta(Double beta) { + this.beta = beta; + } + + public Double getThetaLow() { + return thetaLow; + } + + public void setThetaLow(Double thetaLow) { + this.thetaLow = thetaLow; + } + + public Double getThetaHigh() { + return thetaHigh; + } + + public void setThetaHigh(Double thetaHigh) { + this.thetaHigh = thetaHigh; + } } diff --git a/src/main/java/Presenter/Presenter.java b/src/main/java/Presenter/Presenter.java index 6dd2010..5c5e0bb 100644 --- a/src/main/java/Presenter/Presenter.java +++ b/src/main/java/Presenter/Presenter.java @@ -61,26 +61,32 @@ public class Presenter implements Observer { } view.logHeading("Schnittpunkte der Dualen Geraden:"); view.createTable(heading, rows); - - - Thread t = new Thread(() -> { - RepeatedMedianEstimator rm = new RepeatedMedianEstimator(this.getLines()); - rm.run(); - }); - t.start(); - } @Override public void update(Observable o, Object arg) { Line result = ((Line) arg); - SwingUtilities.invokeLater(() -> { - getView().createPlot(result.getM(), result.getB()); - getView().setLmsIsComplete(true); - getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt"); - getView().log("m: " + result.getM() + "\t b: " + result.getB()); - }); + if (result.getId() == "lms"){ + SwingUtilities.invokeLater(() -> { + getView().visualizeLMS(result.getM(), result.getB()); + //getView().setLmsIsComplete(true); + getView().logHeading("Least Median of Squares"); + getView().log("m: " + result.getM()); + getView().log("b: " + result.getB()); + getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt"); + }); + } + + if (result.getId() == "rm"){ + SwingUtilities.invokeLater(() -> { + getView().visualizeRM(result.getM(), result.getB()); + getView().logHeading("Repeated Median Estimator"); + getView().log("m: " + result.getM()); + getView().log("b: " + result.getB()); + getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt"); + }); + } } @@ -89,7 +95,7 @@ public class Presenter implements Observer { view.createArrangement(); } - public void startScatterPlotVisualization(String[] input) { + public void calculateLMS(String[] input) { Double constant = Double.parseDouble(input[0]); Double error = Double.parseDouble(input[1]); lms = new LeastMedianOfSquaresEstimator(model.getLines(), model.getNodes(), this); @@ -99,6 +105,13 @@ public class Presenter implements Observer { lms.run(); } + public void calculateRM(String input){ + RepeatedMedianEstimator rm = new RepeatedMedianEstimator(this.getLines(), this); + rm.setBeta(Double.parseDouble(input)); + rm.addObserver(this); + rm.run(); + } + public Point calcIntersection(Line a, Line b) { Line p1 = a; diff --git a/src/main/java/View/MainFrame.java b/src/main/java/View/MainFrame.java index 8cd9dc1..36e6550 100644 --- a/src/main/java/View/MainFrame.java +++ b/src/main/java/View/MainFrame.java @@ -2,6 +2,10 @@ package View; import Presenter.Presenter; +import View.Panels.LMSPanel; +import View.Panels.MenuPanel; +import View.Panels.OutputPanel; +import View.Panels.RMPanel; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; @@ -37,12 +41,16 @@ public class MainFrame extends JFrame { private OutputPanel output; private MenuPanel menupanel; - private SidePanel sidepanel; + private LMSPanel lmsPanel; + private RMPanel rmPanel; private JPanel pane; private ArrangementDialog arrangement; private JDialog arrangementDialog; - private PlotDialog plot; + private PlotDialog plotLMS; + private PlotDialog plotRM; + private PlotDialog plotTS; + private JSplitPane splitpane; @@ -84,16 +92,26 @@ public class MainFrame extends JFrame { } } - public void createPlot(double m, double b) { - - plot = new PlotDialog(); - SwingUtilities.invokeLater(() -> { - plot.createPlot(getPresenter().getLines()); - plot.addLineToPlot(m, b); - sidepanel.setPlotDialog(plot); - }); + public void visualizeLMS(double m, double b) { + plotLMS = new PlotDialog(); + lmsPanel.setPlotDialog(plotLMS); + createPlot(m,b,plotLMS,lmsPanel); } + public void visualizeRM(double m, double b) { + plotRM = new PlotDialog(); + rmPanel.setPlotDialog(plotRM); + createPlot(m,b,plotRM,rmPanel); + } + + public void createPlot(double m, double b, PlotDialog plot, JPanel panel){ + SwingUtilities.invokeLater(() -> { + plot.clear(); + plot.createPlot(getPresenter().getLines()); + plot.addLineToPlot(m, b); + panel.revalidate(); + }); + } /******************************************************************************************************************* * init GUI @@ -106,8 +124,8 @@ public class MainFrame extends JFrame { } private void setupTabbedPane() { - tabbedPane.add("Least Median of Squares", sidepanel); - tabbedPane.add("Repeated Median", new JPanel()); + tabbedPane.add("Least Median of Squares", lmsPanel); + tabbedPane.add("Repeated Median", rmPanel); tabbedPane.add("Theil-Sen", new JPanel()); } @@ -137,12 +155,15 @@ public class MainFrame extends JFrame { } private void setDimensions() { - this.setSize(1900, 1000); - sidepanel.setMinimumSize(new Dimension(400, 500)); + this.setMinimumSize(new Dimension(1900,1000)); + this.setExtendedState(JFrame.MAXIMIZED_BOTH); + lmsPanel.setMinimumSize(new Dimension(400, 500)); + rmPanel.setMinimumSize(new Dimension(400, 500)); arrangementDialog.setSize(new Dimension(800, 800)); output.setMinimumSize(new Dimension(400, 500)); } + private void setLayouts() { this.setLayout(new BorderLayout()); pane.setLayout(new FlowLayout()); @@ -151,7 +172,8 @@ public class MainFrame extends JFrame { private void initializeComponents() { //Panels pane = new JPanel(); - sidepanel = new SidePanel(); + lmsPanel = new LMSPanel(); + rmPanel = new RMPanel(); menupanel = new MenuPanel(); //Dialogs @@ -173,9 +195,15 @@ public class MainFrame extends JFrame { t.start(); }); - sidepanel.getStartButton().addActionListener((ActionEvent e) -> { + lmsPanel.getStartButton().addActionListener((ActionEvent e) -> { Thread t = new Thread( - () -> this.getPresenter().startScatterPlotVisualization(sidepanel.getInput())); + () -> this.getPresenter().calculateLMS(lmsPanel.getInput())); + t.start(); + }); + + rmPanel.getStartButton().addActionListener((ActionEvent e) -> { + Thread t = new Thread( + () -> this.getPresenter().calculateRM(rmPanel.getInput())); t.start(); }); } @@ -276,8 +304,8 @@ public class MainFrame extends JFrame { return menupanel; } - public JPanel getSidepanel() { - return sidepanel; + public JPanel getLmsPanel() { + return lmsPanel; } public JSplitPane getSplitpane() { @@ -297,12 +325,12 @@ public class MainFrame extends JFrame { } - public PlotDialog getPlot() { - return plot; + public PlotDialog getPlotLMS() { + return plotLMS; } - public void setPlot(PlotDialog plot) { - this.plot = plot; + public void setPlotLMS(PlotDialog plotLMS) { + this.plotLMS = plotLMS; } public Presenter getPresenter() { diff --git a/src/main/java/View/SidePanel.java b/src/main/java/View/Panels/LMSPanel.java similarity index 91% rename from src/main/java/View/SidePanel.java rename to src/main/java/View/Panels/LMSPanel.java index f36cced..ceb67ef 100644 --- a/src/main/java/View/SidePanel.java +++ b/src/main/java/View/Panels/LMSPanel.java @@ -1,6 +1,8 @@ -package View; +package View.Panels; +import View.PlotDialog; import java.awt.BorderLayout; +import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -17,7 +19,7 @@ import javax.swing.border.TitledBorder; * @Email: a_wolf28@uni-muenster.de * @Date: 02.06.2017. */ -public class SidePanel extends JPanel { +public class LMSPanel extends JPanel { private JLabel[] labels; @@ -29,9 +31,9 @@ public class SidePanel extends JPanel { private PlotDialog plotDialog; private GridBagConstraints gbc; - public SidePanel() { - this.labels = new JLabel[10]; - this.input = new JTextField[10]; + public LMSPanel() { + this.labels = new JLabel[2]; + this.input = new JTextField[2]; this.setLayout(new BorderLayout()); this.northPanel = new JPanel(new BorderLayout()); this.centerPanel = new JPanel(new BorderLayout()); @@ -59,6 +61,7 @@ public class SidePanel extends JPanel { private void addTextfieldAndInput(int row, String name, Double value) { this.labels[row] = new JLabel(name); + this.labels[row].setFont(new Font("SansSerif", Font.PLAIN, 12)); this.input[row] = new JTextField(); this.input[row].setText("" + value); diff --git a/src/main/java/View/MenuPanel.java b/src/main/java/View/Panels/MenuPanel.java similarity index 97% rename from src/main/java/View/MenuPanel.java rename to src/main/java/View/Panels/MenuPanel.java index 4e5f5c7..9e950bc 100644 --- a/src/main/java/View/MenuPanel.java +++ b/src/main/java/View/Panels/MenuPanel.java @@ -1,4 +1,4 @@ -package View; +package View.Panels; import java.awt.BorderLayout; import javax.swing.JMenu; diff --git a/src/main/java/View/OutputPanel.java b/src/main/java/View/Panels/OutputPanel.java similarity index 92% rename from src/main/java/View/OutputPanel.java rename to src/main/java/View/Panels/OutputPanel.java index 3b28c56..ade4782 100644 --- a/src/main/java/View/OutputPanel.java +++ b/src/main/java/View/Panels/OutputPanel.java @@ -1,4 +1,4 @@ -package View; +package View.Panels; import java.awt.BorderLayout; import java.util.List; @@ -38,28 +38,28 @@ public class OutputPanel extends JPanel { public void appendParagraph(String p) { - content.append("

" + p + "


"); + content.append("

" + p + "

"); output.setText(content.toString()); } public void appendParagraphWithHeading(String h1) { - content.append("

" + h1 + "


"); + content.append("

" + h1 + "

"); output.setText(content.toString()); } public void appendParagraphRed(String p) { - content.append("

" + p + "


"); + content.append("

" + p + "

"); output.setText(content.toString()); } public void appendParagraphGreen(String p) { - content.append("

" + p + "


"); + content.append("

" + p + "

"); output.setText(content.toString()); } diff --git a/src/main/java/View/Panels/RMPanel.java b/src/main/java/View/Panels/RMPanel.java new file mode 100644 index 0000000..9ceb209 --- /dev/null +++ b/src/main/java/View/Panels/RMPanel.java @@ -0,0 +1,114 @@ +package View.Panels; + +import View.PlotDialog; +import java.awt.BorderLayout; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; + +/** + * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. + * + * @Author: Armin Wolf + * @Email: a_wolf28@uni-muenster.de + * @Date: 21.06.2017. + */ +public class RMPanel extends JPanel { + + private JLabel labels; + private JTextField input; + private JButton startButton; + private JPanel continer; + private JPanel northPanel; + private JPanel centerPanel; + private PlotDialog plotDialog; + private GridBagConstraints gbc; + + public RMPanel() { + this.labels = new JLabel(); + + this.input = new JTextField(); + this.setLayout(new BorderLayout()); + this.northPanel = new JPanel(new BorderLayout()); + this.centerPanel = new JPanel(new BorderLayout()); + this.northPanel.setBorder(new TitledBorder("Konfiguration")); + this.centerPanel.setBorder(new TitledBorder("Visualisierung")); + + this.continer = new JPanel(); + this.continer.setLayout(new GridBagLayout()); + + this.gbc = new GridBagConstraints(); + this.gbc.anchor = GridBagConstraints.NORTH; + this.gbc.fill = GridBagConstraints.HORIZONTAL; + + addTextfieldAndInput(0, "\u00df (0 < \u00df < 1)", 0.5); + + + this.startButton = new JButton("start"); + gbc.insets = new Insets(30, 5, 10, 0); + gbc.gridx = 0; + gbc.gridy = 2; + gbc.weightx = 0.05; + gbc.weighty = 0.05; + continer.add(startButton, gbc); + + this.northPanel.add(continer, BorderLayout.CENTER); + this.add(northPanel, BorderLayout.NORTH); + this.add(centerPanel, BorderLayout.CENTER); + } + + + private void addTextfieldAndInput(int row, String name, Double value) { + this.labels = new JLabel(name); + this.labels.setFont(new Font("SansSerif", Font.PLAIN, 13)); + this.input = new JTextField(); + this.input.setText("" + value); + + gbc.insets = new Insets(0, 5, 0, 0); + gbc.gridx = 0; + gbc.gridy = row; + gbc.weightx = 0.05; + gbc.weighty = 0.05; + continer.add(this.labels, gbc); + + gbc.gridx = 1; + gbc.gridy = row; + gbc.weightx = 0.9; + gbc.weighty = 0.05; + gbc.insets = new Insets(0, 0, 0, 5); + continer.add(this.input, gbc); + } + + + public JButton getStartButton() { + return startButton; + } + + public String getInput() { + String input = ""; + input = this.input.getText(); + return input; + } + + public void setInput(JTextField input) { + this.input = input; + } + + public PlotDialog getPlotDialog() { + return plotDialog; + } + + public void setPlotDialog(PlotDialog plotDialog) { + this.plotDialog = plotDialog; + this.centerPanel.add(plotDialog, BorderLayout.CENTER); + this.plotDialog.setVisible(true); + this.repaint(); + this.revalidate(); + } +} diff --git a/src/main/java/View/PlotDialog.java b/src/main/java/View/PlotDialog.java index 0c6ce60..7d7b8bc 100644 --- a/src/main/java/View/PlotDialog.java +++ b/src/main/java/View/PlotDialog.java @@ -39,13 +39,12 @@ public class PlotDialog extends JPanel { public PlotDialog() { super(); - this.setPreferredSize(new Dimension(800, 500)); - this.setMinimumSize(new Dimension(800, 500)); + this.setPreferredSize(new Dimension(1000, 1000)); + this.setMinimumSize(new Dimension(1000, 800)); this.setLayout(new BorderLayout()); } public void createPlot(LinkedList points) { - try { Thread thread = new Thread(() -> convertData(points)); thread.start(); @@ -61,6 +60,8 @@ public class PlotDialog extends JPanel { chart.setBorderVisible(false); chart.setAntiAlias(true); chart.getPlot().setBackgroundPaint(Color.WHITE); + chart.setBorderVisible(false); + XYPlot xyPlot = (XYPlot) chart.getPlot(); xyPlot.setDomainCrosshairVisible(true); @@ -89,9 +90,15 @@ public class PlotDialog extends JPanel { xyPlot.setRangeCrosshairVisible(true); panel = new ChartPanel(chart); + panel.setMouseZoomable(false); this.add(panel, BorderLayout.CENTER); } + public void clear(){ + if (datapoints != null) + datapoints.removeAllSeries(); + } + public void addLineToPlot(double m, double b) { linesA = new XYSeries("linesA"); linesA.add(min.intValue(), min.intValue() * m + b);