Trennung GUI und Funktion

Albatrox

Mitglied
Hey Leute,
ich versuch grad bei einem Programm, die Funktion von der GUI zu trennen und in einer extra Klasse unter zu bringen, allerdings, kommt jetzt keine Lösung mehr.
Hier mal des Code:
Die Klasse mit der graphischen Oberfläche:
Java:
package übung;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class umrechner extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	JTextField tf1 = new JTextField();
	JTextField tf2 = new JTextField();
	JTextField tf3 = new JTextField();
	JButton b1 = new JButton("umrechnen");
	String [] list = {"Dollar", "Australische Dollar", "Rubel"};
	JComboBox combo = new JComboBox(list);
	
	public umrechner(){
		super("Kapital Umrechner");
		setLayout(new BorderLayout());
		add(new JLabel("Währungs-Umrechner"), "North");
		add(b1, "South");
		JPanel panel1 = new JPanel();
		panel1.setLayout(new GridLayout(3,2));
		panel1.add(new JLabel("Tausch - Währung"));
		panel1.add(combo);
		panel1.add(new JLabel("Tausch - Betrag"));
		panel1.add(tf2);
		panel1.add(new JLabel("umgerechnet in €"));
		panel1.add(tf3);
		add(panel1);
		b1.addActionListener(new MyActionListener());
		combo.addActionListener(new MyActionListener());
	}
		class MyActionListener implements ActionListener{
			public void actionPerformed(ActionEvent ae){
				double ergebnis;
				if (ae.getSource() == b1 && combo.equals("Dollar")){
						double betrag = Double.parseDouble(tf2.getText());
						funktion obj1 = new funktion( betrag);
						ergebnis = (obj1.währungsrechner());
						tf3.setText(Double.valueOf(ergebnis).toString());
				}
			}
		}
	public static void main (String [] args){
		umrechner fenster = new umrechner();
		fenster.setSize(300,150);
		fenster.setVisible(true);
	}
}
Hier noch die Klasse, die die Funktion enthält:
Java:
package übung;

public class funktion extends umrechner {
	private double betrag;
	public funktion(double betrag){
		this.betrag = betrag;
	}
	public double währungsrechner(){
		double ergebnis = betrag;
		ergebnis = betrag * 0.950642634;
		ergebnis = Math.round(ergebnis );
		return ergebnis;
	}
	
}
 

Thallius

Top Contributor
Zunächst trennst du die GUI nicht von der Funktion indem Du die Funktion von der UI Klasse ableitest. Damit setzt du die Funktion nur oben drauf. Das ist also der ganz falsche Ansatz.

Zum zweiten frage ich mich wie deine Combobox equal zu "Dollar" sein soll. Maximal kann ja wohl der ausgewählte Eintrag "Dollar" sein.

Gruß

Claus
 
Zuletzt bearbeitet:

Foxei

Bekanntes Mitglied
Hallo Albatrox,
wenn du wirklich Logik Code von UI Code trennen wird ist das ganze ein wenig aufwendiger. Hier einmal ein Leitfaden wie man zu einem in meinen Augen optimalen Ergebnisse zu deiner Aufgabe kommt.

1) Model
Eine Model-Klasse anlegen die alle nötigen Informationen bereitstellt. Also im jetzigen Fall die Namen der Währungen und ihren Wechselkurs. Alles immer schön mit Getter und Setter Methoden ausstaffiert.
[Java]package waehrungsRechner;

public class WaehrungsModel {
private String[] waehrungen;
private double[] kurs;
public WaehrungsModel() {
setWaehrungen(new String[]{"Dollar", "Australische Dollar", "Rubel"});
setKurs(new double[]{0.94508,0.72311,0.01536});
}
public String[] getWaehrungen() {
return waehrungen;
}
public void setWaehrungen(String[] waehrungen) {
this.waehrungen = waehrungen;
}
public double[] getKurs() {
return kurs;
}
public void setKurs(double[] kurs) {
this.kurs = kurs;
}
public double getSingleKurs(String waehrung) {
for(int i=0;i<getWaehrungen().length;i++){
if(getWaehrungen().equals(waehrung)){
return getKurs();
}
}
return 0;
}
}[/code]

2) UI
Wichtig ist das wir keine Informationen eintragen dafür haben wir unsere Model Klasse. Sagen wir unser UI sieht so aus.
Waehrungsrechner.png

Dann müssen drei Objekte von außen angesteuert werden können.
  1. Die ComboBox
  2. Das TextFeld für die betrags Eingabe
  3. Das TextFeld für die Euro Ausgabe
Zusätzlich lagen wir den ActionListener des Buttons aus der UI Klasse aus.
Java:
package waehrungsRechner;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class UI extends JFrame {
	private JTextField txtBetrag;
	private JFormattedTextField txtEuro;
	private JComboBox<String> cmbWaehrung;
	private JButton btnNewButton;

	public UI() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(305, 210);
		setLocationRelativeTo(null);
		setTitle("W\u00E4hrungsrechner");
		
		GridBagLayout gbl_contentPane = new GridBagLayout();
		gbl_contentPane.columnWidths = new int[]{0, 0};
		gbl_contentPane.rowHeights = new int[]{0, 0, 0, 0, 0, 0};
		gbl_contentPane.columnWeights = new double[]{0.0,1.0};
		gbl_contentPane.rowWeights = new double[]{0.0, 1.0, 1.0, 1.0, 0.0, Double.MIN_VALUE};
		getContentPane().setLayout(gbl_contentPane);
		
		TitleLabel lblTitle = new TitleLabel();
		lblTitle.setText("W\u00E4hrungsrechner");
		GridBagConstraints gbc_lblTitle = new GridBagConstraints();
		gbc_lblTitle.gridwidth = 2;
		gbc_lblTitle.insets = new Insets(0, 0, 5, 0);
		gbc_lblTitle.gridx = 0;
		gbc_lblTitle.gridy = 0;
		gbc_lblTitle.fill=GridBagConstraints.HORIZONTAL;
		getContentPane().add(lblTitle, gbc_lblTitle);
		
		JLabel lblTauschWaehrung = new JLabel("Tausch - W\u00E4hrung");
		GridBagConstraints gbc_lblTauschWaehrung = new GridBagConstraints();
		gbc_lblTauschWaehrung.insets = new Insets(0, 5, 5, 5);
		gbc_lblTauschWaehrung.anchor = GridBagConstraints.EAST;
		gbc_lblTauschWaehrung.gridx = 0;
		gbc_lblTauschWaehrung.gridy = 1;
		getContentPane().add(lblTauschWaehrung, gbc_lblTauschWaehrung);
		
		cmbWaehrung = new JComboBox<String>();
		GridBagConstraints gbc_cmbWaehrung = new GridBagConstraints();
		gbc_cmbWaehrung.insets = new Insets(0, 0, 5, 5);
		gbc_cmbWaehrung.fill = GridBagConstraints.HORIZONTAL;
		gbc_cmbWaehrung.gridx = 1;
		gbc_cmbWaehrung.gridy = 1;
		getContentPane().add(cmbWaehrung, gbc_cmbWaehrung);
		
		JLabel lblTauschBetrag = new JLabel("Tausch - Betrag");
		GridBagConstraints gbc_lblTauschBetrag = new GridBagConstraints();
		gbc_lblTauschBetrag.anchor = GridBagConstraints.WEST;
		gbc_lblTauschBetrag.insets = new Insets(0, 5, 5, 5);
		gbc_lblTauschBetrag.gridx = 0;
		gbc_lblTauschBetrag.gridy = 2;
		getContentPane().add(lblTauschBetrag, gbc_lblTauschBetrag);
		
		txtBetrag = new JTextField();

		GridBagConstraints gbc_txtBetrag = new GridBagConstraints();
		gbc_txtBetrag.insets = new Insets(0, 0, 5, 5);
		gbc_txtBetrag.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtBetrag.gridx = 1;
		gbc_txtBetrag.gridy = 2;
		getContentPane().add(txtBetrag, gbc_txtBetrag);
		txtBetrag.setColumns(10);
		
		JLabel lblBetragInEuro = new JLabel("Betrag in \u20AC");
		GridBagConstraints gbc_lblBetragInEuro = new GridBagConstraints();
		gbc_lblBetragInEuro.anchor = GridBagConstraints.WEST;
		gbc_lblBetragInEuro.insets = new Insets(0, 5, 5, 5);
		gbc_lblBetragInEuro.gridx = 0;
		gbc_lblBetragInEuro.gridy = 3;
		getContentPane().add(lblBetragInEuro, gbc_lblBetragInEuro);
		
		txtEuro = new JFormattedTextField(new DecimalFormat("0.0####"));

		GridBagConstraints gbc_txtEuro = new GridBagConstraints();
		gbc_txtEuro.insets = new Insets(0, 0, 5, 5);
		gbc_txtEuro.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtEuro.gridx = 1;
		gbc_txtEuro.gridy = 3;
		getContentPane().add(txtEuro, gbc_txtEuro);
		txtEuro.setColumns(10);
		
		btnNewButton = new JButton("Umrechnen");
		GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
		gbc_btnNewButton.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton.anchor = GridBagConstraints.EAST;
		gbc_btnNewButton.gridx = 1;
		gbc_btnNewButton.gridy = 4;
		getContentPane().add(btnNewButton, gbc_btnNewButton);
	}

	/**
	 * Fügt der ComboBox das Model für die möglichen Währungen hinzu.
	 * @param array String Array mit den Namen der Währungen
	 */
	public void setComboBoxValues(String[] array){
		DefaultComboBoxModel<String> model=new DefaultComboBoxModel<String>();
		for(String s:array){
			model.addElement(s);
		}
		cmbWaehrung.setModel(model);
	}
	
	/**
	 * Fügt dem Button den ActionListener hinzu.
	 * @param ac ActionListener der Kontroller Klasse
	 */
	public void addListener(ActionListener ac){
		btnNewButton.addActionListener(ac);
	}
	
	/**
	 * Die Aktuelle in der ComboBox ausgewählte Währung
	 * @return Name der Währung
	 */
	public String getWaehrung(){
		return String.valueOf(cmbWaehrung.getSelectedItem());
	}
	
	/**
	 * Überprüfung ob Text = einer Kommazahl ist.
	 * @return Zahl oder bei Fehler 0
	 */
	public double getValue(){
		try {
			double d=Double.parseDouble(txtBetrag.getText().replace(",", "."));
			return d;
		} catch (Exception e) {
			return 0;
		}
	}
	
	/**
	 * Anweisung an das UI bestimmten Betrag anzuzeigen
	 * @param betrag Betrag der angezeigt wird
	 */
	public void displayEuro(double betrag){
		txtEuro.setValue(betrag);
	}
}
TitleLabel.java
Java:
package waehrungsRechner;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;

import javax.swing.JLabel;
import javax.swing.border.EmptyBorder;

public class TitleLabel extends JLabel{
	public TitleLabel() {
		setPreferredSize(new Dimension(100,60));
		setBackground(new Color(100,130,190));
		setBorder(new EmptyBorder(new Insets(0, 20, 0, 0)));
		setFont(new Font(getFont().getFontName(),Font.BOLD,20));
		setForeground(Color.WHITE);
	}
	@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2d=(Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		g2d.setColor(getBackground());
		g2d.fillRect(0, 0, getWidth(), getHeight());
		
		GeneralPath path=new GeneralPath();
		path.moveTo(0f, getHeight()-30);
		path.curveTo(60, 70, getWidth()/8*6, -30, getWidth(), getHeight()-10);
		path.lineTo(getWidth(), getHeight());
		path.lineTo(0f, getHeight());
		
		g2d.setPaint(new GradientPaint(getWidth()/2,0,new Color(255,255,255,100),getWidth()/2, getHeight(),new Color(0,0,0,0)));
		g2d.fill(path);
		super.paintComponent(g);
	}
}

3) Die Verbindung
Nun Verbinden wir Model mit UI über einen Kontroller der auf Eingaben im UI mit Werten aus dem Model reagieren kann. Alle Berechnungen also der Komplette Logik Code ist nun hier im Controller zu finden. Da wir den Action Listener des UI's hier hin ausgelagert haben.
Java:
package waehrungsRechner;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ControllerWaehrungen implements ActionListener{
	private WaehrungsModel model;
	private UI gui;
	
	public ControllerWaehrungen() {
		//Informationen bereitstellen
		model=new WaehrungsModel();
		
		//UI laden
		gui=new UI();
		
		//Anweisungen an das UI schicken
//		gui.setComboBoxValues(model.getWaehrungen());
		gui.addListener(this);
		
		//UI anzeigen
		gui.setVisible(true);
	}

	//ActionListener für UI Ausgelagert
	@Override
	public void actionPerformed(ActionEvent e) {
		//Werte von UI zurückholen
		String waehrung=gui.getWaehrung();
		double betrag=gui.getValue();
		
		//Information aus Model lesen
		double umrechnung=model.getSingleKurs(waehrung);
		
		//UI anweisen etwas anzuzeigen
		gui.displayEuro(betrag*umrechnung);
	}
}

4) Starter
Nun starten wir unser Programm alle Befehle die noch vor dem eigentlichen Programm geladen werden müssen sind hier zu finden.
Java:
package waehrungsRechner;

import javax.swing.UIManager;

public class Main {
	private ControllerWaehrungen controllerWaehrungen;
	public Main() {
		loadLnF();
		controllerWaehrungen=new ControllerWaehrungen();
	}
	private void loadLnF(){
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args){
		new Main();
	}
}

Somit wird dein Programm zwar größer aber es ist wesentlich einfacher das UI zu wechseln bzw die stelle im Code zu finden wo dieses oder jenes passiert.

Gruß Simon :)
 

Albatrox

Mitglied
@Foxei, erstmal vielen Dank für deine Mühen, gibt zwar ein paar Sachen die ich noch nicht kenne, aber ich werds mir mal genauer anschauen.

Ich habe jetzt noch ein bisschen an meiner Version weitergearbeitet. Hab noch ein zweites if in der Klasse "umrechner" hinzugefügt und auch passend dazu die Umrechnung nach Australischem Dollar nach dem Vorbild von der ersten if Anweisung also die Umrechnung zu Dollar. Allerdings wenn ich dann in der ComboBox den Australischen Dollar auswähle, dann kommt bei mir immer ein Fehler, von wegen dass der String leer wäre:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: empty String
Der Fehler wird mir dann in dieser Zeile angezeigt:
betrag = Double.parseDouble(tf2.getText());

Vielen Dank nochmal für die schnellen Antworten

Mfg Albatrox
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Saubere Trennung Model, View, Controller Javafx AWT, Swing, JavaFX & SWT 10
D Swing Trennung der UI- und Persistenz-Schicht AWT, Swing, JavaFX & SWT 1
J prinzipielles verständnis für Oberfläche/Code-trennung AWT, Swing, JavaFX & SWT 5
O Trennung GUI / Funktionalität AWT, Swing, JavaFX & SWT 3
F Zugriff auf Oberfläche bzw Trennung GUI / Logik AWT, Swing, JavaFX & SWT 3
K Trennung von GUI und Logik AWT, Swing, JavaFX & SWT 6
G Korrekte Trennung von GUI, Logik und Event nach MVC AWT, Swing, JavaFX & SWT 5
D Trennung des Event-Handling von der GUI AWT, Swing, JavaFX & SWT 4
D Trennung von Programm und Oberfläche AWT, Swing, JavaFX & SWT 3
O Trennung Gui und Anwendungslogik AWT, Swing, JavaFX & SWT 13
O Trennung Gui und Logik - Strukturierte Client Anwendung AWT, Swing, JavaFX & SWT 4
Juelin JavaFX Netbeans Aufruf Funktion aus Scenebuilder AWT, Swing, JavaFX & SWT 8
G JButton mit importFiles-Funktion auf JDrawPane AWT, Swing, JavaFX & SWT 5
L JavaFx Textformatierung mittels Datenbank und Funktion anpassen AWT, Swing, JavaFX & SWT 5
T Combobox mit Autocomplete-Funktion AWT, Swing, JavaFX & SWT 7
C Swing Aufruf der Funktion (die ein Dialog anzeigt) über Symbol anzeigen lassen AWT, Swing, JavaFX & SWT 4
L Button Funktion zuweisen in WindowBuilder AWT, Swing, JavaFX & SWT 22
A Button mit Speicher-Funktion AWT, Swing, JavaFX & SWT 8
F main-Funktion bei Swing AWT, Swing, JavaFX & SWT 4
kilopack15 Buttons ohne Funktion AWT, Swing, JavaFX & SWT 2
J Event Handling Frage zu der Funktion addActionListener AWT, Swing, JavaFX & SWT 2
D SWT Button mit F5-Funktion AWT, Swing, JavaFX & SWT 1
E ActionListener führt falsche Funktion aus AWT, Swing, JavaFX & SWT 6
C Swing JTextField Funktion zuweisen - Löschen von Buchstaben/Sonderzeichen AWT, Swing, JavaFX & SWT 6
K Funktion für das Bewegen des Balles AWT, Swing, JavaFX & SWT 5
A Textfeld.append/.setText ohne Funktion AWT, Swing, JavaFX & SWT 2
F Swing JTextField in JList (Funktion beibehalten) AWT, Swing, JavaFX & SWT 2
U Disable-Funktion AWT, Swing, JavaFX & SWT 1
C Swing Durch Inhaltsänderung eines JTextfields eine Funktion aufrufen AWT, Swing, JavaFX & SWT 5
J Swing Nach SwingWorker Funktion aus der GUI Klasse aufrufen AWT, Swing, JavaFX & SWT 5
W Funktion aus einer Java Datei in eine andere einbauen AWT, Swing, JavaFX & SWT 25
W Funktion per Tastendruck aufrufen. AWT, Swing, JavaFX & SWT 10
T ableitung übermalt die funktion AWT, Swing, JavaFX & SWT 3
N Swing Funktion repaint() updated nicht AWT, Swing, JavaFX & SWT 5
lumo SWT Image funktion auf ImageDaten AWT, Swing, JavaFX & SWT 9
R mathematische Funktion x^2 AWT, Swing, JavaFX & SWT 6
R mathemathische Funktion x^2 AWT, Swing, JavaFX & SWT 2
J Progressbar mit einfacher Funktion AWT, Swing, JavaFX & SWT 6
L Swing Funktion animieren AWT, Swing, JavaFX & SWT 10
O Variablen an anonyme Funktion AWT, Swing, JavaFX & SWT 10
D Funktion JList.getSelectedValues() gibt nicht alle values zurück AWT, Swing, JavaFX & SWT 2
G Swing Update-Funktion für Swing-Anwendung AWT, Swing, JavaFX & SWT 5
J Swing JDialog mit static-Funktion anzeigen -> Rückgabewert AWT, Swing, JavaFX & SWT 3
I JTextArea mit Copy Paste Funktion AWT, Swing, JavaFX & SWT 7
H Funktion ausführen wenn Button gedrückt wird. AWT, Swing, JavaFX & SWT 2
B Restart-Funktion für einen Updatemechanismus?????? AWT, Swing, JavaFX & SWT 4
G F6 Funktion AWT, Swing, JavaFX & SWT 2
S Swing Button mit Funktion abbilden AWT, Swing, JavaFX & SWT 3
P Funktion ist nicht MAC kompatibel, warum? AWT, Swing, JavaFX & SWT 12
S Funktion nur ausführen, wenn Maus über Componente ist AWT, Swing, JavaFX & SWT 2
A Sleep Funktion / Thread-Problem ! AWT, Swing, JavaFX & SWT 11
GilbertGrape bei "Enter" Funktion ausführen, egal wo der Fokus AWT, Swing, JavaFX & SWT 2
F Jframe Exit Funktion überladen AWT, Swing, JavaFX & SWT 3
G kreis malen -> welche funktion? AWT, Swing, JavaFX & SWT 3
D SWT: Funktion zum Auslesen der Schriftgröße AWT, Swing, JavaFX & SWT 2
D GroupLayout an un plötzlich is CardLayout Funktion tot? AWT, Swing, JavaFX & SWT 10
R Editor mit "Gehe zu"-Funktion AWT, Swing, JavaFX & SWT 4
W Unterdrückung von FrameIcon-Funktion im JInternalFrame AWT, Swing, JavaFX & SWT 5
G Funktion für PopUp Menü AWT, Swing, JavaFX & SWT 32
F ZOOM Funktion in JTextPane AWT, Swing, JavaFX & SWT 6
D paint-Funktion wird nicht ausgeführt AWT, Swing, JavaFX & SWT 6
A Drag and Drop Funktion mit JLabel AWT, Swing, JavaFX & SWT 5
E Beim Schließen des Fensters eigene Funktion aufrufen AWT, Swing, JavaFX & SWT 8
L JOP.showInputDialog: Abbrechen Button-Funktion beenden AWT, Swing, JavaFX & SWT 5
D setPreferredSize(), setMaximumSize() ohne Funktion? AWT, Swing, JavaFX & SWT 4
S JComboBox -> undo Funktion hinzufügen! AWT, Swing, JavaFX & SWT 2
Z Welche Funktion von JTextArea muß ich überschreiben? AWT, Swing, JavaFX & SWT 4
R TAB-Funktion in Fenster ändern - genauer: STRG+TAB AWT, Swing, JavaFX & SWT 5
P Rückgängig-Funktion im Malprogramm AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben