MVC如何使用java swing GUI [英] How MVC work with java swing GUI

查看:143
本文介绍了MVC如何使用java swing GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个带有textfeild和按钮的swing GUI。当我单击按钮时,我想将该值保存在db中的文本中并返回joptionpanesuccess消息。


我以前的方式是


模型:JDBC类


查看:GUI :在该按钮的操作已执行操作中,我调用了save方法参数。

Lets say I have a swing GUI which has textfeild and button. When I click button I want to save that value in text in db and return joptionpane "success" message.
The way I used to do this is
Model : JDBC class
View : GUI : In that button's 'action performed' action I call save method with parameter.

   Controller con = new Controller();
   con.save(text1.getText());

控制器:编写保存方法。

Controller : Write a save method.

   JDBC db = new                             
   public void save(jTextfeild text){     
   text= text1.getText();
   boolean b= db.putData("insert into .. values(text)");
   if(b){
   JOptionPane("Success"); 
   }
 }



这是怎么回事我已开始。但后来我明白这不应该是这样的,这是完全不安全和愚蠢的。


我真的想学习如何在MVC中正确地做到这一点。请用一个小例子来解释这个问题。感谢您的时间。


This is how I started. But later I understood this is not how this should be and this is utterly unsafe and stupid.
I really want to learn how to do this in MVC properly. Please be kind enough to explain this to with a small example. Thank you for your time.

推荐答案

这是一个很难掌握的东西,比如Swing,它已经使用了一种MVC形式,虽然更像VC- M,模型与视图和控制器分开,但视图和控制器组合在一起。

This is a difficult subject to grasp in something like Swing, which already uses a form of MVC, albeit more like VC-M, where the model is separated from the view and controller, but where the view and controller are combined.

想想 JButton ,你没有提供一个控制器来管理当用户按下一个键或用鼠标点击它时它是如何触发的,这是在内部完成的,并且会在发生时通知你。

Think about a JButton, you don't supply a controller to manage how it's triggered when a user presses a key or clicks on it with the mouse, this is done internally and you are notified about the actions when the occur.

考虑到这一点,您需要允许视图半自我管理。例如,根据您的要求,视图将有一个按钮和文本字段。

With this in mind, you need to allow the view to be semi self managed. For instance, based on your requirements, the view would have a button and text field.

视图本身将管理用户与按钮本身之间的交互(维护例如,内部 ActionListener ,但会向控制器提供有关控制器可能感兴趣的任何状态更改的通知。

The view itself would manage the interactions between the user and the button itself (maintain a internal ActionListener for example), but would then provide notifications to the controller about any state changes that the controller might be interested in.

在更纯粹的MVC意义上,视图和模型不会彼此了解任何事情,控制器会管理它们。这与Swing的工作方式有点矛盾,因为Swing允许您将模型直接传递给视图,只需查看任何Swing组件。

In a more pure sense of a MVC, the view and model won't know anything about each other and the controller would manage them. This is a little contradictive to how Swing works, as Swing allows you to pass the model directly to the view, see just about any Swing component.

这并不意味着你不能让事情发挥作用,但你需要知道这个概念可以停滞不前或者需要按摩才能更好地工作。

This doesn't mean that you can't make things work, but you need to know where the concept can falter or needs to be "massaged" to work better.

通常,当我接近时例如,这些类型的东西,我退后一步,看看更广泛的图片。

Normally, when I approach these type of things, I take step back and look at much wider picture, for example.


  • 你有一个可以接受文字和生成文本或对其进行更改

  • 您有一个可以加载和修改文本的模型,但提供的其他活动很少

  • 您有一个想要的控制器从模型中获取文本并将其提供给视图并监视视图对文本的更改并在模型中更新它们

现在,MVC在代码到接口(不是实现)的概念下工作得非常好,在这种程度上,我倾向于从合同开始......

Now, MVC works REALLY well with the concept of "code to interfaces (not implementation)", to that extent, I tend to start with the contracts...

public interface TextView {

    public void setText(String text);
    public String getText();
    public void addTextViewObserver(TextViewObserver observer);
    public void removeTextViewObserver(TextViewObserver observer);

}

public interface TextViewObserver {
    public void textWasChanged(TextView view);
}

现在,视图的一个要求是在文本时生成事件已经以某种有意义的方式改变了,为此,我使用了一个简单的观察者模式来实现。现在你可以说控制器是观察者,但在我看来,控制器可能具有我不想暴露给视图的功能(例如模型)

Now, one of the requirements of the view is to generate events when the text has changed in some meaningful way, to this end, I've used a simple observer pattern to implement. Now you could argue that the controller is the observer, but to my mind, the controller may have functionality that I don't want to expose to the view (like the model for instance)

接着是模型......

Next comes the model...

public interface TextModel {
    public String getText();
    public void setText(String text);
}

非常简单。现在,您可以考虑向这些方法添加某种 Exception ,以允许模型因某种原因失败,但异常应该尽可能通用(或者甚至是自定义的 Exception ),以便在需要时可以替换实现

pretty simple really. Now, you might consider adding some kind of Exception to these methods to allow the model the ability to fail for some reason, but the Exception should be as generic as you can make it (or even a custom Exception), so that you can replace the implementation should you need to

最后,控制器......

And finally, the controller...

public interface TextViewController {

    public TextView getTextView();
    public TextModel getTextModel();

}

再次,非常简单。您可能对控制器有更复杂的要求,但对于此示例,这是我们真正需要的所有内容。

again, pretty simple. You might have a more complex requirement for your controller, but for this example, this is about all we really need.

public class TextViewPane extends JPanel implements TextView {

    private JTextField textField;
    private JButton updateButton;
    private List<TextViewObserver> observers;

    public TextViewPane() {
        observers = new ArrayList<>(25);
        textField = new JTextField(25);
        updateButton = new JButton("Update");
        updateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                fireTextWasChanged();
            }
        });

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        add(textField, gbc);
        add(updateButton, gbc);
    }

    @Override
    public void setText(String text) {
        textField.setText(text);
    }

    @Override
    public String getText() {
        return textField.getText();
    }

    @Override
    public void addTextViewObserver(TextViewObserver observer) {
        observers.add(observer);
    }

    @Override
    public void removeTextViewObserver(TextViewObserver observer) {
        observers.remove(observer);
    }

    protected void fireTextWasChanged() {
        for (TextViewObserver observer : observers) {
            observer.textWasChanged(this);
        }
    }

}



型号。 ..



Model...

public class SimpleTextModel implements TextModel {

    private String text = "This is some text";

    @Override
    public String getText() {
        return text;
    }

    @Override
    public void setText(String text) {
        this.text = text;
    }

}



控制器......



Controller...

public class SimpleTextController implements TextViewController, TextViewObserver {

    private TextView view;
    private TextModel model;

    public SimpleTextController(TextView view, TextModel model) {
        this.view = Objects.requireNonNull(view, "TextView can not null");
        this.model = Objects.requireNonNull(model, "TextModel can not be null");
        view.addTextViewObserver(this);
    }

    @Override
    public TextView getTextView() {
        return view;
    }

    @Override
    public TextModel getTextModel() {
        return model;
    }

    @Override
    public void textWasChanged(TextView view) {
        getTextModel().setText(view.getText());
    }
}



把它放在一起......



Putting it together...

TextViewPane view = new TextViewPane();
TextModel model = new SimpleTextModel();
TextViewController controller = new SimpleTextController(view, model);

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(view);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

现在,所有这些只是一个可能的解决方案的示例。例如,你可以有一个控制器实现,它具有模型或视图的特定实现,或者两者兼而有之。

Now, all this is just an example of one possible solution. You could have a controller implementation which has a particular implementation of the model or view or both, for example.

重点是,你应该不在乎。控制器不关心视图是如何实现的,它只关心它将生成 textWasChanged 事件。该模型根本不关心视图(反之亦然),控制器不关心模型,只是它会得到并设置一些文本。

The point is, you just shouldn't care. The controller doesn't care how the view is implemented, it only cares that it will generate textWasChanged events. The model doesn't care about the view at all (and visa-versa) and the controller doesn't care about model, only that it will get and set some text.

对于更复杂的示例,您可以查看 Java和GUI - ActionListeners根据MVC模式属于哪里?

For a more complex example, you can have a look at Java and GUI - Where do ActionListeners belong according to MVC pattern?


  • 这只是解决问题的唯一方法。例如,您可以将视图限制为单个观察者。

  • 您应该始终在想我可以更改MVC的任何一部分并且它仍然可以工作吗?这使您可以考虑更改任何一部分实施可能对周围合同产生的问题。

  • 视图可以作为另一个子视图的控制器(或充当另一个控制器的容器),你应该明白每个层的实现方式并不重要。一个子视图)。这有时可能会吓到人们,但是视图可以作为一个或多个子控制器/视图的父容器,这允许您开发复杂的UI

  • 不公开实现细节例如,在您的合同中,模型不应抛出 SQLException ,因为另一个实现可能不基于基于SQL的解决方案。不要暴露UI元素,这意味着所有实现都需要实现这些元素。如果我想要向用户提供 JComboBox 的视图实现而不是 JTextField ,会发生什么?这也是我在视图合约中不使用 ActionListener 的原因,因为我不知道如何 textWasChanged 事件实际上可能是由视图的实现生成的

  • This is just ONE possible way to approach the problem. For example, you could limit the view to a single observer.
  • You should always be thinking "can I change any one part of the MVC and will it still work?" This makes you think about the possible issues that changing any one part of the implementation might have on the surrounding contracts. You should get to the point that it simply doesn't matter how each layer is implemented
  • A view may act as a controller for another sub-view (or act as a container for another controller of a sub-view). This can scare people sometimes, but it's possible for a view to act as parent container for one or more sub controllers/views, this allows you to develop complex UIs
  • Don't expose implementation details in your contracts, for example, the model shouldn't throw a SQLException, as another implementation might not be based on a SQL based solution. Don't expose UI elements, this means that ALL implementations would then need to implement those elements. What happens if I want a implementation of the view that presents a JComboBox to the user instead of JTextField? This is also the reason I don't use a ActionListener in the view contract, because I have no idea how a textWasChanged event might actually be generated by an implementation of the view

这篇关于MVC如何使用java swing GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆