2

複数の JCheckBox を持つ Swing アプリがあります。それぞれ が私のプログラムの他の場所にJCheckBoxあるタイプの別のオブジェクトに対応しています。Footype のオブジェクトごとFooに、これらの JCheckBox の 1 つをユーザーがクリックできるようにします (UI に表示するかどうかを Foo オブジェクトに伝えます)。

私が現在行っているのは、オブジェクトJCheckBoxの文字列「name」への参照としてname 属性を使用することです。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

これは一般的な要件であり、Foo オブジェクトを含むものにJCheckboxa を非常に拡張できJFooCheckBox、リスナーが Foo の表示/非表示を処理する必要があります。

于 2012-09-08T03:44:22.327 に答える