我的用例是我有一些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);
}
}
答案 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);
击> <击> 撞击>