Приложение для переписывания в стиле MVC - PullRequest
3 голосов
/ 12 декабря 2010

У меня есть работающее приложение Java Bean с 3 полями, где поле 1 устанавливает предел по модулю после вычитания поля 3 из поля 2. Все работало нормально, но теперь мне сообщили, что мое приложение следует переписать в MVC, где 3 входатакже просмотров.Так что вопрос - что двигаться куда?А какой должна быть модель?

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;
    }
}

1 Ответ

1 голос
/ 30 мая 2011

Вот некоторая информация, которая должна помочь, без предоставления вам точного кода:

По сути, причина использования шаблона проектирования MVC состоит в том, чтобы отделить логику от пользовательского интерфейса. Три части можно кратко описать как:

Модель: Основная логика программы.

Представления: Биты пользовательского интерфейса, которые используют модель (логику) для отображения правильной информации.

Контроллер (ы): Проще всего думать о контроллере как о ActionListeners для вашего View.

«Модель» и «Представление (я)» почти всегда являются отдельными классами; «Контроллер» часто включается в представления, так как иногда он просто состоит из добавления ActionListeners.

Вот пример очень простого приложения с использованием MVC для создания простой программы чище. Предположим, у нас есть базовый калькулятор, определенный следующим интерфейсом:

public class Calc {
   public int add(int[] nums) {}
   public int sub(int[] nums) {}
   public int mult(int[] nums) {}
   public double div(int[] nums) {}
}

И графический интерфейс для этого калькулятора, CalcGUI. Итак, наша цель - отделить модель от представления. Мы могли бы использовать MVC и что-то вроде этого ...

public class CalcGUI extends JFrame {
   private Calc model;
   private JTextField result;
   public CalcGUI(Calc model) {
      this.model = model;
      // Random GUI setup stuff
      result = new JTextField(10);
      ... whatever else you need
      // Add controllers
   }
   // A sample view method that uses the model for logic
   public void add() {
      result.setText(model.add(user's numbers));
   }
}

Обратите внимание, что графическому интерфейсу не нужно использовать какие-либо логические аспекты функциональности программы (математические операции). Объект «модель» Calc выполняет всю логику для GUI (представление); все, что нужно сделать графическому интерфейсу, - это вызвать методы модели и использовать ее возвращаемые значения для отображения правильной информации для пользователя.

Еще одна важная вещь, которую стоит отметить, - это конструктор CalcGUI. Обратите внимание, как это происходит в объекте «Calc». Поскольку объекты являются указателями в Java (на которые ссылается адрес памяти), всегда будет использоваться один и тот же объект «Calc». Это важно, если вам нужно хранить информацию в вашей модели (не в этом приложении, а почти всегда в «реальном» приложении). \

Некоторые полезные ссылки для изучения MVC:

http://www.enode.com/x/markup/tutorial/mvc.html

http://www.roseindia.net/struts/struts/struts2.2.1/mvcdesignpattern.html

http://cristobal.baray.com/indiana/projects/mvc.html

Надеюсь, это помогло!

...