Ich habe eine funktionierende Java-Bean-Anwendung mit 3 Feldern, wo Feld eins Grenze von Modulo nach Subtraktion Feld 3 von Feld 2. Alles funktioniert gut, aber jetzt wurde ich informiert, dass meine App in MVC neu geschrieben werden sollte wo 3 Eingänge auch Ansichten sind. Die Frage ist also - wohin wohin? Und was sollte das Modell sein?Umschreiben App MVC Stil
import java.io.Serializable;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
public class Main{
public Main(){
Values val1 = new Values();
Values val2 = new Values();
Limitator changer = new Limitator(val1, val2);
Values val3 = new Values();
Input in1 = new Input();
Input in2 = new Input();
Input in3 = new Input();
val1.addPropertyChangeListener(in1);
val2.addPropertyChangeListener(in2);
val3.addPropertyChangeListener(changer);
val1.addVetoableChangeListener(changer);
val2.addVetoableChangeListener(changer);
GUI frame = new GUI(in1, in2, in3, val1, val2, val3);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
Main argh = new Main();
}
}
class Input extends JTextField implements PropertyChangeListener{
private static final long serialVersionUID = 1L;
public Input(){
this("0");
}
public Input(String txt){
super(txt);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
Integer newVal = (Integer) evt.getNewValue();
setText("" + newVal);
}
}
class GUI extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
private Values val1;
private Values val2;
private Values val3;
private Input in1;
private Input in2;
private Input in3;
public GUI(Input in1, Input in2, Input in3, Values val1, Values val2, Values val3){
this.setTitle("Beansy!");
this.setPreferredSize(new Dimension(150, 110));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.val1 = val1;
this.val2 = val2;
this.val3 = val3;
this.in1 = in1;
this.in2 = in2;
this.in3 = in3;
Container con = new Container();
con.setLayout(new BoxLayout(con, BoxLayout.Y_AXIS));
in1.addActionListener(this);
in2.addActionListener(this);
in3.addActionListener(this);
con.add(in1);
con.add(in2);
con.add(in3);
this.add(con);
}
@Override
public void actionPerformed(ActionEvent e) {
int tmp = 0;
if(e.getSource()==in1){
try{
tmp = Integer.parseInt(in1.getText());
} catch (NumberFormatException e0){
JOptionPane.showMessageDialog(null, "Numbers only!", "Error", JOptionPane.ERROR_MESSAGE);
in1.setText(val1.getValue()+"");
}
try {
val1.setValue(tmp);
} catch (PropertyVetoException e1) {
JOptionPane.showMessageDialog(null, e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
in1.setText(val1.getValue()+"");
}
}
else if(e.getSource()==in2){
try{
tmp = Integer.parseInt(in2.getText());
} catch (NumberFormatException e0){
JOptionPane.showMessageDialog(null, "Numbers only!", "Error", JOptionPane.ERROR_MESSAGE);
in2.setText(val2.getValue()+"");
}
try {
val2.setValue(tmp);
} catch (PropertyVetoException e1) {
JOptionPane.showMessageDialog(null, e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
in2.setText(val2.getValue()+"");
}
}
else if(e.getSource()==in3){
try{
tmp = Integer.parseInt(in3.getText());
} catch (NumberFormatException e0){
JOptionPane.showMessageDialog(null, "Numbers only!", "Error", JOptionPane.ERROR_MESSAGE);
in3.setText(val3.getValue()+"");
}
try {
val3.setValue(tmp);
} catch (PropertyVetoException e1) {
JOptionPane.showMessageDialog(null, e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
in3.setText(val3.getValue()+"");
}
}
}
}
class Values implements Serializable{
private static final long serialVersionUID = 1L;
private int val = 0;
private VetoableChangeSupport veto = new VetoableChangeSupport(this);
private PropertyChangeSupport prop = new PropertyChangeSupport(this);
public Values(){
this(0);
}
public Values(int val){
try {
setValue(val);
} catch (PropertyVetoException e) {
JOptionPane.showMessageDialog(null, e.getMessage(), "Error when initializing", JOptionPane.ERROR_MESSAGE);
}
}
public synchronized void addPropertyChangeListener(PropertyChangeListener prop_nu) {
this.prop.addPropertyChangeListener(prop_nu);
}
public synchronized void removePropertyChangeListener(PropertyChangeListener prop) {
this.prop.removePropertyChangeListener(prop);
}
public void addVetoableChangeListener(VetoableChangeListener veto){
this.veto.addVetoableChangeListener(veto);
}
public void removeVetoableChangeListener(VetoableChangeListener veto){
this.veto.removeVetoableChangeListener(veto);
}
public int getValue(){
return this.val;
}
public synchronized void forceValue(int val){
int oldValue = this.val;
this.val = val;
prop.firePropertyChange("Value", new Integer(oldValue), new Integer(val));
}
public synchronized void setValue(int val) throws PropertyVetoException{
int oldValue = this.val;
veto.fireVetoableChange("Value", new Integer(oldValue), new Integer(val));
this.val = val;
prop.firePropertyChange("Value", new Integer(oldValue), new Integer(val));
}
}
class Limitator implements VetoableChangeListener, PropertyChangeListener{
int range;
Values val1;
Values val2;
public Limitator(){
this(0, null, null);
}
public Limitator(int num){
this(num, null, null);
}
public Limitator(Values val1, Values val2) {
this(0,val1,val2);
}
public Limitator(int num, Values val1, Values val2) {
this.range = num;
this.val1 = val1;
this.val2 = val2;
}
@Override
public synchronized void vetoableChange(PropertyChangeEvent arg0)throws PropertyVetoException {
int nu_val = (Integer)arg0.getNewValue();
int ol_val = (Integer)arg0.getOldValue();
int another_val;
if(arg0.getSource()==val1){
another_val = val2.getValue();
}else{
another_val = val1.getValue();
}
if(Math.abs(another_val - nu_val) > range){
if(arg0.getSource()==val1){
val1.forceValue(ol_val);
}
else if(arg0.getSource()==val2){
val2.forceValue(ol_val);
}
throw new PropertyVetoException("Limit exceeded!!", arg0);
}
}
@Override
public synchronized void propertyChange(PropertyChangeEvent evt) {
int new_range = ((Integer)evt.getNewValue()).intValue();
this.range = new_range;
}
}
"Und was sollte das Modell sein?" Fragen Sie sich selbst: Wenn ich diese App auf eine andere Benutzeroberfläche portieren müsste (z. B. webbasiert), müsste ich dann den gesamten Code verwerfen? Gibt es Teile des Codes, die ich noch verwenden könnte? Könnte ich den Code reorganisieren, so dass es beim nächsten Mal einfacher wäre, wenn ich auf eine andere Benutzeroberfläche portieren müsste? –
gute Fragen.Problem ist, dass es hier kein echtes Modell gibt. Ich denke nur an einen Wrapper für Limiter und Werte. – DevAno1
Hier ist ein MVC-Beispiel, das einen Ansatz vorschlagen könnte: http://stackoverflow.com/questions/3072979 – trashgod