有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

javajavax。摆动JCheckBox setSelected未从GUI调用

我试图扩展一些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);
    }
}

起来 我已经有了支持“撤销/重做”操作的组件包。我刚刚向所有组件添加了addUndoableEditListener(UndoableEditListener l)方法,所以实现隐藏在我的组件中。这就是我扩展Swing组件而不是使用动作侦听器的原因


共 (3) 个答案

  1. # 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 );
          }
        } );
      }
    }
    

    当按钮后面模型的选定状态发生变化时,允许确定stacktrace。stacktrace显示了以下相关部分

    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)
    

    基本上,监听器直接与按钮模型交互

  2. # 2 楼答案

    如果只想监听此更改,请使用ItemListener(它甚至会监听ButtonGroup更改或setSelected方法调用所产生的事件):

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

    如果您只想从“UI”接收更改,也可以添加ActionListener

    但是如果你真的想知道复选框是如何改变“UI”的状态的

    JCheckBox只是一个简单的按钮,每个状态都有合适的图标,所以我们应该看到JButton事件

    在JButton类中听鼠标没有任何意义——它隐藏在当前ButtonUI的内部

    在BasicButtoni类中,您可以找到添加到其中的侦听器:

    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 );
        }
    } );
    
  3. # 3 楼答案

    您需要add^{}到复选框