JButton:在没有动作射击的情况下模拟JButton按下

时间:2013-12-07 11:16:44

标签: java swing jbutton

我的用例是我有一些JButton可以向ActionListener发起操作。我还使用击键来向AcionListener发出一些相同的动作命令。当击键快捷键触发一个也由其中一个按钮完成的动作时,我希望按钮看起来好像被按下了但不能触发事件。

所以我查看了AbstractButton API,我尝试了一些类似setSelected的方法,但它没有达到预期的效果。最后我看了doCLick的方法,看看我是否可以使用删除动作触发部分,但这也不起作用

 367       public void doClick(int pressTime) {
 368           Dimension size = getSize();
 369           model.setArmed(true);
 370           model.setPressed(true);
 371           paintImmediately(new Rectangle(0,0, size.width, size.height));
 372           try {
 373               Thread.currentThread().sleep(pressTime);
 374           } catch(InterruptedException ie) {
 375           }
 376           model.setPressed(false);
 377           model.setArmed(false);
 378       }

我曾想过删除所有听众。运行doClick,然后再次添加它们,但我认为应该有更优雅的东西。

SSCE将是

public class Test {

public static void main(String[] args) throws InterruptedException{
    JFrame jf = new JFrame();
    jf.setLocationRelativeTo(null);
    JButton jb = new JButton("Test Button");
    jb.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("I don't want this to fire");
        }
    });
    jf.getContentPane().add(jb);
    jf.pack();
    jf.setVisible(true);

    Thread.sleep(1000);
    clickWithoutFiringAction(jb);
}

public static void clickWithoutFiringAction(JButton button){
    Dimension size = button.getSize();
    ButtonModel model = button.getModel();
            //I tried changing these combinations but I could not get the desired effect
    model.setArmed(true);
    model.setPressed(true);
    button.paintImmediately(new Rectangle(0,0, size.width, size.height));
    try {
        Thread.sleep(68);
    } catch(InterruptedException ie) {
    }
    model.setPressed(false);
    model.setArmed(false);
 }
}

3 个答案:

答案 0 :(得分:3)

JButton使用具有DefaultButtonModel函数的setPressed(boolean)来使用fireActionPerformed(ActionEvent e)函数生成执行操作的事件。您需要扩展此模型并为setPressed(boolean b)函数提供自定义实现,以避免触发操作事件。有关更多详细信息,请参阅此模型类的源代码。

class CustomModel extends DefaultButtonModel
{


    @Override
    public void setPressed(boolean b){
        if((isPressed() == b) || !isEnabled()) {
            return;
        }

        if (b) {
            stateMask |= PRESSED;
        } else {
            stateMask &= ~PRESSED;
        }

        fireStateChanged();
    }

}

现在,您可以设置模型:jButton.setModel(new CustomModel());

答案 1 :(得分:1)

如果希望通过左键单击JButton来使用动作侦听器,并且想要在不单击JBUtton的情况下执行操作,则可以编写一个单独的公共方法来执行操作。

就像你使用clickWithoutFiringAction方法一样。

现在,您的所有动作监听器都要执行单独的公共方法。

        final JButton jb = new JButton("Test Button");
        jb.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                clickWithoutFiringAction(jb);
            }
        });

答案 2 :(得分:0)

嘿,我没有仔细阅读,就像Sage写道,你必须提供setPressed()的自定义实现。

<击> 你的例子很好用。你没有看到效果,因为model.setPressed(true);model.setPressed(false);之间的延迟很短,只有68毫秒。将Thread.sleep();中的值增加到几秒钟,您将看到效果。

<击>
 model.setArmed(true);
 model.setPressed(true);
 button.paintImmediately(new Rectangle(0,0, size.width, size.height));
 try {
    Thread.sleep(68); // to short delay.
 } catch(InterruptedException ie) {
 }
 model.setPressed(false);
 model.setArmed(false);

<击>

相关问题