5

私は最近、UML図で指定されたプログラムをコードで実装する必要があるプログラミング割り当てを行っていました。ある時点で、図は、カウント(1から開始)を表示し、クリックされるたびにデクリメントする匿名のJButtonを作成する必要があることを示していました。JButtonとそのActionListenerは両方とも匿名である必要がありました。

私は次の解決策を思いついた:

public static void main(String[] args) {
  JFrame f = new JFrame("frame");
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  f.setSize(400, 400);

  f.getContentPane().add(new JButton() {

    public int counter;

    {
      this.counter = 1;
      this.setBackground(Color.ORANGE);
      this.setText(this.counter + "");

      this.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
          counter --;
          setText(counter + "");
        }
      });

    }
  });

  f.setVisible(true);

}

これにより、匿名のJButtonが追加され、次に別の(内部の)匿名のActionListenerが追加されて、イベントが処理され、必要に応じてボタンのテキストが更新されます。より良い解決策はありますか?匿名を宣言することはできないと確信していますがJButton implements ActionListener ()、同じ結果を達成するためのよりエレガントな方法は他にありますか?

4

6 に答える 6

13

私は通常次のようなことをします:

JPanel panel = new JPanel();
panel.add(new JButton(new AbstractAction("name of button") {
    public void actionPerformed(ActionEvent e) {
        //do stuff here
    }
}));

AbstractActionはActionListenerを実装するため、これでタスクが満たされるはずです。

非常に多くのコード行を一緒に押しつぶすことは悪い習慣かもしれませんが、それを読むことに慣れているなら、それは非常にエレガントである可能性があります。

于 2009-05-21T04:33:58.000 に答える
2

複数のタイプを実装することは、一般的には悪い考えです。

クラスを拡張する必要はめったにありませんJComponentが、多くの悪いソフトウェアやチュートリアルがそれを行っています。with最近人気を博しているイディオム/ハックは、ダブルブレースです。クラスは、他の言語のステートメントのように機能するインスタンス初期化子を与えるためのサブクラスにすぎません。

この場合、関連するコードは次のように記述できます。

JButton button = new JButton();
button.addActionListener(new ActionListener() {
    int counter = 1;
    {
        updateText();
    }
    public void actionPerformed(ActionEvent arg0) {
        --counter;
        updateText();
    }
    private void updateText()
        setText(Integer.toString(counter));
    }
});
f.getContentPane(button);

より複雑になる場合は、データを処理する外部クラス ( を実装ActionListenerまたは拡張しないJButton) を作成することをお勧めします。

EventQueue.invokeLaterまた、ボイラープレートを使用して、Swing コンポーネントが AWT EDT でのみ使用されるようにする必要があることにも注意してください。

于 2009-05-21T10:29:22.693 に答える
1

私は実際のプログラムではそのようなことはしませんが、課題の要件を考えると、これ以上のことはほとんどできません。

于 2009-05-21T04:41:50.937 に答える
1

それを行うためのはるかにエレガントな方法があります。

残念ながら、これは Core Java/Swing アプローチではありません。

Groovy で SwingBuilder を使用して、もう少し簡潔な構文 (疑似コードなど) を使用して同じ結果を得ることができます。

button(text: '' + counter,
         actionPerformed: {counter--; text = '' + counter + ''},
         constraints:BL.SOUTH)

[ http://groovy.codehaus.org/Swing+Builder][1]

私はあなたの課題ではこれを使用しませんが、学生が実際に標準から逸脱し、それによって減点されるのを見てきましたが、少なくともさらに調査するための可能な手段としてそれを含めることができます.

今持っているものは絶対に大丈夫だと思います。

于 2009-05-21T04:43:53.603 に答える
0

これは、宿題でのみ行うことを余儀なくされている悪い習慣のタスクの 1 つです ;-) 悪いこと:

  • それ自体が悪い Action の代わりに ActionListener を使用する
  • その結果、スコーピングの問題が発生します
    • カウンターの範囲が必要以上に広い
    • actionPerformed 内のボタンにアクセスする必要があります (型キャストまたは周囲のオブジェクトの API へのアクセスを介して)
  • 読めない (別名: 保守不可能な) コード

しかし、それなら .. 抵抗することはできません ;-) これは Action を使用したバージョンで、最初の 2 つの問題に関してはクリーンです (またはそう思う)。匿名クラス、その後IDEにインライン化させます

    f.add(new JButton(new AbstractAction() {

        int counter = 1;
        { // constructor block of action
            updateName();
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            counter--;
            updateName();
        }

        private void updateName() {
            putValue(Action.NAME, "" + counter);
        }

    })  { // subclass button 
          {  // constructor block button
            setBackground(Color.PINK);
        }}
    );
于 2011-05-04T16:16:49.373 に答える