【问题标题】:javax.swing.JCheckBox setSelected is not calling from GUIjavax.swing.JCheckBox setSelected 未从 GUI 调用
【发布时间】:2012-05-14 20:43:42
【问题描述】:

我正在尝试扩展一些 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 组件而不是使用动作侦听器的原因。

【问题讨论】:

  • 我的第一个问题:为什么要扩展这些组件而不是简单地使用它们?
  • 你为什么假设 GUI 正是调用这个方法来设置值?如果您想在进行更改时启动操作,则应使用适当的侦听器。
  • 我自己,我将扩展我添加到我的 JCheckBox 的 AbstractAction。
  • 关于你的“UP”:我认为这是一个不好的理由。如果您想扩展附加到组件的操作,请不要扩展视图或组件本身,因为您的目标与显示组件无关。简而言之:不要扩展组件;错了。

标签: java swing overriding jcheckbox


【解决方案1】:

如果您只想监听此更改 - 使用 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 );
    }
} );

【讨论】:

  • 请记住,每个 Swing 组件都有自己的 UI 类,并且可能存在一些/全部/无动作/鼠标/键侦听器。这仅取决于组件类型和 Swing 开发人员创建它的方式。无论如何,如果您将 JDK 源附加到您的 IDE 并在需要时查看它们,则很容易找到有关它的任何信息。
【解决方案2】:

您需要addActionListener 到复选框。

【讨论】:

    【解决方案3】:

    尽管所有的 cmets 都是相关的,并且可能不需要扩展这些组件,但我做了一个快速测试,以确定单击按钮时遵循的代码路径(只是出于好奇)。下面这段代码

    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)
    

    所以基本上听者直接与按钮模型交互。

    【讨论】:

      猜你喜欢
      • 2022-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多