如何使用多个类的摆动 [英] How to work with swing with multiple classes

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

问题描述

我只是想知道一些关于秋千的事情1)如何在swing中使用MVC模型?2)假设我有一个主窗口,我需要将菜单作为单独的类,所有组件作为单独的类,这将是集成它的最佳方法

I just want to know some thing about the swing 1) How to use MVC model in swing? 2)Say i Have an Main window and i need to do the menu as separate class ,all the component as separate class and .which will be the best method to integrate it

推荐答案

好吧,这被称为以矫枉过正的方式回答,对此感到抱歉,但这里有一个快速示例,我尝试使用简单的 MVC 模式来做一件小事:按下一个按钮并更改 JTextField 中的文本.这有点矫枉过正,因为你可以用几行代码做同样的事情,但它确实在单独的文件中说明了一些 MVC 以及模型如何控制状态.如有任何疑问,请提出问题!

OK, this is called answering with overkill, so sorry about that, but here's a quick example I've whipped up that tries to use a simple MVC pattern to do a trivial thing: press a button and change the text in a JTextField. It's overkill because you could do the same thing in just a few lines of code, but it does illustrate some MVC in separate files and how the model controls the State. Please ask questions if anything is confusing!

将所有内容放在一起并开始工作的主类:

The main class that puts all together and gets things started:

import javax.swing.*;

public class SwingMvcTest {
   private static void createAndShowUI() {

      // create the model/view/control and connect them together
      MvcModel model = new MvcModel();
      MvcView view = new MvcView(model);
      MvcControl control = new MvcControl(model);
      view.setGuiControl(control);

      // EDIT: added menu capability
      McvMenu menu = new McvMenu(control);

      // create the GUI to display the view
      JFrame frame = new JFrame("MVC");
      frame.getContentPane().add(view.getMainPanel()); // add view here
      frame.setJMenuBar(menu.getMenuBar()); // edit: added menu capability
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   // call Swing code in a thread-safe manner per the tutorials
   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

视图类:

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;

public class MvcView {
   private MvcControl control;
   private JTextField stateField = new JTextField(10);
   private JPanel mainPanel = new JPanel(); // holds the main GUI and its components

   public MvcView(MvcModel model) {
      // add a property change listener to the model to listen and 
      // respond to changes in the model's state
      model.addPropertyChangeListener(new PropertyChangeListener() {
         public void propertyChange(PropertyChangeEvent evt) {
            // if the state change is the one we're interested in...
            if (evt.getPropertyName().equals(MvcModel.STATE_PROP_NAME)) {
               stateField.setText(evt.getNewValue().toString()); // show it in the GUI
            }
         }
      });
      JButton startButton = new JButton("Start");
      startButton.addActionListener(new ActionListener() {
         // all the buttons do is call methods of the control
         public void actionPerformed(ActionEvent e) {
            if (control != null) {
               control.startButtonActionPerformed(e); // e.g., here
            }
         }
      });
      JButton endButton = new JButton("End");
      endButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            if (control != null) {
               control.endButtonActionPerformed(e); // e.g., and here
            }
         }
      });

      // make our GUI pretty
      int gap = 10;
      JPanel buttonPanel = new JPanel(new GridLayout(1, 0, gap, 0));
      buttonPanel.add(startButton);
      buttonPanel.add(endButton);

      JPanel statePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
      statePanel.add(new JLabel("State:"));
      statePanel.add(Box.createHorizontalStrut(gap));
      statePanel.add(stateField);

      mainPanel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
      mainPanel.setLayout(new BorderLayout(gap, gap));
      mainPanel.add(buttonPanel, BorderLayout.CENTER);
      mainPanel.add(statePanel, BorderLayout.PAGE_END);
   }

   // set the control for this view
   public void setGuiControl(MvcControl control) {
      this.control = control;
   }

   // get the main gui and its components for display
   public JComponent getMainPanel() {
      return mainPanel;
   }

}

控制:

import java.awt.event.ActionEvent;

public class MvcControl {
   private MvcModel model;

   public MvcControl(MvcModel model) {
      this.model = model;
   }

   // all this simplistic control does is change the state of the model, that's it
   public void startButtonActionPerformed(ActionEvent ae) {
      model.setState(State.START);
   }

   public void endButtonActionPerformed(ActionEvent ae) {
      model.setState(State.END);
   }
}

该模型使用 PropertyChangeSupport 对象来允许其他对象(在这种情况下为 View)监听状态变化.所以模型实际上是我们的可观察者",而视图是观察者"

The model uses a PropertyChangeSupport object to allow other objects (in this situation the View) to listen for changes in state. So the model is in effect our "observable" while the view is the "observer"

import java.beans.*;

public class MvcModel {
   public static final String STATE_PROP_NAME = "State";
   private PropertyChangeSupport pcSupport = new PropertyChangeSupport(this);
   private State state = State.NO_STATE;

   public void setState(State state) {
      State oldState = this.state;
      this.state = state;
      // notify all listeners that the state property has changed
      pcSupport.firePropertyChange(STATE_PROP_NAME, oldState, state);
   }

   public State getState() {
      return state;
   }

   public String getStateText() {
      return state.getText();
   }

   // allow addition of listeners or observers
   public void addPropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.addPropertyChangeListener(listener);
   }

}

一个简单的枚举State,来封装状态的概念:

A simple enum, State, to encapsulate the concept of state:

public enum State {
   NO_STATE("No State"), START("Start"), END("End");
   private String text;

   private State(String text) {
      this.text = text;
   }

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

   public String getText() {
      return text;
   }
}

我看到你也提到了菜单,所以我通过添加这个类和在 SwingMcvTest 类中添加了几行来添加菜单支持.请注意,由于代码分离,对 GUI 进行此更改是微不足道的,因为所有菜单需要做的是调用控制方法.它不需要知道模型或视图:

edit: I see you mentioned menu as well, so I've added menu support with the addition of this class and the addition of several lines in the SwingMcvTest class. Note that because of separation of code, it was trivial to make this change to the GUI since all the menu needs to do is call control methods. It needs to know nothing of the model or the view:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class McvMenu {
   private JMenuBar menuBar = new JMenuBar();
   private MvcControl control;

   @SuppressWarnings("serial")
   public McvMenu(MvcControl cntrl) {
      this.control = cntrl;

      JMenu menu = new JMenu("Change State");
      menu.add(new JMenuItem(new AbstractAction("Start") {
         public void actionPerformed(ActionEvent ae) {
            if (control != null) {
               control.startButtonActionPerformed(ae);
            }
         }
      }));
      menu.add(new JMenuItem(new AbstractAction("End") {
         public void actionPerformed(ActionEvent ae) {
            if (control != null) {
               control.endButtonActionPerformed(ae);
            }
         }
      }));

      menuBar.add(menu);
   }

   public JMenuBar getMenuBar() {
      return menuBar;
   }
}

上帝啊,做一些小事要写很多代码!我为本周的 stackoverflow Rube Goldberg 奖提名我自己和我的代码.

God that's a lot of code to do a trivial bit of chit! I nominate myself and my code for this week's stackoverflow Rube Goldberg award.

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

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