JButton

时间:2015-07-16 08:17:49

标签: java swing mouseevent jbutton dispatchevent

我在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在进入下一个之前工作呢?

非常感谢任何帮助或见解。

3 个答案:

答案 0 :(得分:1)

  

如何逐个触发一系列dispatchEvents   用户注意到了吗?我怎样才能使程序等待当前   dispatchEvent在进入下一个之前运用它的魔力?

答案 1 :(得分:1)

  

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

利用按钮提供的翻转支持,请参阅JButton#setRolloverEnabled& JButton#setRolloverIcon

  

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

稍微困难一些,但您可以使用ButtonModel的监听器进行更改并根据您的要求更新图标

  

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

应该通过使用ActionListener

来实现
  

我试图让ENTER按下相同的路线:

JButton#doClick将自动浏览模型的isArmedisPressed状态,这将触发之前评论提供的状态更改...

用鼠标......

WithMouse

使用键盘......

WithKeyboard

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)。