The following is my project
public class KeyStrokeExample {
private JFrame jFrame;
private JPanel jPanel;
private JButton jButton;
private Action action;
public static void main(String[] args) {
KeyStrokeExample keyStrokeExample=new KeyStrokeExample();
keyStrokeExample.initLayout();
keyStrokeExample.test();
}
private void initLayout() {
jFrame=new JFrame("frame");
jPanel=new JPanel();
jButton=new JButton("test");
jPanel.add(jButton);
jFrame.add(jPanel);
jFrame.pack();
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void test() {
action=new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println("test");
}
};
int condition = JComponent.WHEN_FOCUSED;
InputMap inputMap = jPanel.getInputMap(condition);
ActionMap actionMap = jPanel.getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_DOWN_MASK ),"DELETE");
actionMap.put( "DELETE", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println("test");
}
});
}
}
I practice from https://tips4java.wordpress.com/2008/10/10/key-bindings/
I don't know why the program not print "test"
when I remove
action=new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println("test");
}
};
it can work print test"
I want to understand what happened
Thanks
Related
How do I make the Enter key trigger a JComboBox or JButton in a GUI rather than having to hit the Space key? I have an assortment of text fields and check boxes with buttons and combo boxes in between. I'd like to avoid having to switch between hitting space and enter and rather only have to hit enter for all components.
package koning.personal.dungeonsanddragons;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class test {
JFrame window = new JFrame("testGUI");
JPanel windowPanel = new JPanel();
public static JLabel labelSize;
public static JComboBox<String> comboSize;
public static JLabel labelButton;
public static JButton buttonButton;
public test () {
super();
labelSize = new JLabel("Monster Size:");
String[] sizeChoices = { "None", "Tiny", "Small", "Medium", "Large", "Huge", "Colossal"};
comboSize = new JComboBox<String>(sizeChoices);
comboSize.setToolTipText("The creature's size.");
labelButton = new JLabel("Button:");
buttonButton = new JButton();
windowPanel.setLayout(new FlowLayout());
windowPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
windowPanel.add(labelSize);
windowPanel.add(comboSize);
windowPanel.add(labelButton);
windowPanel.add(buttonButton);
windowPanel.setVisible(true);
window.setSize(500, 500);
window.setLayout(new FlowLayout());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.add(windowPanel);
comboSize.addActionListener(handler);
buttonButton.addActionListener(handler);
}
ActionHandler handler = new ActionHandler();
public class ActionHandler implements ActionListener {
public void actionPerformed(ActionEvent eventFocus){
if (eventFocus.getSource() == comboSize){
buttonButton.requestFocusInWindow();
}
if (eventFocus.getSource() == buttonButton){
comboSize.requestFocusInWindow();
}
}
}
#SuppressWarnings("unused")
public static void main(String[] args) {
test GUITest = new test();
}
}
You can add a KeyListener and execute doClick
JButton btn = new JButton();
btn.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER)
btn.doClick();
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
});
If the goal is to have something happen when the enter button is pressed (pressed once and something happens with all the components) then you can add a KeyListener to the JFrame:
JFrame frame = new JFrame("Examplpe");
//here you create and add the components to the frame
and then you can add a KeyListener:
frame.addKeyListener(new KeyListener(
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode == KeyEvent.VK_ENTER){//this is the if block I'm refering to in the following explanation
//do something with all the components
}
}
#Override
public void keyReleased(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {}
}
and then when you press Enter, the code inside the if block will be executed.
Hope this helps :)
I write Java desktop app to fetch and post some data from my online rails backend app. The App have to call a get request every 5 second to update the relay state(example Arduino). here is my code:
public class GUI extends javax.swing.JFrame {
private Serial serial = null;
private Service service = null;
private volatile boolean connected = false;
private Thread updateThread;
public GUI() {
initComponents();
init_serial();
service = new Service();
updateThread = new Thread() {
public void run() {
while (connected) {
updateJob();
}
}
};
updateThread.start();
}
private void init_serial() {
serial = new Serial();
serial.searchForPorts();
serial.connect();
serial.initIOStream();
serial.initListener();
}
private void updateJob() {
ActionListener actListner = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
updateState();
}
};
Timer timer = new Timer(5000, actListner);
timer.start();
}
private void updateState() {
String portState = service.get_port_state();
serial.write(portState);
System.out.println(portState);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
connected = true;
logger.setText(null);
logger.setText("connected");
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
logger.setText(null);
logger.setText("disconnected");
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
}
});
}
}
but it didn't work as expected, my question is how can i fix my code and how to put the thread correctly?
You can use a Thread object in class's member and you can start and stop in button click action events. Here is the sample to start/stop thread.
public class GUI extends javax.swing.JFrame {
Thread updateThread = null;
public GUI() {
JButton btnStart = new JButton("Start");
JButton btnStop = new JButton("Stop");
JPanel jPanel = new JPanel();
jPanel.setBounds(0, 0, 100, 200);
jPanel.add(btnStart);
jPanel.add(btnStop);
add(jPanel);
btnStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
updateThread = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
System.out.println("Work updated");
try {
Thread.sleep(1000);//Time to wait for next routine
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
updateThread.start();
}
});
btnStop.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
updateThread.stop();
}
});
setVisible(true);
setBounds(0, 0, 100, 200);
}
public static void main(String[] args) {
new GUI();
}
}
You can possibly use thread.join();
It's a very simple program, but for some reason when I debug it and set breakpoints at the keyPressed, keyReleased and keyTyped method, the program never stops there.
mainKeyListener = new KeyListener() {
public void keyPressed(KeyEvent e) {
System.out.println("KEY PRESSED");
repaint();
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
};
Here I add it to a JPanel, which is the exact size of the frame and the only object on it:
JPanel backgroundPanel = new JPanel();
backgroundPanel.setBounds(0,0, 400, 500);
backgroundPanel.addKeyListener(mainKeyListener);
backgroundPanel.setFocusable(true);
getContentPane().add(backgroundPanel);
Your problem is laying in focused element. I think that your panel lost the focus.
Note:
To fire keyboard events, a component must have the keyboard focus. It can be solved in many ways for your example you can use KeyboardFocusManager for example like this:
KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addKeyEventDispatcher(new KeyEventDispatcher() {
public boolean dispatchKeyEvent(KeyEvent e) {
if(focusManager.getFocusOwner()!=backgroundPanel){
focusManager.redispatchEvent(backgroundPanel,e);
return true;}
else return false;
}
});
Also try to use Key Bindings http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html
Hi this should work for you.
public class Gui extends JFrame
{
private JPanel backgroundPanel = new JPanel();
public Gui() throws HeadlessException
{
this.setLayout(new GridLayout(1,1));
setPanelProps();
backgroundPanel.addKeyListener(createListener());
this.add(backgroundPanel);
this.setVisible(true);
this.setSize(new Dimension(400,500));
}
public void setPanelProps(){
backgroundPanel.setBounds(0, 0, 400, 500);
backgroundPanel.setSize(new Dimension(400,500));
backgroundPanel.setFocusable(true);
backgroundPanel.setBackground(new Color(50,60,70));
}
public KeyListener createListener(){
return new KeyListener() {
#Override
public void keyTyped(KeyEvent e)
{
System.out.println("KEY TYPED");
}
public void keyPressed(KeyEvent e) {
System.out.println("KEY PRESSED");
repaint();
}
#Override
public void keyReleased(KeyEvent e)
{
System.out.println("KEY RELEASED");
}
};
}
}
public class GuiRun
{
public static void main(String[] args)
{
Gui gui = new Gui();
}
}
I am trying to move a rectangle up,down,left,right when up,down,left,right keys are pressed. I am puzzled why the key listeners no longer listen when the game is started..i.e when gameloop is started. Before starting the game or pressing "start" the listener works i.e it prints "up pressed" System.out.println("up pressed"); but when the game is started by clicking the start button then the listener no longer work. Why is this so? Appreciate any help!
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GameLoopTest extends JFrame implements ActionListener
{
private GamePanel gamePanel = new GamePanel();
private JButton startButton = new JButton("Start");
private JButton quitButton = new JButton("Quit");
private JButton pauseButton = new JButton("Pause");
private boolean running = false;
private boolean paused = false;
private int fps = 60;
private int frameCount = 0;
public GameLoopTest()
{
super("Fixed Timestep Game Loop Test");
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
JPanel p = new JPanel();
p.setLayout(new GridLayout(1,2));
p.add(startButton);
p.add(pauseButton);
p.add(quitButton);
cp.add(gamePanel, BorderLayout.CENTER);
cp.add(p, BorderLayout.SOUTH);
setSize(1000, 700);
startButton.addActionListener(this);
quitButton.addActionListener(this);
pauseButton.addActionListener(this);
Action handle_up_action_pressed = new AbstractAction(){
public void actionPerformed(ActionEvent e){
gamePanel.up_pressed= true;
System.out.println("up pressed");
}
};
Action handle_up_action_released = new AbstractAction(){
public void actionPerformed(ActionEvent e){
gamePanel.up_pressed= false;
}
};
Action handle_down_action_pressed = new AbstractAction(){
public void actionPerformed(ActionEvent e){
gamePanel.down_pressed= true;
}
};
Action handle_down_action_released = new AbstractAction(){
public void actionPerformed(ActionEvent e){
gamePanel.down_pressed= false;
}
};
Action handle_left_action_pressed = new AbstractAction(){
public void actionPerformed(ActionEvent e){
gamePanel.left_pressed= true;
}
};
Action handle_left_action_released = new AbstractAction(){
public void actionPerformed(ActionEvent e){
gamePanel.left_pressed= false;
}
};
Action handle_right_action_pressed = new AbstractAction(){
public void actionPerformed(ActionEvent e){
gamePanel.right_pressed= true;
}
};
Action handle_right_action_released = new AbstractAction(){
public void actionPerformed(ActionEvent e){
gamePanel.right_pressed= false;
}
};
gamePanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "handle_up_pressed");
gamePanel.getActionMap().put("handle_up_pressed", handle_up_action_pressed);
gamePanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "handle_up_released");
gamePanel.getActionMap().put("handle_up_released", handle_up_action_released);
gamePanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "handle_down_pressed");
gamePanel.getActionMap().put("handle_down_pressed", handle_down_action_pressed);
gamePanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "handle_down_released");
gamePanel.getActionMap().put("handle_down_released", handle_down_action_released);
gamePanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "handle_left_pressed");
gamePanel.getActionMap().put("handle_left_pressed", handle_left_action_pressed);
gamePanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "handle_left_released");
gamePanel.getActionMap().put("handle_left_released", handle_left_action_released);
gamePanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "handle_right_pressed");
gamePanel.getActionMap().put("handle_right_pressed", handle_right_action_pressed);
gamePanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "handle_right_released");
gamePanel.getActionMap().put("handle_right_released", handle_right_action_released);
}
public static void main(String[] args)
{
GameLoopTest glt = new GameLoopTest();
glt.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
Object s = e.getSource();
if (s == startButton)
{
running = !running;
if (running)
{
startButton.setText("Stop");
runGameLoop();
}
else
{
startButton.setText("Start");
}
}
else if (s == pauseButton)
{
paused = !paused;
if (paused)
{
pauseButton.setText("Unpause");
}
else
{
pauseButton.setText("Pause");
}
}
else if (s == quitButton)
{
System.exit(0);
}
}
//Starts a new thread and runs the game loop in it.
public void runGameLoop()
{
Thread loop = new Thread()
{
public void run()
{
gameLoop();
}
};
loop.start();
}
I have a JDialog which has two fields, username and password. I want to make the form like normal ones in which pressing enter will be like pressing continue.
I have already tried getRootPane().setDefaultButton(myButton);, but only that does not seem to work.
I have already tried getRootPane().setDefaultButton(myButton);, but only that does not seem to work.
than you have to invoke code for this button with method
JButton#doClick();
but better would be use KeyBindings
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");
private JButton okButton = new JButton("OK");
public Test() {
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
JPanel buttonPane = new JPanel();
okButton.setActionCommand("OK");
buttonPane.add(okButton);
killkButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
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() {
okButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke("ENTER"), "clickENTER");
okButton.getActionMap().put("clickENTER", new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
startTimer();
}
});
}
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();
}
});
}
}
JButton button = ...
JTextField password = ...
ActionListener buttonListener = ...
button.addActionListner(buttonListener);
password.addActionListener(buttonListener);
When enter is pressed in a JTextField, an action event is fired.
You can achieve this by adding an action listener to your textfield, like so.
JTextField field1 = new JTextField();
field1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//here is your method to continue
continue();
}
});