2

我有一个带有多个 JCheckBox 的 Swing 应用程序。每个JCheckBox对应Foo 于我程序中其他地方的另一个类型的对象。对于 type 的每个对象Foo,我将提供其中一个 JCheckBox 供用户单击(它告诉 Foo 对象它们是否应该显示在 UI 上)。

我目前正在做的是使用名称属性JCheckBox作为对Foo对象字符串“名称”的引用。我觉得一个更干净的解决方案是扩展JCheckBox以向其添加一个额外的字段,以便JCheckBox可以通过简单地存储对它的引用来跟踪它附加到哪个 Foo 对象。想法?人们是否定期扩展 Swing 组件,以便他们可以将控制器/视图中的部件链接回模型?我会遇到一些可怕的陷阱吗?

4

3 回答 3

4

如果没有额外的细节,很难了解这个特定示例的全貌。您可以使用操作来完成此任务。有关更多详细信息,请参阅如何使用操作。这是一个例子:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class CheckBoxDemo {

    static class Foo {
        private boolean visible;
        private String name;

        public Foo(String name) {
            this.name = name;
        }

        public boolean isVisible() {
            return visible;
        }

        public void setVisible(boolean visible) {
            this.visible = visible;
            System.out.println(getName() + ".setVisible:" + visible);
        }

        public String getName() {
            return name;
        }
    }

    static class FooAction extends AbstractAction {
        private Foo foo;

        public FooAction(Foo foo) {
            super(foo.getName());
            this.foo = foo;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            JCheckBox checkBox = (JCheckBox) e.getSource();
            foo.setVisible(checkBox.isSelected());
        }
    }

    private static void createAndShowGUI() {
        List<Foo> fooList = new ArrayList<Foo>();
        fooList.add(new Foo("Foo1"));
        fooList.add(new Foo("Foo2"));
        fooList.add(new Foo("Foo3"));

        JPanel content = new JPanel(new BorderLayout());

        JPanel fooPanel = new JPanel();
        for (Foo foo : fooList) {
            fooPanel.add(new JCheckBox(new FooAction(foo)));
        }

        content.add(fooPanel, BorderLayout.NORTH);

        final JTextArea textArea = new JTextArea();
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setPreferredSize(new Dimension(200, 200));
        content.add(scrollPane, BorderLayout.CENTER);

        JFrame frame = new JFrame("CheckBoxDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(content);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        // just for brevity of example
        System.setOut(new PrintStream(new OutputStream() {
            @Override
            public void write(int b) throws IOException {
                textArea.append(String.valueOf((char) b));
            }
        }));
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
于 2012-09-08T05:27:51.310 回答
3

一般规则是不要出于应用原因扩展 JSomething:它们被设计为按原样使用

您的上下文听起来像是一个绑定场景。@Max 建议(使用动作作为绑定代理)指出了要遵循的方向,对于更复杂的要求,您可以考虑使用绑定框架(如 JGoodies 或 BetterBeansBinding)

于 2012-09-08T06:16:46.540 回答
0

这是一个常见的要求,您可以将JCheckboxa 扩展到JFooCheckBox其中包含 Foo 对象的某些对象,并且侦听器应负责 Foo 的显示/隐藏。

于 2012-09-08T03:44:22.327 回答