I have a JTable that has a delete button to delete its rows.
I want to create a shortcut, for example when user selects a row and presses the 'Delete' button on keyboard , that line should be deleted.
My line is deleted with my JButton1 perfectly.
if (e.getSource() == KeyEvent.VK_DELETE) {
// Delete row Method
}
But it doesn't work.
don't to use KeyListener for this job, and in Swing never, use KeyBindings instead
add ListSelectionListener to JTable, notice to test if(table.getSelectedRow > 0)
use KeyBindings for JTable, override Delete key
I don't know what is the exact problem because you provide too few code. However, you can't use getSource() to test which key is typed (pressed, or released). Use getKeyChar() and getKeyCode().
The following is explanation of my code:
You need to add a KeyListener to a component(of course)
The component must have focus
The component must be focusable (set focusable to true)
The component need to request for focus
Override keyTyped keyPressed or keyReleased to retrieve KeyEvent
To check which key is typed in keyTyped, use getKeyChar()
To check which key is pressed or released in keyPressed and keyReleased, use getKeyCode()
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(new Dimension(410, 330));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBackground(Color.GREEN);
panel.setBounds(50, 50, 300, 200);
panel.addKeyListener(new MyKeyListener()); // add KeyListener
panel.setFocusable(true); // set focusable to true
panel.requestFocusInWindow(); // request focus
f.getContentPane().add(panel);
f.setVisible(true);
}
static class MyKeyListener extends KeyAdapter {
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == '\177') {
// delete row method (when "delete" is typed)
System.out.println("Key \"Delete\" Typed");
}
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
// delete row method (when "delete" is pressed)
System.out.println("Key \"Delete\" Pressed");
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
// delete row method (when "delete" is released)
System.out.println("Key \"Delete\" Released");
}
}
}
}
Take a look to this page:
http://www.coderanch.com/t/341332/GUI/java/setting-keyboard-navigation-shortcut-keys
Taken from there:
Create a key listener for that button (it seems you have already made that):
Button btn = new Button("Press Me");
btn.addKeyListener(myKeyListener);
And implement the keylistener:
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_DELETE ){
//Do whatever you want
}
}
Try it and tell me if it works.
Related
In my java code below it produces a frame with a jtextrea. This allows for simple text processing. All I want to do is add " Sam". Which is 5 spaces with sam at the end. Every time the user hits enter. You can see also the gif I added below which is exactly what I am looking for.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
class text11 extends JFrame implements ActionListener {
// JFrame
static JFrame f;
// text area
static JTextArea jt;
// main class
public static void main(String[] args)
{
// create a new frame to store text field and button
f = new JFrame("textfield");
// create a label to display text
// create a object of the text class
text11 te = new text11();
// create a text area, specifying the rows and columns
jt = new JTextArea(" ", 20, 20);
JPanel p = new JPanel();
// add the text area and button to panel
p.add(jt);
f.add(p);
// set the size of frame
f.setSize(300, 300);
f.show();
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
String actionKey = "ADD_SAM";
InputMap inputMap = jt.getInputMap(JComponent.WHEN_FOCUSED);
KeyStroke enterPressed = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
inputMap.put(enterPressed, actionKey);
jt.getActionMap().put(actionKey, new TextAction(actionKey) {
#Override
public void actionPerformed(ActionEvent e) {
jt.append(" Sam\n");
}
});
To get input so you know when the use hits enter, you have to create your own KeyListener class. If you don't know how to use it, here is a handy link from the documentation you can use: https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html.
But simply put, an KeyListener is an interface where you have to specify a few methods, but in your case I think the only one you need is keyPressed(KeyEvent e)(which is called pressed). If you're interested in the others, keyReleased(KeyEvent e) is when a key gets released, and keyType(KeyEvent e) is when it's pressed and released quickly. Then, use JFrames addKeyListener(KeyListener k) to add your custom action listener.
After you did that, you can use JTextArea's setText() and getText() method to append " sam" to the end (the 5 spaces get cut of by stack overflow, I know you want 5 spaces).
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
jt.setText(jt.getText() + " sam");
}
}
If you added the KeyListener correctly, you should be fine!
I'm trying to make it so that when the user presses the Enter key the JButton which is associated with that key gets triggered.
Here's what my code looks like:
import java.awt.event.KeyEvent;
private void formKeyPressed(java.awt.event.KeyEvent evt) {
if(evt.getKeyCode()==KeyEvent.VK_ENTER) {
jButton2.setEnabled(true);
}
}
How to trigger a JButton with a key press?
Add an ActionListener to the button. It will fire an event when the button is in focus and the user presses the enter key. See How to Write an Action Listener for more info.
Edit
See also further details in Rob Camick's Enter Key and Button.
ActionListener itself won't be sufficient. You will have to write a KeyListener to get this thing down. A KeyListener which captures Enter button press would look like this.
this.button.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
System.out.println("Hello");
JOptionPane.showMessageDialog(null, "Enter key pressed !");
}
}
});
I am Trying to make the program respond when the button ESC is clicked so that it will dispose the jframe. I am Not sure what the problem is but it seems to be in the if statement in the main menu.
*Note: te is the object name for the class (Text Editor)
This part is in the main method
f.add(text);
f.addKeyListener(te);
f.setVisible(true);
while(true){
if (exiting == true){
f.dispose();
}
}
This part is outside the main method
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE){
exiting = true;
}
}
Don't use KeyListeners, as a general rule, the component they are attached MUST have key board focus in order to be triggered.
Instead, use a key binding...
InputMap im = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getRootPane().getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel");
am.put("cancel", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
See How to Use Key Bindings for more details
Because of the power of the Action API, I would create a basic "dispose" action to start with:
public class DisposeWindowAction extends AbstractAction {
private Window window;
public DisposeWindowAction(Window window) {
this.window = window;
putValue(NAME, "Dispose");
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, 0));
}
public Window getWindow() {
return window;
}
#Override
public void actionPerformed(ActionEvent e) {
getWindow().dispose();
}
}
I'd then bind this to the ActionMap...
am.put("cancel", new DisposeWindowAction(this));
Why you ask? Because you can then use the same Action in JMenuItems and JButtons`....
JButton disposeButton = new JButton(new DisposeWindowAction(this));
...
(You can use the same instance of the Action, but you get the idea) and now the user has something like three more ways to dispose of the window...
See How to Use Actions for more details
there is an easier way to add a listener to the jframe. All you have to do is create a keylistener overriding keypressed and then check what type of object e.getComponent() is. If it is a window type you can call dispose on it when the escape key is pressed.
public void keyPressed(KeyEvent e){
If(e.getKeyCode() == KeyEvent.VK_ESCAPE){
If( e.getComponent() instanceof Window){
((Window)e.getComponent()).dispose();
}
}
}
You can of course change window to JFrame, and put the two if statements together.
Also you do not need the while loop.
I have made my own version of Tetris in Java and i have added the possibility of moving the shapes both with JButtons and with certain keyboard keys. The code snippet i used is the following:
leftButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent E) {
moveLeft();
}
});
rightButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent E) {
moveRight();
}
});
rotateButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent E) {
rotateMovingShape();
}
});
myPanel.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent event) {
int keyCode = event.getKeyCode();
if (keyCode == event.VK_A)
{
moveLeft();
}
if (keyCode == event.VK_D)
{
moveRight();
}
if (keyCode == event.VK_S)
{
rotateMovingShape();
}
}
});
The problem i have is that after i use the JButtons, i cannot longer control the shapes with the keyboard keys. I suspect it has something to do with gaining/losing focus, but i am not sure. Could anyone tell me what's going on?
You get that problem, because you use KeyListener, instead of that you need to use Key Bindings. For example:
component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_A,0), "aPressed");
component.getActionMap().put("aPressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("a key");
}
});
component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_D,0), "dPressed");
component.getActionMap().put("dPressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("d key");
}
});
// other bindings
where component is your JPanel.
A KeyListener only receives key events when the component has the keyboard focus. Clicking on the buttons transfers the focus to them and away from your panel, so you don't get the events. Any one of the following approaches will solve this:
Call setFocusable(false); on the buttons so that they won't steal the focus.
Add the KeyListener to the buttons too.
Use key bindings instead of a KeyListener, so that you can catch the key press whether the component has focus or not.
I need a keylistener to be always 'listening' for the escape key to be pressed, to then exit the program.
I have tried typing addKeyListener(this); in my main constructor (the one with the panel being drawn in) and have used
public void keyPressed( KeyEvent e)
{
int code = e.getKeyCode();
if(code == KeyEvent.VK_ESCAPE)
{
System.exit( 0 );
}
}
I get no errors, but pressing the escape key doesn't seem to do anything, any suggestions?
Top-Level Container by default never receiving KeyEvent from KeyListener, by default, but is possible with a few code lines, wrong idea, wrong listener
JPanel by defaul react to KeyEvent, but only in the case that isFocusable, is FocusOwner, wrong idea, wrong listener, (for example) because you needed to move Focus from JTextField to JPanel programatically, wrong idea
add KeyBindings to JFrame/ JDialog / JWindow, accesible by default for Swing JComponent, not for AWT Components
You can use the InputMap/ActionMap mechanism :
Object escapeActionKey = new Object();
pnl.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ESCAPE"), escapeActionKey);
pnl.getActionMap().put(escapeActionKey, new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.err.println("escape 1");
}
});
JComponent.WHEN_IN_FOCUSED_WINDOW means that this keystroke is available when the pnl component is in the focused window.
Or you can also add a global AWTEventListener listener :
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
public void eventDispatched(AWTEvent event) {
if(event.getID() == KeyEvent.KEY_PRESSED) {
KeyEvent kEvent = (KeyEvent) event;
boolean isEsc = (kEvent.getKeyCode() == KeyEvent.VK_ESCAPE);
if(isEsc) {
System.err.println("escape 2");
}
}
}
}, AWTEvent.KEY_EVENT_MASK);
In Swing there is a top layer panel : the GlassPane which allow to handle event at top level (to avoid other widget to comsume the event)