algorithms-for-computing-li.../LinearRegressionTool/src/main/java/de/wwwu/awolf/view/MainFrame.java

625 lines
20 KiB
Java

package de.wwwu.awolf.view;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.AbstractPresenter;
import de.wwwu.awolf.presenter.Presenter;
import de.wwwu.awolf.presenter.util.Logging;
import de.wwwu.awolf.view.listener.*;
import de.wwwu.awolf.view.panels.DualityPanel;
import de.wwwu.awolf.view.panels.EvaluationPanel;
import de.wwwu.awolf.view.panels.InfoPanel;
import de.wwwu.awolf.view.panels.PlotPanel;
import de.wwwu.awolf.view.panels.tabs.LMSPanel;
import de.wwwu.awolf.view.panels.tabs.RMPanel;
import de.wwwu.awolf.view.panels.tabs.TSPanel;
import de.wwwu.awolf.view.panels.tabs.TabPanel;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class MainFrame extends JFrame {
private AbstractPresenter presenter;
private Boolean lmsIsComplete = false;
private Boolean rmIsComplete = false;
private Boolean tsIsComplete = false;
private JButton arrangementButton;
private JButton importButton;
private JButton generateButton;
private JButton exportButton;
private InfoPanel output;
private MenuBar menu;
private JToolBar toolBar;
private TabPanel lmsPanel;
private TabPanel rmPanel;
private TabPanel tsPanel;
private DualityPanel arrangement;
private JDialog arrangementDialog;
private PlotPanel plotLMS;
private PlotPanel plotRM;
private PlotPanel plotTS;
private JDialog progressDialog;
private JDialog evaluationDialog;
private Container progressContent;
private JProgressBar progressBar;
private JSplitPane splitpane;
private JScrollPane scrollPane;
private JTabbedPane tabbedPane;
private EvaluationPanel evaluationPanel;
/**
* Konstruktor
*/
public MainFrame() {
super();
initializeComponents();
setDimensions();
setLayouts();
setTitles();
addComponents();
setCloseOperations();
setIcons();
disableFunctionality();
this.setVisible(true);
}
/*******************************************************************************************************************
* visualisierungs methoden
******************************************************************************************************************/
/**
* Erzeugt den Dialog für die duale Darstellung
*/
public void createDualityDialog() {
arrangement = new DualityPanel();
arrangementDialog = new JDialog();
arrangementDialog.setTitle("Dualraum - Dialog");
arrangementDialog.setMinimumSize(new Dimension(1024, 768));
arrangementDialog.setPreferredSize(new Dimension(800, 800));
arrangementDialog.setLocationRelativeTo(this);
arrangementDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
arrangementButton.addActionListener(new DualityVisualizerListener((Presenter) getPresenter()));
arrangement.clear();
arrangement.setPrameters(getPresenter().getModel().getLines(),
getPresenter().getModel().getNodes(),
getPresenter().getModel().getxMinimum(),
getPresenter().getModel().getxMaximum(),
getPresenter().getModel().getyMinimum(),
getPresenter().getModel().getyMaximum());
arrangement.createArrangement();
SwingUtilities.invokeLater(() -> {
arrangementDialog.add(arrangement);
arrangementDialog.setLocationRelativeTo(this);
arrangementDialog.revalidate();
arrangementDialog.repaint();
arrangementDialog.setVisible(true);
});
}
/**
* Visualisiert das Ergebnis des LMS-Schätzers
*
* @param m Steigung
* @param b y-Achsenabschnitt
*/
public void visualizeLMS(double m, double b) {
plotLMS = new PlotPanel();
lmsPanel.setPlotPanel(plotLMS);
createPlot(m, b, plotLMS, lmsPanel, "LMS");
}
/**
* Visualisiert das Ergebnis des LMS-Schätzers
*
* @param line Line
*/
public void visualizeLMS(final Line line) {
plotLMS = new PlotPanel();
lmsPanel.setPlotPanel(plotLMS);
createPlot(line.getM(), line.getB(), plotLMS, lmsPanel, "LMS");
}
/**
* Visualisiert das Ergebnis des RM-Schätzers
*
* @param m Steigung
* @param b y-Achsenabschnitt
*/
public void visualizeRM(double m, double b) {
plotRM = new PlotPanel();
rmPanel.setPlotPanel(plotRM);
createPlot(m, b, plotRM, rmPanel, "RM");
}
/**
* Visualisiert das Ergebnis des RM-Schätzers
*
* @param line Line
*/
public void visualizeRM(final Line line) {
plotRM = new PlotPanel();
rmPanel.setPlotPanel(plotRM);
createPlot(line.getM(), line.getB(), plotRM, rmPanel, "RM");
}
/**
* Visualisiert das Ergebnis des TS-Schätzers
*
* @param m Steigung
* @param b y-Achsenabschnitt
*/
public void visualizeTS(double m, double b) {
plotTS = new PlotPanel();
tsPanel.setPlotPanel(plotTS);
createPlot(m, b, plotTS, tsPanel, "TS");
}
/**
* Visualisiert das Ergebnis des TS-Schätzers
*
* @param line Line
*/
public void visualizeTS(final Line line) {
plotTS = new PlotPanel();
tsPanel.setPlotPanel(plotTS);
createPlot(line.getM(), line.getB(), plotTS, tsPanel, "TS");
}
/**
* Erzeugt den Plot zu einer Eingabe von Punkten und der Lösung eines Schätzers (m,b)
*
* @param m Steigung
* @param b y-Achsenabschnitt
* @param plot Plot
* @param panel Panel auf dem der Plot plaziert wird
* @param name Bezeichnung der Gerade
*/
public void createPlot(double m, double b, PlotPanel plot, JPanel panel, String name) {
SwingUtilities.invokeLater(() -> {
plot.clear();
plot.createPlot(getPresenter().getModel().getLines());
plot.addLineToPlot(m, b, name);
panel.revalidate();
});
}
/**
* Visualisierung des Import-Prozesses
*
* @param progress akteulle Prozentzahl (0-100)
*/
public void showImportProgress(Integer progress) {
progressBar.setValue(progress);
progressBar.setStringPainted(true);
progressDialog.setVisible(true);
}
/**
* Zeigt den Evaluations-Dialog an (ggf. wird dieser erzeugt)
*/
public void showEvauluationDialog() {
if (evaluationDialog == null) {
SwingUtilities.invokeLater(() -> {
evaluationDialog = new JDialog();
evaluationDialog.setTitle("evaluation");
evaluationDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
evaluationDialog.setSize(new Dimension(1500, 800));
evaluationDialog.setLocationRelativeTo(null);
evaluationPanel = new EvaluationPanel(this);
evaluationDialog.setLocationRelativeTo(this);
evaluationDialog.add(evaluationPanel);
evaluationDialog.setVisible(true);
});
} else {
SwingUtilities.invokeLater(() -> {
evaluationDialog.setLocationRelativeTo(this);
evaluationDialog.setVisible(true);
});
}
}
/**
* Fügt der Evaluations-Tabelle eine Spalte mit Daten hinzu
*
* @param res Daten der Spalte
* @param col Spalte
* @param isApprCol <code>true</code>, falls es sich um die Überschirften der Approximationsgüten handelt
*/
public void appendEvalResult(Object[] res, int col, boolean isApprCol) {
SwingUtilities.invokeLater(() -> {
Object[] tmp = Arrays.copyOfRange(res, 2, res.length);
if (isApprCol) {
evaluationPanel.setCurrentRow(tmp.length);
evaluationPanel.addColumn(tmp, col, true);
} else {
evaluationPanel.addColumn(tmp, col + 1, false);
}
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
/**
* Fügt der Evaluations-Tabelle eine Zeile mit Daten hinzu
*
* @param res Daten der Spalte
*/
public void appendEvalResult(Object[] res) {
SwingUtilities.invokeLater(() -> {
Object[] tmp = Arrays.copyOfRange(res, 1, res.length);
evaluationPanel.addRow(tmp);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
/**
* Visualisiert die Ausgleichsgerade zu gegebenen Algorithmen
*
* @param res Steigungen und y-Achsenabschnitte
* @param alg Kodierung der Alg.
*/
public void drawLineResult(Object[] res, int alg) {
SwingUtilities.invokeLater(() -> {
Object[] result = Arrays.copyOfRange(res, 2, res.length);
evaluationPanel.drawLines(result, alg);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
/**
* Visualisiert die Ausgleichsgerade zu einem gegebenen Algorithmus
*
* @param res Steigungen und y-Achsenabschnitte
*/
public void drawLineResults(Object[] res) {
SwingUtilities.invokeLater(() -> {
Object[] result = Arrays.copyOfRange(res, 1, res.length);
List<Double[]> 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();
});
}
/**
* Evaluations-Datensätze werden Visualisiert
*
* @param lines Liste der Geraden
*/
public void addEvalDataset(List<Line> lines) {
SwingUtilities.invokeLater(() -> {
evaluationPanel.setDualPoints(lines);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
/*******************************************************************************************************************
* init GUI
******************************************************************************************************************/
/**
* Setzt den Titel der Komponenten
*/
private void setTitles() {
this.setTitle("Algorithmen zur Berechnung von Ausgleichgeraden");
importButton.setText("Import");
exportButton.setText("Export");
generateButton.setText("Generiere");
arrangementButton.setText("Dualraum");
}
/**
* Fügt die einzelnen Seiten dem TabbedPane hinzu
*/
private void setupTabbedPane() {
tabbedPane.add("Least Median of Squares", lmsPanel);
tabbedPane.add("Repeated Median", rmPanel);
tabbedPane.add("Theil-Sen", tsPanel);
}
/**
* Komponenten werden in Container gesetzt
*/
private void addComponents() {
toolBar.add(arrangementButton);
toolBar.add(importButton);
toolBar.add(exportButton);
toolBar.add(generateButton);
toolBar.setFloatable(false);
setJMenuBar(menu.getMenuBar());
add(toolBar);
//northPanel.add(toolBar);
setupSplitPane();
setupTabbedPane();
progressContent.add(progressBar, BorderLayout.CENTER);
progressBar.setBorder(BorderFactory.createTitledBorder("Import..."));
progressDialog.setLocationRelativeTo(null);
((JPanel) progressDialog.getContentPane()).setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
this.add(toolBar, BorderLayout.NORTH);
this.add(splitpane, BorderLayout.CENTER);
}
/**
* Konfiguration des SplitPane
*/
private void setupSplitPane() {
splitpane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitpane.setResizeWeight(.5d);
splitpane.setContinuousLayout(true);
splitpane.setLeftComponent(output);
splitpane.setRightComponent(tabbedPane);
}
/**
* Fenster Funktionalität wird gesetzt
*/
private void setCloseOperations() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
progressDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
}
/**
* Größen der Komponenten werden gesetzt
*/
private void setDimensions() {
this.setSize(new Dimension(1500, 800));
this.setResizable(true);
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
this.setMaximizedBounds(env.getMaximumWindowBounds());
lmsPanel.setMinimumSize(new Dimension(400, 500));
rmPanel.setMinimumSize(new Dimension(400, 500));
tsPanel.setMinimumSize(new Dimension(400, 500));
output.setMinimumSize(new Dimension(400, 500));
progressDialog.setSize(300, 45);
progressDialog.setResizable(false);
progressDialog.setUndecorated(true);
}
/**
* Setzen der Layouts
*/
private void setLayouts() {
this.setLayout(new BorderLayout());
toolBar.setLayout(new FlowLayout(FlowLayout.LEFT));
}
/**
* Initialisierung der Komponenten
*/
private void initializeComponents() {
//panels
toolBar = new JToolBar();
lmsPanel = new LMSPanel();
rmPanel = new RMPanel();
tsPanel = new TSPanel();
menu = new MenuBar(this);
//Dialogs
progressDialog = new JDialog();
progressDialog.setLocationRelativeTo(null);
progressContent = progressDialog.getContentPane();
progressBar = new JProgressBar();
//Panes
tabbedPane = new JTabbedPane();
output = new InfoPanel();
splitpane = new JSplitPane();
//Buttons
arrangementButton = new JButton();
importButton = new JButton();
generateButton = new JButton();
exportButton = new JButton();
pack();
}
/**
* Icons werden passend gesetzt
*/
private void setIcons() {
try {
ClassLoader classLoader = getClass().getClassLoader();
Image imgImport = ImageIO.read(classLoader.getResource("import.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
Image imgPlot = ImageIO.read(classLoader.getResource("plot.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
Image imgStart = ImageIO.read(classLoader.getResource("start.png")).getScaledInstance(32, 32, Image.SCALE_SMOOTH);
Image imgGenerate = ImageIO.read(classLoader.getResource("generate.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
Image imgExport = ImageIO.read(classLoader.getResource("export.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
Image imgFrame = ImageIO.read(classLoader.getResource("frame.png")).getScaledInstance(32, 23, Image.SCALE_SMOOTH);
importButton.setIcon(new ImageIcon(imgImport));
exportButton.setIcon(new ImageIcon(imgExport));
generateButton.setIcon(new ImageIcon(imgGenerate));
arrangementButton.setIcon(new ImageIcon(imgPlot));
lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
rmPanel.getStartButton().setIcon(new ImageIcon(imgStart));
tsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
this.setIconImage(imgFrame);
} catch (IOException e) {
Logging.logError(e.getMessage(), e);
}
}
/**
* Funktionalitäten werden hinzugefügt
*/
public void setActionListeners() {
//action listener für MenuItems
menu.addActionListeners();
//action listener für diese Klasse
arrangementButton.addActionListener(new DualityVisualizerListener((Presenter) getPresenter()));
lmsPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), lmsPanel));
rmPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), rmPanel));
tsPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), tsPanel));
importButton.addActionListener(new ImportDataListener((Presenter) this.getPresenter(), this));
exportButton.addActionListener(new ExportDataListener((Presenter) this.getPresenter(), this));
generateButton.addActionListener(new GenerateDataListener((Presenter) this.getPresenter()));
}
/**
* Funktionalitäten werden aktiviert.
*/
public void enableFunctionality() {
this.getLmsPanel().getStartButton().setEnabled(true);
this.getRmPanel().getStartButton().setEnabled(true);
this.getTsPanel().getStartButton().setEnabled(true);
this.getArrangementButton().setEnabled(true);
this.getExportButton().setEnabled(true);
}
/**
* Funktionalitäten werden deaktiviert.
*/
public void disableFunctionality() {
this.getLmsPanel().getStartButton().setEnabled(false);
this.getRmPanel().getStartButton().setEnabled(false);
this.getTsPanel().getStartButton().setEnabled(false);
this.getArrangementButton().setEnabled(false);
this.getExportButton().setEnabled(false);
}
/*******************************************************************************************************************
* log Methode
******************************************************************************************************************/
/**
* @param s Text der ausgegeben wird
*/
public void log(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraph(s));
}
/**
* @param s Fehlertext der ausgegeben wird
*/
public void logError(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphRed(s));
}
/**
* @param s Text der in grüner Farbe ausgegeben wird
*/
public void logSuccess(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s));
}
/**
* @param s Text der als Überschrift ausgegeben wird
*/
public void logHeading(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s));
}
/**
* Ausgabe einer Tabelle
*
* @param heading Überschrift
* @param rows Zeilen mit Text
*/
public void createTable(List<String> heading, List<List<String>> rows) {
SwingUtilities.invokeLater(() -> output.logTable(heading, rows));
}
/*******************************************************************************************************************
* Getter und Setter Methoden
******************************************************************************************************************/
/**
* @return liefert den Button, zum visualisieren des dualen Raums zurück
*/
public JButton getArrangementButton() {
return arrangementButton;
}
/**
* @return liefert das Panel zum visualisieren des LMS-Schätzers
*/
public TabPanel getLmsPanel() {
return lmsPanel;
}
/**
* @return liefert das Panel zum visualisieren des RM-Schätzers
*/
public TabPanel getRmPanel() {
return rmPanel;
}
/**
* @return liefert die Instanz des Presenters zurück
*/
public AbstractPresenter getPresenter() {
return presenter;
}
/**
* @param presenter Presenter Instanz
*/
public void setPresenter(AbstractPresenter presenter) {
this.presenter = presenter;
}
/**
* @return liefert den Dialog zum visualisieren des Import-Fortschrits
*/
public JDialog getProgressDialog() {
return progressDialog;
}
/**
* @return liefert das Panel zum visualisieren des TS-Schätzers
*/
public TabPanel getTsPanel() {
return tsPanel;
}
/**
* @return liefert den Button, exportieren zurück
*/
public JButton getExportButton() {
return exportButton;
}
}