让两个同级的 Swing 组件交互

Letting two same-level Swing components interact

我正在尝试制作一个应用程序,但目前对如何整齐地构建我的代码有点困惑。

为简单起见,假设我想要一个 JFrame 包含:

  1. 一个 JPanel,其中包含一个 JComboBox,用户可以在其中 select 一个形状(正方形、圆形等)。
  2. 一个单独的 JPanel,直观地显示 JComboBox 中的 selected 形状。

所以我有以下代码:

public class Frame extends JFrame {

    Frame() {
        ComboBoxPanel comboBoxPanel = new ComboBoxPanel();
        ShapePanel shapePanel = new ShapePanel();

        this.getContentPane().add(comboBoxPanel, BorderLayout.WEST);
        this.getContentPane().add(shapePanel, BorderLayout.CENTER);

        this.setResizable(true);
        this.pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new Frame();
    }
}

组合框面板:

public class ComboBoxPanel extends JPanel {

    private JComboBox<Shape> comboBox;

    ComboBoxPanel() {
        comboBox = new JComboBox<Shape>(Shape.SHAPES);
        this.add(comboBox);

        comboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    // Here I want to repaint the shapePanel
                }
            }
        });
    }
}

最后,ShapePanel 看起来像:

public class ShapePanel extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
        // Get selected Shape from JComboBox and draw it
    }
}

简而言之,如何让这两个同级组件以一种整洁的方式相互交互?我想到了一些解决方案,但它们看起来真的很脏。欢迎任何想法。

谢谢。

我建议阅读观察者模式或 mvc 模式。最好的解决方案可能是 mvc。在 MVC(模型、视图、控制器)中,您将模型(您的数据)保存在视图(两个 jpanels)之外。然后,因为两个面板共享相同的数据,所以很容易让您的显示面板由您的输入面板驱动。

如果您的 ComboBoxPanelShapePanel 都位于同一个 JFrame 中,则它们应该 "see" 彼此。从那里,您可以只使用 类 中的 getter 和 setter 来访问彼此的属性。

如果你在谈论不相关的 类,你总是可以采用一种设计模式,例如 类 签署合同并通过方法公开感兴趣的行为的观察者模式。

我在这里使用观察者模式写了一个详细的例子:


如果您有兴趣将用户界面和逻辑实现分开。 MVC 是另一个可行的选择。您的 Model 将仅包含您的逻辑和数据,而您的 View 仅包含您的 UI.

ModelView不需要知道对方的存在。您将使用链接视图和模型的 Controller。这样它就大大解耦了你的代码。所以有一天,如果你决定改变你的逻辑,UI 不受影响。

如果您决定更改 UI,逻辑也不受影响。


甚至可以结合观察者模式和 MVC。毕竟,这取决于你想要达到什么。