java – JButton&Action&KeyBinding
作者:互联网
我创建了一个接收Action的JButton类,JButton类包括击键和&鼠标监听器,所以我可以根据需要在多个帧中使用相同的类.
我的问题是:
按下键时JButton没有获得焦点,但它正在执行操作.
我需要创建一个新的背景或告诉用户按钮执行操作的东西.
有任何想法吗??
这是我的代码:
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);
}
}
}
解决方法:
为什么在只需将KeyBindings添加到其实例时扩展JButton类?
不确定你想要什么,但这对我来说很好:
基本上是一个JButton,它可以通过鼠标点击激活,或按F1(只要焦点在窗口中,如果按下将焦点转移到JButton)或ENTER(仅在焦点在JButton时).
当调用AbstractAction时,它将在JButton上调用requestFocusInWindow()(因此按下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;
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:
或者作为@GuillaumePolet建议(1对他)重写JButton的processKeyBinding并检查适当的键,然后调用方法:
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);
}
});
}
}
标签:java,focus,swing,key-bindings,jbutton 来源: https://codeday.me/bug/20190725/1536574.html