JButton&动作&键绑定 [英] JButton & Action & KeyBinding
问题描述
我的问题是:
按键时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);
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(保存[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 KeyBinding
s 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屋!