- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定多个问题excellent_informative_for_me-trashgod的答案,that和that,以及其他几个无法回答我的问题,
一个关于ActionListeners位置的设计类应该如何设计
(以及总体MVC分离-下文会有更多说明)。
目录
问题解释
我的示例的文件结构树(4)
编译/清理源代码的命令(4)
资料来源
1.问题解释
我已经读过有关MVC的信息,并且我想我大部分都已经了解了,因此出于这个问题,让我们假设这是正确的。不赘述:
根据控制器的要求,从模型产生视图。
在大多数实现中,View可以访问Model实例。
控制器与用户交互,将更改传播到模型和视图。
模型是极其简化的数据存储容器。
可以通过View进行观察。
现在,我的困惑与ActionListeners有关-应该注册哪个类-并且依次包含-按钮的代码,或者实际上是大多数View元素的代码,它们实际上不仅仅是指示器,而是模型操纵器?
假设,我们在视图中有两个项目-用于更改模型数据的按钮,以及仅用于更改视图外观的一些可视项目。让代码负责更改View类中的View外观似乎是合理的。我的问题与第一种情况有关。我有几个想法:
View创建按钮,因此在View中创建ActionListeners并同时注册回调很自然。但这要求View具有与模型相关的代码,从而破坏封装。 View应该只了解底层的Controller或Model,仅通过Observer与之交谈。
我可以公开按钮等View项目,并从Controller将ActionListeners附加到它们,但这又破坏了封装。
我可以为每个按钮实现某种程度的回调-View会问控制器是否有任何代码应该为给定的按钮名称注册为ActionListener,但这似乎过于复杂,并且需要在控制器和视图之间进行名称同步。
我可以假设,理智的;),TableFactory中的按钮可以公开,允许将ActionListeners注入任何代码。
控制器可以替换整个View项(创建按钮并替换现有的按钮),但这似乎很疯狂,因为它不是它的角色
2.我的示例的文件结构树(4)
.
└── test
├── controllers
│ └── Controller.java
├── models
│ └── Model.java
├── resources
│ └── a.properties
├── Something.java
└── views
├── TableFactory.java
└── View.java
package test.controllers;
import test.models.Model;
import test.views.View;
public class Controller {
// Stub - doing nothing for now.
}
package test.models;
import java.util.Observable;
public class Model extends Observable {
}
package test;
import test.views.View;
import test.models.Model;
import test.controllers.Controller;
public class Something {
Model m;
View v;
Controller c;
Something() {
initModel();
initView();
initController();
}
private void initModel() {
m = new Model();
}
private void initView() {
v = new View(m);
}
private void initController() {
c = new Controller(m, v);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Something it = new Something();
}
});
}
}
package test.views;
import java.awt.*; // layouts
import javax.swing.*; // JPanel
import java.util.Observer; // MVC => model
import java.util.Observable; // MVC => model
import test.models.Model; // MVC => model
import test.views.TableFactory;
public class View {
private JFrame root;
private Model model;
public JPanel root_panel;
public View(Model model){
root = new JFrame("some tests");
root.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
root_panel = new JPanel();
root_panel.add(new TableFactory(new String[]{"a", "b", "c"}));
this.model = model;
this.model.addObserver(new ModelObserver());
root.add(root_panel);
root.pack();
root.setLocationRelativeTo(null);
root.setVisible(true);
}
}
class ModelObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.print(arg.toString());
System.out.print(o.toString());
}
}
package test.views;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class TableFactory extends JPanel {
private String[] cols;
private String[] buttonNames;
private Map<String, JButton> buttons;
private JTable table;
TableFactory(String[] cols){
this.cols = cols;
buttonNames = new String[]{"THIS", "ARE", "BUTTONS"};
commonInit();
}
TableFactory(String[] cols, String[] buttons){
this.cols = cols;
this.buttonNames = buttons;
commonInit();
}
private void commonInit(){
this.buttons = makeButtonMap(buttonNames);
DefaultTableModel model = new DefaultTableModel();
this.table = new JTable(model);
for (String col: this.cols)
model.addColumn(col);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
JPanel buttons_container = new JPanel(new GridLayout(1, 0));
for (String name : buttonNames){
buttons_container.add(buttons.get(name));
}
JScrollPane table_container = new JScrollPane(table);
this.removeAll();
this.add(buttons_container);
this.add(table_container);
this.repaint();
}
private Map<String, JButton> makeButtonMap(String[] cols){
Map<String, JButton> buttons = new HashMap<String, JButton>(cols.length);
for (String name : cols){
buttons.put(name, new JButton(name));
}
return buttons;
}
}
javax.swing.Action
=> setAction是我的选择。控制器访问View的JPanels,获取对包含按钮或任何JComponent的地图的引用,并对其添加操作。 View不知道Controllers代码中的内容。当我使它很好地工作时,我将更新此答案,因此任何在这里绊倒的人都可以使用它。
最佳答案
当Model–View–Controller模式为no panacea时,它是Swing应用程序设计中的循环模式。如here所述,Swing控制组件通常是视图包含层次结构的一部分:Swing应用程序的控制器可能无事可做,只是将这些组件连接到相关的侦听器; Action
实例(“可用于从组件中分离功能和状态”)特别方便。在此example中,Reset处理程序(简单的ActionListener
)嵌套在控制器中,但也可以将其作为Action
从模型中导出。按照here的建议,您可能必须尝试不同的设计。 here引用了几种方法。
关于java - Java Swing MVC体系结构-Q与MCVE示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34089447/
我尝试使用多处理来加速我的一个应用程序,结果导致性能下降。我确信这是一个设计缺陷,但这就是讨论的重点 - 如何更好地解决这个问题以利用多处理。 我目前在 1.4ghz 原子上的结果: SP 版本 =
当我想问一个问题,例如stackoverflow 我通常不得不发布源代码。 问题是,我正在使用相当大的自定义框架、类结构等,并且与问题相关的部分可能会在很多地方本地化(有时很难检测到代码的哪些部分对问
考虑这个 issue.py文件: import subprocess print('Calling subprocess...') subprocess.run(['python', '--versi
我遇到了一个非常奇怪的问题。我有一个 JPanel,其中包含 JTextFields 和 JComboBoxes。我可以在 JPanel 加载时更改 JComboBox,但一旦我触摸或编辑其中一个 J
我有一个用 python 编写的程序,用户提供命令行参数来说明应在某些数据上处理哪些统计数据、哪些组合。 最初,我编写的代码会采用 X 种组合中的 N 个统计数据并计算结果 - 然而,我发现如果我为自
与 C++/WinRT微软显然付出了相当大的努力来使其 API 符合标准。最后他们还发布了 machine learning API以及 code sample repo . 不幸的是,所有示例都依赖
我正在开发一个使用 WebRTC DataChannel 的 Web 应用,但无法在 Chrome 中打开该 channel 。我将其简化为一个简单的测试,在同一页面上打开两个 RTCPeerConn
在我的游戏中,成为叛徒的士兵将自动从炮塔、坦克和很多持有人。 (MCVE) 一个士兵可以同时驻留在1个炮塔和1个坦克中。 士兵最多可以驻留在 1 个炮塔和最多 1 个坦克中。 这是 Soldier、T
我是一名优秀的程序员,十分优秀!