0

いくつかの Swing コンポーネントを拡張し、その状態と対話するメソッドをオーバーライドしようとしています (JComboBox の setSelectedIndex、JCheckBox の setSelected など)。JCheckBox に問題があります。setSelected メソッドをオーバーライドしましたが、ユーザーが UI を介して JCheckBox の状態を変更したときに呼び出されないようです。メソッドを呼び出すことで JCheckBox の状態を変更できますが、GUI は別の方法で状態を変更しているようです。クラスでそのイベントをキャッチするにはどうすればよいですか? Swing の他のクラスでは、すべて問題なく、オーバーライドされたすべてのメソッドが正しく機能します。

public class MyCheckBox extends JCheckBox {
    @Override
    public void setSelected(boolean selected) {
        //Method is not performed when MyCheckBox is clicked
        super.setSelected(selected);
    }
}

UP.: 「元に戻す/やり直し」アクションをサポートするコンポーネントのパッケージを作成しました。addUndoableEditListener(UndoableEditListener l) メソッドをすべてのコンポーネントに追加したので、実装はコンポーネント内に隠されています。そのため、アクション リスナーを使用する代わりに Swing コンポーネントを拡張します。

4

3 に答える 3

2

この変更を単純にリッスンする場合は、ItemListener を使用します (ButtonGroup の変更または setSelected メソッド呼び出しによって行われたイベントもリッスンします)。

checkBox.addItemListener ( new ItemListener ()
{
    public void itemStateChanged ( ItemEvent e )
    {
        System.out.println (isSelected ());
    }
} );

または、「UI」からのみ変更を受け取りたい場合は、ActionListener を追加します。

しかし、チェックボックスが「UI」から状態を変更する方法を本当に知りたい場合は...

JCheckBox は、状態ごとに適切なアイコンを持つ単純なボタンにすぎないため、JButton イベントが表示されるはずです。

JButton クラスでマウスをリッスンすることについては何もありません-現在の ButtonUI の内部に隠されています

BasicButtonUI クラスには、リスナーが追加されています。

protected void installListeners(AbstractButton b) {
    BasicButtonListener listener = createButtonListener(b);
    if(listener != null) {
        b.addMouseListener(listener);
        b.addMouseMotionListener(listener);
        b.addFocusListener(listener);
        b.addPropertyChangeListener(listener);
        b.addChangeListener(listener);
    }
}

マウスを離したときの BasicButtonListener:

public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
    // Support for multiClickThreshhold
        if (shouldDiscardRelease) {
        shouldDiscardRelease = false;
        return;
    }
    AbstractButton b = (AbstractButton) e.getSource();
    ButtonModel model = b.getModel();
    model.setPressed(false);
    model.setArmed(false);
    }
}

そのイベントは、ボタン内に設定された ButtonModel に送信されます。それをキャプチャするには、ボタン/チェック内の ButtonModel を独自のものに置き換える必要があります。

check.setModel ( new DefaultButtonModel ()
{
    public void setSelected ( boolean b )
    {
        super.setSelected ( b );
    }
} );
于 2012-05-05T16:08:54.070 に答える
1

すべてのコメントは関連性があり、おそらくこれらのコンポーネントを拡張する必要はありませんが、ボタンをクリックしたときにどのコード パスがたどられるかを簡単にテストしました (好奇心から)。次のコード

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
import java.awt.EventQueue;

public class JCheckBoxTest {

  private static JCheckBox createCheckBox(){
    JCheckBox checkBox = new JCheckBox();
    checkBox.setModel( new JToggleButton.ToggleButtonModel(){
      @Override
      public void setSelected( boolean b ) {
        Thread.dumpStack();
        super.setSelected( b );
      }
    });
    return checkBox;
  }

  public static void main( String[] args ) {
    EventQueue.invokeLater( new Runnable() {
      @Override
      public void run() {
        JFrame testFrame = new JFrame( "TestFrame" );
        testFrame.add( createCheckBox() );
        testFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        testFrame.pack();
        testFrame.setVisible( true );
      }
    } );
  }
}

ボタンの背後にあるモデルの選択状態が変更されたときに、スタック トレースを決定できます。スタックトレースは、次の関連部分を示しています

at JCheckBoxTest$1.setSelected(JCheckBoxTest.java:19)
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.java:289)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)

基本的に、リスナーはボタンモデルと直接対話します。

于 2012-05-05T16:09:14.600 に答える
1

チェックボックスに を追加する必要がありActionListenerます。

于 2012-05-05T16:07:08.657 に答える