MVC具体实现

时间:2015-10-10 12:33:13

标签: java model-view-controller

我正努力在Java中实现基于mvc的GUI。实际上我并不能开发GUI,但我对目前基于mvc(或至少我尝试过)的实现感到不满意。我读了很多关于mvc的内容,但有时候我会感到困惑,因为它会让我更清醒。

具体来说,我实现了可观察的模型,并在数据发生变化时通知观察者(可能是控制器或视图)。如有必要,我的控制器和我的视图可以访问所有模型。视图必须实现控制器用于访问视图的特定接口(但不必知道具体实现)。视图也是可观察的,并生成一些已定义的事件,然后控制器(观察视图)将处理。

我意识到这种方式可以用来创建一个pdf文档,而不是用文字写这个文档。要快速创建文档,可以轻松地将文档内容与gui一起单击,也可以在文本字段中更改文本。因此GUI有许多复选框和文本字段等。那么我应该如何处理所有文本字段,复选框等的操作?我可以为每个更改的文本字段创建一个事件到控制器并在文本字段内传递新文本,控制器将把它放到相应的模型中。但由于我的GUI有很多文本字段,这将导致代码的大量开销。

我的想法是:GUI实际上只显示模型中存储的内容,因此如果我更改文本字段,gui可以将新字符串直接存储在模型中。

当用户没有按下按钮生成pdf文档时,会向控制器发送一个事件,该事件将根据模型中的存储数据创建必要的内容。

我试图做一个简短的例子它是如何工作的(ViewObserver和ViewObservable是一个自我实现的类和接口,类似于现有的Observer和Observable):

/*
 * Model
 */
public class Model extends Observable    
{
    private String title;
    public void setTitle(String title)
    {
        this.title = title;
        super.setChanged();
        super.notifyObservers();
    }
    public String getTitle()
    {
        return title;
    }
}

/*
 * View
 */
public class View extends ViewObservable implements ViewInterface, Observer
{
    private JTextField titleField;
    private Model model;

    public View(Model model)
    {
        this.model = model;
        this.model.addObserver(this);            

        titleField = new JTextField("Title");
        txtTextPrice.getDocument().addDocumentListener(new DocumentListener() 
        {
            @Override
            public void changedUpdate(DocumentEvent e) {updateTitle();}
            @Override
            public void insertUpdate(DocumentEvent e) {updateTitle();}
            @Override
            public void removeUpdate(DocumentEvent e) {updateTitle();}
            private void updateTitle()
            {
               model.setTitle(titleField.getText());
            }

        });
    }

    @Override
    public void update(Observable o, Object arg) 
    {
        if(o.equals(model))
        {
            //get the data from the model and show it
            titleField .setText(model.getTitle());
        }    
    }
}

/*
 * Controller
 */
public class Controller implements ViewObserver
{
    private JTextField titleField;
    private Model model;

    public Controller(ViewInterface view, Model model)
    {
        view.addObserver(this);
        this.model = model;
        this.model.addObserver(this); 
    }

    /* 
     * Events from the view
     */
    @Override
    public void signalEvent(ViewEvent e, Object arg) 
    {
        //Generate here the the pdf document for example
        //if the corresponding event is thrown. Get the
        //necessary data from the models
    }
}

但我认为我的架构存在问题,或者gui处理了多少事件?如果按钮,复选框和文本字段的监听器在控制器中,那么控制器如何独立于我的视图以及控制器如何从所有文本字段获取所有数据?或者我是否错过了解如何实施mvc?

1 个答案:

答案 0 :(得分:0)

您可以在面板中的所有文本字段上添加一个侦听器。在该侦听器中,您可以获取触发此事件的文本字段,以便您能够在该侦听器上处理您的逻辑。对于其他类型的组件,如button,它使用不同的侦听器类型,如actionListener。将它们混合在一起应该没有问题。一般来说,Swing将使用EDT线程来处理所有侦听器调用。它是单线程模型。确保不要在侦听器上放置过多的开销逻辑。如果你这样做,那么挥杆将通过超时异常。一种解决方案是使用来自JDK库的SwingWorker。