I'm writing a program where there is a keyboard and a JTextArea. Once a button is pressed, the color of the button should change as well as the caret position. I used Key Binding. Now if I first change the color then move the caret, only the caret moves but color doesn't change and vise versa. Here is a sample of my code: (I have many panels to organize the rest of the buttons...)
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);
}
}
}
}