Java JTextArea KeyListener - java

When I pressed the ENTER my JTextArea starts a new row and I only want do to the doClick() method nothing else.
How should I do that?
textarea.addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_ENTER){
button.doClick();
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
});

Use .consume():
Consumes this event so that it will not be processed in the default
manner by the source which originated it.
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_ENTER){
e.consume();
button.doClick();
}
}
Documentation

You should use KeyBindings with any JTextComponent in question. KeyListeners are way too low level from Swing's perspective. You are using the concept which was related to AWT, Swing uses KeyBindings to do the same task with more efficiency and provides desired results :-)
A small program for your help :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class KeyBindingExample {
private static final String key = "ENTER";
private KeyStroke keyStroke;
private JButton button;
private JTextArea textArea;
private Action wrapper = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
button.doClick();
}
};
private void displayGUI() {
JFrame frame = new JFrame("Key Binding Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel(new BorderLayout(5, 5));
textArea = new JTextArea(10, 10);
keyStroke = KeyStroke.getKeyStroke(key);
Object actionKey = textArea.getInputMap(
JComponent.WHEN_FOCUSED).get(keyStroke);
textArea.getActionMap().put(actionKey, wrapper);
button = new JButton("Click Me!");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.format("Button Clicked :-)%n");
}
});
contentPane.add(textArea, BorderLayout.CENTER);
contentPane.add(button, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new KeyBindingExample().displayGUI();
}
};
EventQueue.invokeLater(r);
}
}

Related

Keybinding not calling AbstractAction

I am making a game where the user has to press keys to move around. I am using keybindings but they are not working. The keybindings are supposed to call the Wp class and print "W pressed", but nothing happens. Here's the code:
public class SO extends JFrame {
public static void main(String[] args) {
new SO();
}
C c;
public SO(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500, 500);
c=new C();
c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "wp");
c.getActionMap().put("wp", new Wp());
this.setVisible(true);
}
private class C extends JComponent {
public void paint(Graphics g){}
}
private class Wp extends AbstractAction {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("W pressed");
}
}
}
Use Action to call like component.getActionMap().put("doSomething", anAction);
Refer Key Binding for more information. Below is a sample code I have referred in another Stackoverflow Question reference link SO Ref link
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonBinding {
private JPanel contentPane;
private JTextField tField;
private JButton button;
private KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");
private Action action = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Action Performed");
contentPane.setBackground(Color.BLUE);
}
};
private MouseAdapter mouseActions = new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent me) {
System.out.println("Mouse Entered");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "enter");
button.getActionMap().put("enter", action);
}
#Override
public void mouseExited(MouseEvent me) {
System.out.println("Mouse Exited");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "none");
contentPane.setBackground(Color.RED);
}
};
private void displayGUI() {
JFrame frame = new JFrame("Button Binding Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
tField = new JTextField(10);
button = new JButton("Click Me");
button.addMouseListener(mouseActions);
contentPane.add(tField);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new ButtonBinding().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}

JButton with both ActionListener / MouseListener

Is it possible to create a Jbutton with both an ActionListener and MouseListener
Meaning so i create a button and then when i press it ( throught actionListener) it changes the frame so that AFTER then button was pressed i can press anywhere on the frame and MouseListener would in use.
JButton button = new JButton();//Creates Button
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Insert MouseListener
//Then do something with mouseListener
}
});
Heres the curent code: however they're now in sync when i try to click the button and i cannot call mouseListener a 2nd time
JButton button2 = new JButton("Click");
button2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("You clicked the button");
newCube.stopCube();
}
});
button2.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mousePressed(java.awt.event.MouseEvent evt)
{
double x = evt.getX();
double y = evt.getY();
newCube.setCube(x,y);
}
});
If you want to move something by clicking on it, you can use a mouse listener on that node directly, instead of using it on the button.
To add both the action listener and a mouse listener on a button, you can use the addActionListener and addMouseListener methods on the button.
Look at the api for information about these methods... http://docs.oracle.com/javase/7/docs/api/javax/swing/JButton.html
If I understood you correctly, this sample might help you (add this to your own ActionListener)
#Override
public void actionPerformed(ActionEvent e) {
((JButton)e.getSource()).addMouseListener(yourMouseListener);
}
I tried this, it works.
Here is example with JToggleButton which add/remove MouseListener to JFrame.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
public class Example extends JFrame {
private MouseAdapter mouseListener;
public Example(){
init();
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void init() {
mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
System.out.println("clicked");
}
};
setLayout(new FlowLayout());
JToggleButton b = new JToggleButton("add listener");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(((JToggleButton)e.getSource()).isSelected()){
Example.this.addMouseListener(mouseListener);
((JToggleButton)e.getSource()).setText("remove listener");
} else {
Example.this.removeMouseListener(mouseListener);
((JToggleButton)e.getSource()).setText("add listener");
}
}
});
add(b);
}
public static void main(String... s){
new Example();
}
}
EDIT: examle with JButton:
public class Example extends JFrame {
private MouseAdapter mouseListener;
public Example(){
init();
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void init() {
mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
System.out.println("clicked");
}
};
setLayout(new FlowLayout());
JButton b = new JButton("add listener");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(((JButton)e.getSource()).getText().equals("add listener")){
Example.this.addMouseListener(mouseListener);
((JButton)e.getSource()).setText("remove listener");
} else {
Example.this.removeMouseListener(mouseListener);
((JButton)e.getSource()).setText("add listener");
}
}
});
add(b);
}
public static void main(String... s){
new Example();
}
}
What you want to do is still not clear to me. Though this can help you. It will add a mouse listner to the component when the start button is clicked and remove the mouse listner when stop button is clicked. Thus you can stop the two listeners from working in sync..
JButton startButton = new JButton();
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Add MouseListener to move the component
}
});
JButton stopButton = new JButton();
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Remove the MouseListener
}
});

How to add KeyListener to JComponent when mouse is entered?

I have created custom button class which extends JComponent and want to add KeyListener on mouseEntered event (and later remove on mouseExited). So my goal is - when the mouse enters this JComponent - then if I press Enter - some code will be executed, related to only this button. How can I do that?
Use Key Bindings instead of KeyListeners, since the latter is way to low level for Swing. Just bring your mouse over the JButton, and then press ENTER, then take your mouse outside the bounds of the JButton and try pressing ENTER again. Have a look at this example and see if this is what you wanted :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonBinding {
private JPanel contentPane;
private JTextField tField;
private JButton button;
private KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");
private Action action = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Action Performed");
contentPane.setBackground(Color.BLUE);
}
};
private MouseAdapter mouseActions = new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent me) {
System.out.println("Mouse Entered");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "enter");
button.getActionMap().put("enter", action);
}
#Override
public void mouseExited(MouseEvent me) {
System.out.println("Mouse Exited");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "none");
contentPane.setBackground(Color.RED);
}
};
private void displayGUI() {
JFrame frame = new JFrame("Button Binding Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
tField = new JTextField(10);
button = new JButton("Click Me");
button.addMouseListener(mouseActions);
contentPane.add(tField);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new ButtonBinding().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}

Enter Key to behave as Tab on an Editable JComboBox

I have a JComboBox set as Editable which I would like the user to be able to jump to the next control after hitting the enter key. I have tried many approaches but none of them worked, on one of them the event is fired successfully (EditorCompoment.keyRelease) however the method "transferFocus()" does not transfer the focus to the next control like it should.
Any help is much appreciated.
Thanks
public static void addEnterKeyListener(final javax.swing.JComboBox field)
{
field.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
field.setFocusTraversalKeysEnabled(false);
Action myAction = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
field.transferFocus();
}
};
field.getActionMap().put("enter-action", myAction);
field.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("ENTER"), "enter-action");
field.addKeyListener(new KeyAdapter()
{
#Override
public void keyReleased(final KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
System.out.println("Pressed enter inside JComboBox");
field.transferFocus();
}
}
});
field.getEditor().getEditorComponent().addKeyListener(new KeyAdapter()
{
#Override
public void keyReleased(final KeyEvent e)
{
System.out.println("Pressed enter inside JComboBox #2");
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
field.transferFocus();
/*This will fire but will not transfer the focus to the next control*/
System.out.println("Transfered the focus from JComboBox");
}
}
});
field.getEditor().addActionListener(new ActionListener()
{
#Override public void actionPerformed(ActionEvent arg0)
{
field.transferFocus();
}
});
System.out.println("Added enter events to JComboBox");
}
Apply an ActionListener to the editorComponent (a JTextField) of the combo's editor:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JComboBoxDemo implements Runnable
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new JComboBoxDemo());
}
public void run()
{
JComboBox comboBox = new JComboBox(new String[]{"A", "B", "C"});
comboBox.setEditable(true);
final JTextField editorComponent = (JTextField) comboBox.getEditor().getEditorComponent();
editorComponent.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
editorComponent.transferFocus();
}
});
JPanel panel = new JPanel(new FlowLayout());
panel.add(new JLabel("Field 1"));
panel.add(comboBox);
panel.add(new JLabel("Field 2"));
panel.add(new JTextField(10));
panel.add(new JLabel("Field 3"));
panel.add(new JTextField(10));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
Container c = frame.getContentPane();
c.setLayout(new BorderLayout());
c.add(panel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}

Close a swing Dialog after done operations

I have a jdialog and want close it on confirmation after that store the data of a text box... now I have no problem to store the data from the box but,
How can I close this dialog after the operation???
Seems a simple thing but I haven't found the solution.
public class test extends JDialog {
private final JPanel contentPanel = new JPanel();
public test() {
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
{
JButton okButton = new JButton("OK");
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
try{
int x=Integer.parseInt(textField.getText());
saver.saveN(x);
}catch(Exception ecc){
JOptionPane.showMessageDialog(Test.this,"error");
}
}
});
}
}
}
}
Either use Window#dispose or Window#setVisible(false).
if you use this dialog only once time then there is same to use dispose() as setVisible(false)
in the case that you invoke this method more than once time, then you can use HIDE_ON_CLOSE
or setVisible(false), better would be re_use this JDialog
EDIT
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class Test {
private static final long serialVersionUID = 1L;
private JDialog dialog = new JDialog();
private final JPanel contentPanel = new JPanel();
private Timer timer1;
private JButton killkButton = new JButton("Kill JDialog");
public Test() {
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
JPanel buttonPane = new JPanel();
JButton okButton = new JButton("OK");
okButton.setActionCommand("OK");
buttonPane.add(okButton);
killkButton.setActionCommand("Kill JDialog");
buttonPane.add(killkButton);
dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
dialog.addWindowListener(new WindowListener() {
public void windowOpened(WindowEvent e) {
}
public void windowClosing(WindowEvent e) {
startTimer();
}
public void windowClosed(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
});
dialog.setLayout(new BorderLayout());
dialog.getRootPane().setDefaultButton(okButton);
dialog.add(buttonPane, BorderLayout.SOUTH);
dialog.add(contentPanel, BorderLayout.CENTER);
dialog.pack();
dialog.setLocation(100, 100);
dialog.setVisible(true);
setKeyBindings();
}
private void setKeyBindings() {
killkButton.getInputMap(
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke("ENTER"), "clickENTER");
killkButton.getActionMap().put("clickENTER", new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
private void startTimer() {
timer1 = new Timer(1000, new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
dialog.setVisible(true);
}
});
}
});
timer1.setDelay(500);
timer1.setRepeats(false);
timer1.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Test test = new Test();
}
});
}
}
If you plan to use a jDialog again with all the field values and component states left the same when you close it, use setVisible(false).
In any other case, call dispose(), to avoid the jDialog remaining in the memory when it is no longer required.

Categories