JButton&动作&键绑定 [英] JButton & Action & KeyBinding

查看:141
本文介绍了JButton&动作&键绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个接收Action的JButton类,JButton类包含了击键&鼠标监听器,所以我可以根据需要在多个框架中使用相同的类。



我的问题是:
按键时JButton没有得到焦点,它正在做的行动。
i需要做一个新的背景或者告诉用户该按钮做了什么。



任何想法??



以下是我的代码:

  import java.awt.Color; 
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
导入swtdesigner.SwingResourceManager;

public class IButtonSave extends JButton {
private static final long serialVersionUID = 1L;
private Action action = null;
public IButtonSave(){
super();
setFocusPainted(true);
setFocusable(true);

尝试{
jbInit();
} catch(Throwable e){
e.printStackTrace();


$ b private void jbInit()抛出异常{
setMargin(new Insets(0,0,0,0));
setBorder(new LineBorder(Color.black,1,true));
setIconTextGap(0);
setHorizo​​ntalTextPosition(SwingConstants.CENTER);
setVerticalTextPosition(SwingConstants.TOP);
setPreferredSize(new Dimension(50,43));
setMinimumSize(new Dimension(50,43));
setMaximumSize(new Dimension(50,43));
addMouseListener(new ThisMouseListener());
setVerifyInputWhenFocusTarget(true);
}

public void setAction(Action a){
action = a;
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F1,0,true);
KeyStroke ks2 = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0);
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks,Save);
getInputMap(JComponent.WHEN_FOCUSED).put(ks2,Save);

getActionMap()。put(Save,a);
setText(保存[F1]);
setIcon(SwingResourceManager.getIcon(SwingResourceManager.class,/images/small/save.png));
setToolTipText([F1]);


private class ThisMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e){
this_mouseClicked(e);

$ b protected void this_mouseClicked(MouseEvent e){
if(e.getClickCount()> = 1){
action.actionPerformed(null);




$ div class =h2_lin>解决方案

为什么要扩展 JButton 类,只需要将 KeyBinding s添加到它的实例?



不知道你想要什么,但是这对我来说工作正常:

基本上是一个 JButton 可以通过鼠标点击激活,或者按 F1 (只要焦点在窗口中,如果按下,焦点将转移到 JButton )或 ENTER (仅限于 JButton 的焦点)。

当调用 AbstractAction 时,它会调用 requestFocusInWindow() JButton (因此按下 F1 将使按钮增益焦点,这是我认为你想要的):




  import java.awt.BorderLayout; 
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
导入javax.swing.SwingUtilities;
$ b $ public class Test {

public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JButton btn = new JButton Button);

AbstractAction aa = new AbstractAction(){
@Override
public void actionPerformed(ActionEvent ae){
System.out.println(这里);

btn.requestFocusInWindow(); //请求按钮具有焦点
}
};

// so button can使用F1和ENTER键
btn.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),Enter);
btn.getActionMap()。put(Enter,aa);
btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1,0),F1);
btn.getActionMap()。put(F1,aa);

btn.addActionListener(aa); //如此按钮可以被点击

JTextField tf = new JTextField(添加到显示ENTER不会工作,除非按钮焦点);

frame.add(tf);
frame.add(btn,BorderLayout.SOUTH);

frame.pack();
frame.setVisible(true);
}
});




UPADTE: p>

或者以@GuillaumePolet建议(+1给他)覆盖 processKeyBinding JButton 并检查合适的键并调用方法:

$ p $ import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
导入javax.swing.SwingUtilities;
$ b $ public class Test {

public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JButton btn = new JButton (Button){
@Override
protected boolean processKeyBinding(KeyStroke ks,KeyEvent ke,int i,boolean bln){
boolean b = super.processKeyBinding(ks,ke,i, bn);

if(b&& ks.getKeyCode()== KeyEvent.VK_F1){
requestFocusInWindow();
}

返回b;
}
};

AbstractAction aa = new AbstractAction(){
@Override
public void actionPerformed(ActionEvent ae){
System.out.println(Here);
}
};

//所以按钮可以使用F1和ENTER按钮
btn.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),Enter);
btn.getActionMap()。put(Enter,aa);
btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1,0),F1);
btn.getActionMap()。put(F1,aa);

btn.addActionListener(aa); //如此按钮可以被点击

JTextField tf = new JTextField(添加到显示ENTER不会工作,除非按钮焦点);

frame.add(tf);
frame.add(btn,BorderLayout.SOUTH);

frame.pack();
frame.setVisible(true);
}
});
}
}


I have created a JButton class that recieving Action, the JButton class includes keystrokes & mouse listener so i can use the same class in multiple frames as needed.

My problems is that: JButton not getting the focus when pressing the key, but it doing the action. i need to make a new background or something that tell the user that the button did the action.

Any ideas??

Here is my code:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import swtdesigner.SwingResourceManager;

public class IButtonSave extends JButton{
    private static final long serialVersionUID = 1L;
    private Action action = null;
    public IButtonSave() {
        super();
        setFocusPainted(true);
        setFocusable(true);

        try {
            jbInit();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    private void jbInit() throws Exception {
        setMargin(new Insets(0, 0, 0, 0));
        setBorder(new LineBorder(Color.black, 1, true));
        setIconTextGap(0);
        setHorizontalTextPosition(SwingConstants.CENTER);
        setVerticalTextPosition(SwingConstants.TOP);
        setPreferredSize(new Dimension(50, 43));
        setMinimumSize(new Dimension(50, 43));
        setMaximumSize(new Dimension(50, 43));
        addMouseListener(new ThisMouseListener());
        setVerifyInputWhenFocusTarget(true);
    }

    public void setAction(Action a){
        action = a;
        KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F1,0,true);
        KeyStroke ks2 = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0);
        getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "Save");
        getInputMap(JComponent.WHEN_FOCUSED).put(ks2, "Save");

        getActionMap().put("Save", a);
        setText("Save [F1]");
        setIcon(SwingResourceManager.getIcon(SwingResourceManager.class, "/images/small/save.png"));
        setToolTipText("[F1]");
    }

    private class ThisMouseListener extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            this_mouseClicked(e);
        }
    }
    protected void this_mouseClicked(MouseEvent e) {
        if(e.getClickCount() >= 1){
            action.actionPerformed(null);
        }
    }
}

解决方案

Why extend JButton class when you can simply add KeyBindings to its instance?

Not to sure what you want but this works fine for me:

Basically a JButton which can be activated by mouse click, or pressing F1 (as long as focus is in window and if pressed will shift focus to JButton) or ENTER (only when in focus of JButton).

When the AbstractAction is called it will call requestFocusInWindow() on JButton (thus pressing F1 will make button gain focus which is what I think you wanted):

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class Test {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                final JButton btn = new JButton("Button");

                AbstractAction aa = new AbstractAction() {
                    @Override
                    public void actionPerformed(ActionEvent ae) {
                        System.out.println("Here");

                        btn.requestFocusInWindow();//request that the button has focus
                    }
                };

                //so button can be pressed using F1 and ENTER
                btn.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "Enter");
                btn.getActionMap().put("Enter", aa);
                btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), "F1");
                btn.getActionMap().put("F1", aa);

                btn.addActionListener(aa);//so button can be clicked

                JTextField tf = new JTextField("added to show ENTER wont work unless button in focus");

                frame.add(tf);
                frame.add(btn, BorderLayout.SOUTH);

                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

UPADTE:

alternatively as @GuillaumePolet suggested (+1 to him) override processKeyBinding of JButton and check for appropriate key and than call the method:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class Test {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                final JButton btn = new JButton("Button") {
                    @Override
                    protected boolean processKeyBinding(KeyStroke ks, KeyEvent ke, int i, boolean bln) {
                        boolean b = super.processKeyBinding(ks, ke, i, bln);

                        if (b && ks.getKeyCode() == KeyEvent.VK_F1) {
                            requestFocusInWindow();
                        }

                        return b;
                    }
                };

                AbstractAction aa = new AbstractAction() {
                    @Override
                    public void actionPerformed(ActionEvent ae) {
                        System.out.println("Here");
                    }
                };

                //so button can be pressed using F1 and ENTER
                btn.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "Enter");
                btn.getActionMap().put("Enter", aa);
                btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), "F1");
                btn.getActionMap().put("F1", aa);

                btn.addActionListener(aa);//so button can be clicked

                JTextField tf = new JTextField("added to show ENTER wont work unless button in focus");

                frame.add(tf);
                frame.add(btn, BorderLayout.SOUTH);

                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

这篇关于JButton&动作&键绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆