Java 在手动单击组件之前,焦点不起作用
我正在尝试创建一个计算器,我正在使用键绑定器来允许用户输入数字,而不必手动按下按钮。但是,我注意到,直到我用鼠标按下其中一个按钮后,键夹才起作用。这是我的密码:Java 在手动单击组件之前,焦点不起作用,java,swing,focus,Java,Swing,Focus,我正在尝试创建一个计算器,我正在使用键绑定器来允许用户输入数字,而不必手动按下按钮。但是,我注意到,直到我用鼠标按下其中一个按钮后,键夹才起作用。这是我的密码: import java.awt.*; ... public class Calculator extends JFrame { static JFrame f = new JFrame(); static JPanel p = new JPanel(); static JButton[] b = new JB
import java.awt.*;
...
public class Calculator extends JFrame {
static JFrame f = new JFrame();
static JPanel p = new JPanel();
static JButton[] b = new JButton[19];
static String[] bs = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
".", "+", "-", "*", "/", "=", "C", "\u2190", "\u00B1" };
static JTextArea t = new JTextArea();
public static void main(String[] args) {
f.setSize(300, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
for (int i = 0; i < b.length; i++) {
b[i] = new JButton();
b[i].setText(bs[i]);
b[i].addActionListener(new BAction());
b[i].setFont(new Font("Arial", Font.BOLD, 17));
b[i].setFocusable(true);
}
setLayout(p, b);
f.add(p);
f.setVisible(true);
}
public static JPanel setLayout(JPanel p, JButton[] b) {
Image icon = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
f.setIconImage(icon);
GridBagLayout g = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
p.setLayout(g);
p.setSize(f.getSize());
t.setEditable(false);
t.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
t.setFont(new Font("Arial", Font.PLAIN, 15));
t.setFocusable(false);
t.setText("0");
f.setFocusable(true);
p.setFocusable(true);
key();
...
// GridBagLayouting here
...
return p;
}
static class BAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
...
// Assigning ActionEventListeners
...
}
@SuppressWarnings({ "serial" })
private static void key() {
// 0
Action b0 = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
b[0].doClick();
}
};
p.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD0, 0), "b0");
p.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_0, 0), "b0");
p.getActionMap().put("b0", b0);
// 1
Action b1 = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
b[1].doClick();
}
};
p.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD1, 0), "b1");
p.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "b1");
p.getActionMap().put("b1", b1);
// 2
Action b2 = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
b[2].doClick();
}
};
p.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD2, 0), "b2");
p.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_2, 0), "b2");
p.getActionMap().put("b2", b2);
// +
Action bplus = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
b[11].doClick();
}
};
p.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ADD, 0), "b+");
p.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS,
InputEvent.SHIFT_MASK), "b+");
p.getActionMap().put("b+", bplus);
}
}
import java.awt.*;
...
公共类计算器扩展JFrame{
静态JFrame f=新JFrame();
静态JPanel p=newjpanel();
静态JButton[]b=新JButton[19];
静态字符串[]bs={“0”、“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”、“9”,
“、“+”、“-”、“*”、“/”、“=”、“C”、“\u2190”、“\u00B1”};
静态JTextArea t=新JTextArea();
公共静态void main(字符串[]args){
f、 设置大小(300300);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f、 可设置大小(假);
for(int i=0;i
在创建绑定时,您可以在“聚焦”窗口中使用而不是“聚焦”组件的“祖先”时使用
更新
/**
* Constant used for <code>registerKeyboardAction</code> that
* means that the command should be invoked when the receiving
* component is an ancestor of the focused component or is
* itself the focused component.
*/
public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
/**
* Constant used for <code>registerKeyboardAction</code> that
* means that the command should be invoked when
* the receiving component is in the window that has the focus
* or is itself the focused component.
*/
public static final int WHEN_IN_FOCUSED_WINDOW = 2;
在创建绑定时,可以在聚焦组件的聚焦窗口中使用而不是而不是在聚焦组件的聚焦窗口中使用
更新
/**
* Constant used for <code>registerKeyboardAction</code> that
* means that the command should be invoked when the receiving
* component is an ancestor of the focused component or is
* itself the focused component.
*/
public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
/**
* Constant used for <code>registerKeyboardAction</code> that
* means that the command should be invoked when
* the receiving component is in the window that has the focus
* or is itself the focused component.
*/
public static final int WHEN_IN_FOCUSED_WINDOW = 2;
我使用按键夹允许用户输入数字,而不必手动按下按钮
不要为每个键绑定创建唯一的操作。您可以轻松创建一个操作供所有数字共享:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class CalculatorPanel extends JPanel
{
private JTextField display;
public CalculatorPanel()
{
Action numberAction = new AbstractAction()
{
@Override
public void actionPerformed(ActionEvent e)
{
display.setCaretPosition( display.getDocument().getLength() );
display.replaceSelection(e.getActionCommand());
}
};
setLayout( new BorderLayout() );
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
add(display, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setBorder( new LineBorder(Color.BLACK) );
button.setPreferredSize( new Dimension(50, 50) );
buttonPanel.add( button );
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke(text), text);
inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text);
button.getActionMap().put(text, numberAction);
}
}
private static void createAndShowUI()
{
// UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );
JFrame frame = new JFrame("Calculator Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new CalculatorPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入javax.swing.border.*;
公共类计算器面板扩展了JPanel
{
专用JTextField显示;
公共计算器面板()
{
Action numberAction=new AbstractAction()
{
@凌驾
已执行的公共无效操作(操作事件e)
{
display.setCaretPosition(display.getDocument().getLength());
display.replaceSelection(例如getActionCommand());
}
};
setLayout(新的BorderLayout());
display=新的JTextField();
display.setEditable(false);
display.setHorizontalAlignment(JTextField.RIGHT);
添加(显示,BorderLayout.NORTH);
JPanel buttonPanel=新的JPanel();
setLayout(新的GridLayout(0,5));
添加(按钮面板、边框布局、中心);
对于(int i=0;i<10;i++)
{
String text=String.valueOf(i);
JButton按钮=新JButton(文本);
addActionListener(numberAction);
button.setOrder(新行边框(颜色为黑色));
按钮。设置首选尺寸(新尺寸(50,50));
烟蒂