Java JButton上的多个dispatchEvent调用

Java JButton上的多个dispatchEvent调用,java,swing,mouseevent,jbutton,dispatchevent,Java,Swing,Mouseevent,Jbutton,Dispatchevent,我在JavaSwing应用程序中有一个定制的JButton。 它会根据鼠标事件更改其外观。 MouseEvent.MOUSE_ENTERED-将触发按钮的悬停图像。MouseEvent.MOUSE_按下-将触发按下的图像。 MouseEvent.MOUSE_RELEASED-将前景更改为灰色并禁用按钮。 这在实际的鼠标点击中运行良好 我想添加对按ENTER键的支持。 只需调用按钮。doClick()并没有经过悬停按钮释放周期,而是直接跳转到释放事件 所以我有一个简短而有效的代码来做这件事 Inp

我在JavaSwing应用程序中有一个定制的JButton。 它会根据鼠标事件更改其外观。
MouseEvent.MOUSE_ENTERED-将触发按钮的悬停图像。MouseEvent.MOUSE_按下-将触发按下的图像。
MouseEvent.MOUSE_RELEASED-将前景更改为灰色并禁用按钮。
这在实际的鼠标点击中运行良好

我想添加对按ENTER键的支持。
只需调用
按钮。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);
    }
我试图让回车键通过相同的路径:
触发鼠标输入的事件,该事件将改变鼠标悬停按钮的外观,然后按下鼠标并释放鼠标。
但我只看到最后一个事件效果。这就好像我只是单独启动了最后一个事件,它缺乏互动软件的生动性。 我尝试(正如可以看到的那样)在每次事件触发后让线程进入睡眠状态,但没有效果。 如果我尝试触发其他两个事件中的每一个,它们在屏幕上都会很明显。把事情搞砸的是配料

我怎样才能一个接一个地触发一系列用户会注意到的dispatchEvents?我怎样才能让程序等待当前的dispatchEvent发挥作用,然后再大步前进到下一个dispatchEvent

如有任何帮助或见解,将不胜感激

我怎样才能一个接一个地触发一系列的dispatchEvents呢 用户注意到了吗?我如何使程序等待当前时间 在大步前进到下一步之前,调度事件是否会发挥其魔力

  • 鼠标和按键事件在ButtonComponents中正确实现,不要使用MouseListener,要使用来自、通过使用、用于的事件

    • 这是批处理,因为您的整个代码都在
      事件调度线程(EDT)
      上运行

      actionPerformed()
      调用
      simulatedlick()
      时,在新线程而不是同一线程(将是EDT)上调用它

      MouseEvent.MOUSE_ENTERED-将触发按钮的悬停图像

      使用按钮提供的防滚翻支架,参见

      MouseEvent.MOUSE_PRESSED-将触发按下的图像

      有点困难,但您可以使用
      按钮的侦听器来更改模型,并根据您的要求更新图标

      MouseEvent.MOUSE_RELEASED-将前景更改为灰色,并禁用按钮

      应该通过使用
      ActionListener

      我试图让回车键通过相同的路径:

      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();
                      }
                  });
              }
      
          }
      
      }
      


      “MouseEvent.MOUSE_ENTERED-将触发按钮的悬停图像。”-&“MouseEvent.MOUSE_PRESSED-将触发按下的图像。”-&/或
      public void simulatedclick(){
      …doClick有什么问题吗?
      ?这并不能解决我的问题。我确实可以使用这种方法来更好地自定义按钮(也许吧。我没有尝试过,所以我不知道这是否会引入错误),但我仍然需要在没有物理鼠标帮助的情况下手动调用这些事件,以创建实际按下的假象。我写道doClick什么也没做。实际上,它大部分都做了。出于您的需要,您可能需要伪造“所选图标”在
      JButton
      按钮model
      上使用
      ChangeListener
      ,假设您希望在按下[Enter]键时显示“所选图标”按钮。
      doClick
      对您不起作用的原因是您没有监控更改按钮的型号是的,让我们违反Swing的单线程规则,这不会伤害任何人