我正在编写一个有键盘和JTextArea的程序。按下按钮后,按钮的颜色应与插入符号位置一起改变。我使用了Key Binding。现在,如果我先改变颜色然后移动插入符号,只有插入符号移动但颜色不会改变,反之亦然。以下是我的代码示例:(我有许多面板来组织其余按钮......)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ButtonGroup;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class KeyboardTest extends JFrame {
public static final JTextArea textToType = new JTextArea("jjj jjj jjj jjj kkk kkk kkk kkk jjj kkk jjj kkk jjj kkk jkj jkj jkj jkj kjk kjk kjk \r\nkjk jjj jjj jjj kkk kkk kkk jk jk jk kj kj kj jj kk jk kj kj jk jj jk kk kj j j j j k \r\nk k k j k k j j k k j jkj jjk kjj kkj jkk kkk jjj kjk");
public static final int caretPosition = 0;
public static void main(String[] args) {
new KeyboardTest();
}
public KeyboardTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception ex) {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setBounds(100, 100, 650, 390);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JPanel contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
add(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[] { 614, 0 };
gbl_contentPane.rowHeights = new int[] { 31, 14, 51, 181, 25, 0 };
gbl_contentPane.columnWeights = new double[] { 0.0,
Double.MIN_VALUE };
gbl_contentPane.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0,
0.0, Double.MIN_VALUE };
contentPane.setLayout(gbl_contentPane);
JLabel title = new JLabel(
"Our first touch typing lesson introduces 2 home row keys for the right hand: j k");
GridBagConstraints gbc_title = new GridBagConstraints();
gbc_title.fill = GridBagConstraints.BOTH;
gbc_title.insets = new Insets(0, 0, 5, 0);
gbc_title.gridx = 0;
gbc_title.gridy = 1;
contentPane.add(title, gbc_title);
textToType.setEditable(false);
textToType.setFont(new Font("Lucida Console", Font.PLAIN, 12));
textToType.setBackground(new Color(255, 250, 205));
textToType
.setText("jjj jjj jjj jjj kkk kkk kkk kkk jjj kkk jjj kkk jjj kkk jkj jkj jkj jkj kjk kjk kjk \r\nkjk jjj jjj jjj kkk kkk kkk jk jk jk kj kj kj jj kk jk kj kj jk jj jk kk kj j j j j k \r\nk k k j k k j j k k j jkj jjk kjj kkj jkk kkk jjj kjk");
textToType.getCaret().setVisible(true);
textToType.setCaretPosition(caretPosition);
textToType.setFocusable(false);
GridBagConstraints gbc_textToType = new GridBagConstraints();
gbc_textToType.fill = GridBagConstraints.BOTH;
gbc_textToType.insets = new Insets(0, 0, 5, 0);
gbc_textToType.gridx = 0;
gbc_textToType.gridy = 2;
contentPane.add(textToType, gbc_textToType);
JPanel keyboardPanel = new JPanel();
GridBagConstraints gbc_keyboardPanel = new GridBagConstraints();
gbc_keyboardPanel.fill = GridBagConstraints.BOTH;
gbc_keyboardPanel.insets = new Insets(0, 0, 5, 0);
gbc_keyboardPanel.gridx = 0;
gbc_keyboardPanel.gridy = 3;
contentPane.add(keyboardPanel, gbc_keyboardPanel);
keyboardPanel.setLayout(new GridLayout(5, 0, 0, 0));
JPanel kPanel1 = new JPanel();
keyboardPanel.add(kPanel1);
kPanel1.setLayout(null);
JPanel buttonspanel1 = new JPanel();
buttonspanel1.setBounds(0, 0, 523, 36);
kPanel1.add(buttonspanel1);
buttonspanel1.setLayout(new GridLayout(0, 13, 0, 5));
JButton one = new JButton("1");
one.setFocusable(false);
buttonspanel1.add(one);
addKeyBindingGreen(one, "1", KeyEvent.VK_1);
addKeyBinding(one, "1", KeyEvent.VK_1);
}
//Key Binding to change the button to green...
protected void addKeyBindingGreen(JButton btn, String name,
int virtualKey) {
ActionMap am = getActionMap();
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(virtualKey, 0, false), name
+ ".pressed");
im.put(KeyStroke.getKeyStroke(virtualKey, 0, true), name
+ ".released");
am.put(name + ".pressed", new KeyActionGreen(btn, true));
am.put(name + ".released", new KeyActionGreen(btn, false));
}
//Key binding to move the caret
protected void addKeyBinding(JButton btn, String name,
int virtualKey) {
ActionMap am = getActionMap();
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(virtualKey, 0, false), name
+ ".pressed");
im.put(KeyStroke.getKeyStroke(virtualKey, 0, true), name
+ ".released");
am.put(name + ".pressed", new KeyAction(btn, true, caretPosition));
am.put(name + ".released", new KeyAction(btn, false, caretPosition ));
}
}
public class KeyAction extends AbstractAction {
private JButton btn;
private boolean cur;
private int caretPosition;
public KeyAction(JButton btn, boolean cur, int caretPosition) {
this.btn = btn;
this.cur = cur;
this.caretPosition = caretPosition;
}
@Override
public void actionPerformed(ActionEvent e) {
if (cur) {
btn.getModel().setPressed(true);
textToType.setCaretPosition(caretPosition++);
} else {
btn.getModel().setPressed(false);
}
}
}
public class KeyActionGreen extends AbstractAction {
private JButton btn;
private boolean highlight;
public KeyActionGreen(JButton btn, boolean highlight) {
this.btn = btn;
this.highlight = highlight;
}
@Override
public void actionPerformed(ActionEvent e) {
if (highlight) {
btn.getModel().setPressed(true);
btn.setBackground(Color.GREEN);
btn.setOpaque(true);
} else {
btn.getModel().setPressed(false);
btn.setBackground(null);
btn.setOpaque(false);
}
}
}
}
答案 0 :(得分:1)
您正在Action
和name + ".pressed"
方法中向name + ".released"
和ActionMap
的{{1}}和addKeyBinding
键添加addKeyBindingGreen
。
AcationMap
是Map
。 Map
的行为是每个键只能包含一个值。如果您尝试将两个值放在同一个键上,那么您输入的第一个值将被第二个值推出,在您的情况下,该值将是您添加第二个值的Action
。
唯一的选择是将您想要的代码合并到一个Action
答案 1 :(得分:1)
<强>更新强>
有三个核心问题,
您将caretPosition
(从KeyboardTest
)的值传递给KeyAction
,问题是KeyAction
只会更新{的{1}}类实例{1}}相对于它自己,也就是说,如果您有两个caretPosition
实例,它们将有两个单独的值,并将单独更新。
这是因为Java中的参数是按值传递的,而不是通过引用...
传递的您可以传递包含KeyAction
值的对象,确保将相同的实例传递给所有按钮。这样一来,动作就是修改相同的值,或者你可以简单地让动作引用类实例字段......
int
您正在进行public int caretPosition = 0;
//...
public class KeyAction extends AbstractAction {
private JButton btn;
private boolean cur;
public KeyAction(JButton btn, boolean cur) {
this.btn = btn;
this.cur = cur;
}
@Override
public void actionPerformed(ActionEvent e) {
if (cur) {
btn.getModel().setPressed(true);
textToType.setCaretPosition(caretPosition++);
} else {
btn.getModel().setPressed(false);
}
}
}
的后期增量而不是预增量...
caretPosition
这意味着,textToType.setCaretPosition(caretPosition++);
的值仅在caretPosition
返回后更改,这意味着第一次触发操作时,它的值为0,仍然......
您应该将其更改为更像......
setCaretPosition
正如已经指出的那样,您只能通过textToType.setCaretPosition(++caretPosition);
/ Action
绑定将KeyStroke
附加到ActionMap
。
这给你留下了至少三个基本选项......
您可以自行承认,您只能指定一个InputMap
并且必须决定哪一个是最佳选择......
在这种情况下,您“可以”将另一个Action
或Action
附加到各个按钮,例如,可以执行另一个ActionListener
...但您需要确保键绑定Action
触发了按钮,例如使用Action
之类的内容...
设计一个“可链接的”JButton#doClick
,它能够获取Action
的列表,并在触发时触发这些操作......
Action
上面的例子确实有一个问题,它没有“配置”属性,因此无法与public class ChainableAction extends AbstractAction {
private List<Action> actions;
public ChainableAction(Action... actions) {
this.actions = new ArrayList<>(Arrays.asList(actions));
}
@Override
public void actionPerformed(ActionEvent e) {
for (Action action : actions) {
action.actionPerformed(e);
}
}
}
之类的东西一起使用。您可以通过构造函数提供配置信息(例如图标和文本)。
设置一个继承链,其中颜色JMenuItem
和文本Action
能够以形式或其他方式相互延伸,然后您只需使用最终的子Action
对于绑定...
Action
然后你就可以将public class KeyAction extends ColorActionGreen {
private JButton btn;
private boolean cur;
private int caretPosition;
public KeyAction(JButton btn, boolean cur, int caretPosition, boolean highlight) {
super(btn, highlight);
this.btn = btn;
this.cur = cur;
this.caretPosition = caretPosition;
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (cur) {
btn.getModel().setPressed(true);
textToType.setCaretPosition(caretPosition++);
} else {
btn.getModel().setPressed(false);
}
}
}
public class ColorActionGreen extends AbstractAction {
private JButton btn;
private boolean highlight;
public ColorActionGreen(JButton btn, boolean highlight) {
this.btn = btn;
this.highlight = highlight;
}
@Override
public void actionPerformed(ActionEvent e) {
if (highlight) {
btn.getModel().setPressed(true);
btn.setBackground(Color.GREEN);
btn.setOpaque(true);
} else {
btn.getModel().setPressed(false);
btn.setBackground(null);
btn.setOpaque(false);
}
}
}
用于所有绑定甚至KeyAction
自己...