Java Swing中的控制器是什么?
2022-09-05 00:12:17
我想以有意义的方式将MVC设计应用于使用Swing的Java应用程序。因此,我的问题是,在Java Swing中如何构建控制器?
我有两个选择:
- 每个组件侦听器都是一个单独的类,作为控制器包的一部分
- 每个组件侦听器都是视图包中的一个匿名类,它使用控制器方法将其调用委托给类。
两者都可能吗?这是一个偏好问题,还是明确界定?
我想以有意义的方式将MVC设计应用于使用Swing的Java应用程序。因此,我的问题是,在Java Swing中如何构建控制器?
我有两个选择:
两者都可能吗?这是一个偏好问题,还是明确界定?
控制器构成了组件接口的另一半,主要是交互的一半。控制器负责处理鼠标和键盘事件。
在Swing组件中,像等是控制器。并且所有侦听器类都将事件重定向到具有业务逻辑的模型JButton
例:
主程序
import javax.swing.*;
public class CalcMVC {
//... Create model, view, and controller. They are
// created once here and passed to the parts that
// need them so there is only one copy of each.
public static void main(String[] args) {
CalcModel model = new CalcModel();
CalcView view = new CalcView(model);
CalcController controller = new CalcController(model, view);
view.setVisible(true);
}
}
视图
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class CalcView extends JFrame {
//... Constants
private static final String INITIAL_VALUE = "1";
//... Components
private JTextField m_userInputTf = new JTextField(5);
private JTextField m_totalTf = new JTextField(20);
private JButton m_multiplyBtn = new JButton("Multiply");
private JButton m_clearBtn = new JButton("Clear");
private CalcModel m_model;
//======================================================= constructor
/** Constructor */
CalcView(CalcModel model) {
//... Set up the logic
m_model = model;
m_model.setValue(INITIAL_VALUE);
//... Initialize components
m_totalTf.setText(m_model.getValue());
m_totalTf.setEditable(false);
//... Layout the components.
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(new JLabel("Input"));
content.add(m_userInputTf);
content.add(m_multiplyBtn);
content.add(new JLabel("Total"));
content.add(m_totalTf);
content.add(m_clearBtn);
//... finalize layout
this.setContentPane(content);
this.pack();
this.setTitle("Simple Calc - MVC");
// The window closing event should probably be passed to the
// Controller in a real program, but this is a short example.
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void reset() {
m_totalTf.setText(INITIAL_VALUE);
}
String getUserInput() {
return m_userInputTf.getText();
}
void setTotal(String newTotal) {
m_totalTf.setText(newTotal);
}
void showError(String errMessage) {
JOptionPane.showMessageDialog(this, errMessage);
}
void addMultiplyListener(ActionListener mal) {
m_multiplyBtn.addActionListener(mal);
}
void addClearListener(ActionListener cal) {
m_clearBtn.addActionListener(cal);
}
}
控制器
import java.awt.event.*;
public class CalcController {
//... The Controller needs to interact with both the Model and View.
private CalcModel m_model;
private CalcView m_view;
//========================================================== constructor
/** Constructor */
CalcController(CalcModel model, CalcView view) {
m_model = model;
m_view = view;
//... Add listeners to the view.
view.addMultiplyListener(new MultiplyListener());
view.addClearListener(new ClearListener());
}
////////////////////////////////////////// inner class MultiplyListener
/** When a mulitplication is requested.
* 1. Get the user input number from the View.
* 2. Call the model to mulitply by this number.
* 3. Get the result from the Model.
* 4. Tell the View to display the result.
* If there was an error, tell the View to display it.
*/
class MultiplyListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String userInput = "";
try {
userInput = m_view.getUserInput();
m_model.multiplyBy(userInput);
m_view.setTotal(m_model.getValue());
} catch (NumberFormatException nfex) {
m_view.showError("Bad input: '" + userInput + "'");
}
}
}//end inner class MultiplyListener
//////////////////////////////////////////// inner class ClearListener
/** 1. Reset model.
* 2. Reset View.
*/
class ClearListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
m_model.reset();
m_view.reset();
}
}// end inner class ClearListener
}
型
import java.math.BigInteger;
public class CalcModel {
//... Constants
private static final String INITIAL_VALUE = "0";
//... Member variable defining state of calculator.
private BigInteger m_total; // The total current value state.
//============================================================== constructor
/** Constructor */
CalcModel() {
reset();
}
//==================================================================== reset
/** Reset to initial value. */
public void reset() {
m_total = new BigInteger(INITIAL_VALUE);
}
//=============================================================== multiplyBy
/** Multiply current total by a number.
*@param operand Number (as string) to multiply total by.
*/
public void multiplyBy(String operand) {
m_total = m_total.multiply(new BigInteger(operand));
}
//================================================================= setValue
/** Set the total value.
*@param value New value that should be used for the calculator total.
*/
public void setValue(String value) {
m_total = new BigInteger(value);
}
//================================================================= getValue
/** Return current calculator total. */
public String getValue() {
return m_total.toString();
}
}
普拉齐尔施,
伙计,这是一个非常沉重的问题...没有人会在论坛帖子中充分回答这个问题。Robert Eckstein(Java之神之一)的这部作品《Java SE Application Design With MVC》详细讨论了这个问题。
就个人而言,我最终使用了MVC的“变体”,我称之为MBVC(模型业务视图控制器),它实际上非常接近MVVMC...MVVM广泛用于.NET循环;添加控制器对我来说是有意义的,因为我有一些Web MVC经验。我希望在我开始使用MVC-ise我的应用程序之前,我已经阅读了上面的文章。你仍然可以在Sun(现在的Oracle)Java论坛上阅读我相当困惑的帖子。
干杯。基思。