I have a working java beans application with 3 fields, where field 1 sets the modulo limit after subtracting field 3 from field 2. Everything works fine, but now I was told that my application should be rewritten in MVC, where 3 Inputs also represent views. So the question is, where to go? And what should be the model?
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;
}
}