gpt4 book ai didi

java - 如何避免在 swing gui MVC 应用程序中出现长链 getter 调用?

转载 作者:行者123 更新时间:2023-12-02 03:30:48 25 4
gpt4 key购买 nike

我是一名学生,正在开发一个带有大型 GUI 组件的个人 java 项目(请阅读:不是家庭作业),并尝试遵循 MVC 架构。我正在使用许多具有各种布局的嵌套 JPanel 构建一个复杂的 View 。这些面板中按钮的 Action 监听器将在包含对模型和 View 的引用的 Controller 类中实现。每个面板仅包含对其直接子面板的引用,因此当 Controller 需要更新深度嵌套面板之一中的某些内容时,它需要如下代码:

view.getCardLayoutPanel().getReceptionPanel().getOrderContentsPanel().updateTable(tableModel);

这似乎不太理想。下面是整个系统的一些伪代码。我在此处的代码中省略了简单的 get 方法,但我的所有 GUI 组件类都包含 get 方法,这些方法返回对其直接拥有的子面板的引用。

如何在仍然遵守 MVC 的情况下改善这种情况?

Controller :

public class Controller implements ActionListener {

private View view;

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

private void updateOrderTable() {

TableModel tableModel; //= **call model method to query db and generate a TableModel**
// This looks bad
view.getCardLayoutPanel().getReceptionPanel().getOrderContentsPanel().updateTable(tableModel);
}
}

View :

public class View {
// Setup stuff

JFrame mainFrame = new JFrame();
myCardLayoutPanel = new MyCardLayoutPanel ();\
// add cardLayoutPanel to mainframe
}

下一层:

public class MyCardLayoutPanel extends JPanel {

receptionPanel = new ReceptionPanel();
dataEntryPanel = new DataEntryPanel();
// etc

// Add all the panels to the layout
}

还有一个中间面板(我将省略它)遵循相同的模式......最后是带有表格的 JPanel。

public class OrderContentsPanel extends JPanel {

private JTable table;
private JScrollPane scrollpane;

public OrderContentsPanel() {
setLayout(new BorderLayout());
scrollPane = newJScrollPane(table);
add("Center", scrollPane) //
}

public void updateTable(TableModel tablemodel) {
table.setModel(tableModel);
}
}

最佳答案

通过应用程序级事件丰富您的面板和模型可能会有所帮助。

例如,假设您的应用程序有一个 OrderEntryPanel,每次用户输入订单时都会生成一个事件,以及一个 ArrivedOrdersPanel,它使用到达订单的事件。这些面板的内部结构以及它们在视觉上如何相对彼此排列并不是 Controller 感兴趣的。相反, Controller 将专注于将事件从面板传输到模型,反之亦然。

OrderEntryPanel 看起来像这样:

public class OrderEntryPanel extends JPanel {
private final JTextField orderTextField = new JTextField(20);
private final JButton sendButton = new JButton("Send order");

private Consumer<String> consumer;

public OrderEntryPanel() {
add(new JLabel("Place your order here: "));
add(orderTextField);
add(sendButton);

sendButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
consumer.accept(orderTextField.getText());
orderTextField.setText("");
}
});
}

public void setOrderEntryConsumer(Consumer<String> consumer) {
this.consumer = consumer;
}
}

ArrivedOrdersPanel 类似:

public class ArrivedOrdersPanel extends JPanel {

private JTable table = new JTable();
private DefaultTableModel tableModel = new DefaultTableModel(0, 2);

public ArrivedOrdersPanel() {
setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(table);
add("Center", scrollPane);

table.setModel(tableModel);
}

public void orderArrived(String orderText) {
Integer orderNumber = Integer.valueOf(tableModel.getRowCount()+1);
tableModel.addRow(new Object[] {orderNumber, orderText});
}
}

View 类创建并初始化它们,并为它们提供 getter 方法(我将省略这个细节;它不会对这个想法有太大贡献。)

模型(此处为 OrderStore)消耗用户输入订单的事件,然后生成新到达订单的事件:

public class OrderStore {
private final List<Order> orders = new LinkedList<>();

private Consumer<Order> orderArrivedConsumer;

public void incomingOrder(String orderText) {
Order order = new Order(orderText);

orders.add(order);

orderArrivedConsumer.accept(order);
}

public void setOrderArrivedConsumer(Consumer<Order> consumer) {
this.orderArrivedConsumer = consumer;
}
}

最后,我们可以使用简单的 lambda 连接模型和 View :

public static void main(String[] args) throws IOException {
View view = new View();
view.init();

OrderStore model = new OrderStore();

// In order not to dilute the essential point, the consumers do not switch execution control
// from Swing's event dispatcher thread to a background thread and vice versa

view.getOrderEntryPanel().setOrderEntryConsumer(
orderText -> model.incomingOrder(orderText));

model.setOrderArrivedConsumer(
order -> view.getArrivedOrdersPanel().orderArrived(order.getOrderText()));
}

因此,UI 的复杂性与 UI 与模型的耦合是分开的。

关于java - 如何避免在 swing gui MVC 应用程序中出现长链 getter 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38130745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com