我在Java Swing应用程序中有一个自定义的JButton。 它会根据鼠标事件改变它的外观 MouseEvent.MOUSE_ENTERED - 将触发按钮的悬停图像。 MouseEvent.MOUSE_PRESSED - 将触发按下的图像 MouseEvent.MOUSE_RELEASED - 将前景更改为灰色并禁用按钮 通过实际鼠标点击,这可以正常工作。
我想添加一个按ENTER键的支持
只是简单地调用button.doClick()
没有经历悬停 - 按下 - 释放周期,而只是跳转到发布事件。
所以我有这个简短有效的代码来做这件事。
InputMap im = workspacePnl.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = workspacePnl.getActionMap();
im.put(KeyStroke.getKeyStroke("ENTER"), "connect");
am.put("connect", new ConectAction());
private class ConectAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent ev) {
simulateClick();
}
和有问题的代码:
public void simulateClick() {
MouseEvent evt;
evt = new MouseEvent(connectBtn,
MouseEvent.MOUSE_ENTERED, 1, 0, 0, 0, 1, false);
connectBtn.dispatchEvent((AWTEvent) evt);
//CommonUtil.sleep(300);
evt = new MouseEvent(connectBtn,
MouseEvent.MOUSE_PRESSED, 8, 0, 0, 0, 1, false);
connectBtn.dispatchEvent((AWTEvent) evt);
//CommonUtil.sleep(300);
evt = new MouseEvent(connectBtn,
MouseEvent.MOUSE_RELEASED, 20, 0, 0, 0, 1, false);
connectBtn.dispatchEvent((AWTEvent) evt);
}
我正在尝试让ENTER按下相同的路径:
触发MOUSE_ENTERED事件,该事件将改变按钮的悬停外观,然后是MOUSE_PRESSED和MOUSE_RELEASED。
但我只看到最后的事件效果。就好像我只是单独发射最后一个事件而缺乏交互式软件的活力。
我尝试(可以看出已注释掉)让线程在每个事件触发后进入休眠状态,但它没有任何效果。
如果我尝试触发其他两个事件中的每一个,它们在屏幕上会自行显示出来。这是混乱在一起让事情变得混乱。
如何逐个触发一系列dispatchEvents,这些都会被用户注意到?我怎样才能使程序等待当前的dispatchEvent在进入下一个之前工作呢?
非常感谢任何帮助或见解。
答案 0 :(得分:1)
如何逐个触发一系列dispatchEvents 用户注意到了吗?我怎样才能使程序等待当前 dispatchEvent在进入下一个之前运用它的魔力?
答案 1 :(得分:1)
MouseEvent.MOUSE_ENTERED - 将触发按钮的悬停图像。
利用按钮提供的翻转支持,请参阅JButton#setRolloverEnabled
& JButton#setRolloverIcon
MouseEvent.MOUSE_PRESSED - 将触发按下的图像。
稍微困难一些,但您可以使用ButtonModel
的监听器进行更改并根据您的要求更新图标
MouseEvent.MOUSE_RELEASED - 将前景更改为灰色并禁用该按钮。
应该通过使用ActionListener
我试图让ENTER按下相同的路线:
JButton#doClick
将自动浏览模型的isArmed
和isPressed
状态,这将触发之前评论提供的状态更改...
用鼠标......
使用键盘......
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton btn = new JButton();
try {
btn.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("/Trash01.png"))));
btn.setRolloverIcon(new ImageIcon(ImageIO.read(getClass().getResource("/Trash02.png"))));
btn.setRolloverEnabled(true);
// btn.setSelectedIcon(new ImageIcon(ImageIO.read(getClass().getResource("/Trash03.png"))));
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
btn.getModel().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (btn.getModel().isPressed()) {
try {
btn.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("/Trash03.png"))));
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
try {
btn.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("/Trash01.png"))));
} catch (IOException ex) {
ex.printStackTrace();
}
}
System.out.println("Armed: " + btn.getModel().isArmed());
System.out.println("Enabled: " + btn.getModel().isEnabled());
System.out.println("Pressed: " + btn.getModel().isPressed());
System.out.println("Rollover: " + btn.getModel().isRollover());
System.out.println("Selected: " + btn.getModel().isSelected());
}
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(btn, gbc);
add(new JTextField("Stealer of focus"), gbc);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
btn.setEnabled(false);
}
});
InputMap im = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke("ENTER"), "connect");
am.put("connect", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
System.out.println("click");
btn.doClick();
}
});
}
}
}
答案 2 :(得分:0)
由于您的整个代码都在EventDispatchingThread (EDT)
上运行,因此它正在一起批处理。
当您从simulateClick()
致电actionPerformed()
时,请在新主题上调用它而不是相同的主题(将是EDT)。