Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (489)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Can't seem to get keyboard focus properly  (Read 1153 times)
0 Members and 1 Guest are viewing this topic.
Offline altitude

Junior Newbie




Java games rock!


« Posted 2004-09-21 15:39:29 »

Hi folks.

I'm trying to create a JPanel and get keyboard events from that panel.  i've been reading through the docs and whatnot, but i can't seem to get it setup properly.  Can anyone help?

I'm including three sets of the same code.  The desired outcome is that when you run the app, every time you hit a key, it a message should appear in the console.  

This first code example doesn't work properly on my WinXP machine (sun java 1.4.1_02), or my MacOS machine (apple java 1.4.2_05).  When you run the app, and hit any key, no output appears on the console:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class KeyListenerTest0 extends JPanel implements Runnable {

 private Thread m_subThread = null;

 public static void main ( String[] argv ) {
  final Frame f = new Frame ( "KeyListenerTest0 1" );
  f.addWindowListener ( new WindowAdapter () {
   public void windowClosing ( WindowEvent e ) {
    f.dispose ();
    System.exit ( 0 );
   }
  } );

  f.add ( new KeyListenerTest0 () );
  f.setSize ( 220, 220 );
  f.setVisible ( true );
 }

 public void run () {
  Thread.currentThread ().setPriority ( Thread.MIN_PRIORITY );
  while ( true ) {
   try {
    Thread.sleep ( 500 );
   } catch ( Exception e ) {
   }
   repaint ();
  }
 }

 public KeyListenerTest0 () {
  setBackground ( Color.white );
  setLayout ( new BorderLayout () );

  //  Add a key listener which will just dump out info.
 addKeyListener ( new KeyListener () {
   public void keyPressed ( KeyEvent ke ) { System.out.println ( "Key Pressed: " + ke.getKeyChar () ); }
   public void keyReleased ( KeyEvent ke ) { System.out.println ( "Key Released: " + ke.getKeyChar () ); }
   public void keyTyped ( KeyEvent ke ) { System.out.println ( "Key Typed: " + ke.getKeyChar () ); }
  } );
  //  Print out focus info
 getFocus ( "First Try" );

  m_subThread = new Thread ( this );
  m_subThread.start ();
 }

 private void getFocus ( String label ) {
  System.out.println ( "Trying to get focus: '" + label + "'" );
  System.out.println ( "  isFocusable: " + isFocusable () );
  System.out.println ( "  hasFocus: " + hasFocus () );
  if ( hasFocus () == false ) {
   boolean b = requestFocusInWindow ();
   System.out.println ( "  requestFocusInWindow returns: " + b );
  }
  System.out.println ( "  hasFocus: " + hasFocus () );
  KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
  Component c = kfm.getFocusOwner ();
  System.out.println ( "  Who has focus?: " + c );
  System.out.println ( "Done trying to get focus for: '" + label + "'" );
  System.out.println();
}

 public void paintComponent ( Graphics g ) {
  Graphics2D g2 = (Graphics2D) g;
  g2.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
  g2.setPaint ( Color.orange );
  g2.fillOval ( 100, 100, 100, 100 );
 }
}


This second example works on my WinXP machine, but not on my mac.   The only thing different is that I put a getFocus() call in the run() method.  I'm pretty sure that this is not the way i'm supposed to do this...

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class KeyListenerTest1 extends JPanel implements Runnable {

 private Thread m_subThread = null;

 public static void main ( String[] argv ) {
  final Frame f = new Frame ( "KeyListenerTest1 1" );
  f.addWindowListener ( new WindowAdapter () {
   public void windowClosing ( WindowEvent e ) {
    f.dispose ();
    System.exit ( 0 );
   }
  } );

  f.add ( new KeyListenerTest1 () );
  f.setSize ( 220, 220 );
  f.setVisible ( true );
 }

 public void run () {
  Thread.currentThread ().setPriority ( Thread.MIN_PRIORITY );
  //  Try to get focus now.  This works on WinXP, but not MacOS.
 getFocus ( "Second try from 'run'" );
  while ( true ) {
   try {
    Thread.sleep ( 500 );
   } catch ( Exception e ) {
   }
   repaint ();
  }
 }

 public KeyListenerTest1 () {
  setBackground ( Color.white );
  setLayout ( new BorderLayout () );

  //  Add a key listener which will just dump out info.
 addKeyListener ( new KeyListener () {
   public void keyPressed ( KeyEvent ke ) { System.out.println ( "Key Pressed: " + ke.getKeyChar () ); }
   public void keyReleased ( KeyEvent ke ) { System.out.println ( "Key Released: " + ke.getKeyChar () ); }
   public void keyTyped ( KeyEvent ke ) { System.out.println ( "Key Typed: " + ke.getKeyChar () ); }
  } );
  //  Print out focus info
 getFocus ( "First Try" );

  m_subThread = new Thread ( this );
  m_subThread.start ();
 }

 private void getFocus ( String label ) {
  System.out.println ( "Trying to get focus: '" + label + "'" );
  System.out.println ( "  isFocusable: " + isFocusable () );
  System.out.println ( "  hasFocus: " + hasFocus () );
  if ( hasFocus () == false ) {
   boolean b = requestFocusInWindow ();
   System.out.println ( "  requestFocusInWindow returns: " + b );
  }
  System.out.println ( "  hasFocus: " + hasFocus () );
  KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
  Component c = kfm.getFocusOwner ();
  System.out.println ( "  Who has focus?: " + c );
  System.out.println ( "Done trying to get focus for: '" + label + "'" );
  System.out.println();
}

 public void paintComponent ( Graphics g ) {
  Graphics2D g2 = (Graphics2D) g;
  g2.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
  g2.setPaint ( Color.orange );
  g2.fillOval ( 100, 100, 100, 100 );
 }
}


This third example works on both the WinXP machine and Mac.  I have now placed a getFocus() call in the paintComponent call.  I am darn near certain that this is not the way to go.  I must be missing something simple.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class KeyListenerTest2 extends JPanel implements Runnable {

 private Thread m_subThread = null;

 public static void main ( String[] argv ) {
  final Frame f = new Frame ( "KeyListenerTest2 1" );
  f.addWindowListener ( new WindowAdapter () {
   public void windowClosing ( WindowEvent e ) {
    f.dispose ();
    System.exit ( 0 );
   }
  } );

  f.add ( new KeyListenerTest2 () );
  f.setSize ( 220, 220 );
  f.setVisible ( true );
 }

 public void run () {
  Thread.currentThread ().setPriority ( Thread.MIN_PRIORITY );
  //  Try to get focus now.  This works on WinXP, but not MacOS.
 getFocus ( "Second try from 'run'" );
  while ( true ) {
   try {
    Thread.sleep ( 500 );
   } catch ( Exception e ) {
   }
   repaint ();
  }
 }

 public KeyListenerTest2 () {
  setBackground ( Color.white );
  setLayout ( new BorderLayout () );

  //  Add a key listener which will just dump out info.
 addKeyListener ( new KeyListener () {
   public void keyPressed ( KeyEvent ke ) { System.out.println ( "Key Pressed: " + ke.getKeyChar () ); }
   public void keyReleased ( KeyEvent ke ) { System.out.println ( "Key Released: " + ke.getKeyChar () ); }
   public void keyTyped ( KeyEvent ke ) { System.out.println ( "Key Typed: " + ke.getKeyChar () ); }
  } );
  //  Print out focus info
 getFocus ( "First Try" );

  m_subThread = new Thread ( this );
  m_subThread.start ();
 }

 private void getFocus ( String label ) {
  System.out.println ( "Trying to get focus: '" + label + "'" );
  System.out.println ( "  isFocusable: " + isFocusable () );
  System.out.println ( "  hasFocus: " + hasFocus () );
  if ( hasFocus () == false ) {
   boolean b = requestFocusInWindow ();
   System.out.println ( "  requestFocusInWindow returns: " + b );
  }
  System.out.println ( "  hasFocus: " + hasFocus () );
  KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
  Component c = kfm.getFocusOwner ();
  System.out.println ( "  Who has focus?: " + c );
  System.out.println ( "Done trying to get focus for: '" + label + "'" );
  System.out.println();
}

 public void paintComponent ( Graphics g ) {
  Graphics2D g2 = (Graphics2D) g;
  g2.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
  g2.setPaint ( Color.orange );
  g2.fillOval ( 100, 100, 100, 100 );
  // try to get focus if we don't already have it.
 if ( hasFocus() == false ) {
   getFocus ( "Inline during paintComponent" );
  }
 }
}


Thanks for any help.

...alex...
Offline Evil-Devil

Senior Member


Medals: 2


Fir Tree Master


« Reply #1 - Posted 2004-09-21 18:52:33 »

getFocus() Huh I get the focus for the component by using the requestFocus() function. And then it works.
Offline altitude

Junior Newbie




Java games rock!


« Reply #2 - Posted 2004-09-21 21:29:09 »

Quote
getFocus() ??? I get the focus for the component by using the requestFocus() function. And then it works.


getFocus() is a method of my own that i'm using to try to get the focus and also display some debugging information.

The javadoc for Component in the JDK1.4 says:

Quote
Because the focus behavior of this method is platform-dependent, developers are strongly encouraged to use requestFocusInWindow when possible.


Hence this is why i'm using requestFocusInWindow() in the getFocus method.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline altitude

Junior Newbie




Java games rock!


« Reply #3 - Posted 2004-09-21 22:10:10 »

WHOOHOO!  I think i figured it out.

Like i said in my original post, i was missing something.  

Let me explain...(to solidify the topics in my head and also to help someone else who reads this thead later...) Here's what i think is/was going on.  Someone please correct me if i'm completely off my rocker...

  • First off, i didn't understand the difference between the window having focus and the component having focus
  • Secondly, I was trying to get the focus before the component was realized (before the event dispatch thread was started.  


I first did some more debugging and found that when the appliacation is initially started up, the parent ApplicationFrame (a Frame subclass) had the focus.  I wondered why that didn't automatically translate into my component having focus since there was only one component in the frame.

I then went poking around the javadoc some more and found a link to the How to use the Focus Subsystem page in the Swing tutorial (http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html).  On this page, it says:
Quote

A component generally gains the focus by the user clicking it, tabbing between components, or otherwise interacting with a component. A component can also be given the focus programmatically, such as when its containing frame or dialog is made visible. This code snippet shows how to give a particular component the focus every time the window is activated:

1  
2  
3  
4  
5  
6  
//Make textField get the focus whenever frame is activated.
frame.addWindowListener(new WindowAdapter() {
 public void windowActivated(WindowEvent e) {
  textField.requestFocusInWindow();
 }
});


If you want to ensure that a particular component gains the focus the first time window is activated, you can call requestFocusInWindow on the component after the component has been realized, but before the frame is displayed. Here is some sample code showing how this can be done:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
//...Where initialization occurs...
JFrame frame = new JFrame("Test");
JPanel = new JPanel(new BorderLayout());

//...Create a variety of components here...

//Create the component that will have the initial focus.
JButton button = new JButton("I'm first");
panel.add(button);
frame.getContentPane().add(panel);  //Add it to the panel

frame.pack();  //Realize the components.
//This button will have the initial focus.
button.requestFocusInWindow();
frame.setVisible(true); //Display the window.



From this, i was able to see the err in my ways.

the answer to the initial question i had (how to get the component to have focus when the app starts up) can be accomplished in either of these two ways. Although since i didn't specify that i wanted the component to always have the focus when the window gets the focus, the latter is more applicable.  

So, in the last version of the KeyListenerTest code the following changes were made:
  • removed the getFocus() method altogether and all calls to getFocus() as well.  
  • In the main() method, I added a call to pack(), as well as requestFocusInWindow() before i set the frame to visible:
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9  
    10  
    11  
    12  
    13  
    14  
    15  
    16  
    17  
    18  
    19  
    20  
    21  
    22  
    23  
    24  
    25  
     public static void main ( String[] argv ) {
      final Frame f = new Frame ( "KeyListenerTest3 1" );
      final KeyListenerTest3 klt = new KeyListenerTest3();

      f.addWindowListener ( new WindowAdapter () {
       public void windowClosing ( WindowEvent e ) {
        f.dispose ();
        System.exit ( 0 );
       }
      } );
     
      f.add ( klt );
      // Make sure the components are realized and the event dispatch queue thread starts
     f.pack();

      // set the size of the frame.
     f.setSize ( 220, 220 );

      // now tell the component to request focus in the window.
     klt.requestFocusInWindow();

      // when we now show the window, the KeyListenerTest3 component (along with
     // it's KeyListener should have focus!  Yippee!
     f.setVisible ( true );
     }


The full listing follows:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class KeyListenerTest3 extends JPanel implements Runnable {
 
 private Thread m_subThread = null;
 
 public static void main ( String[] argv ) {
  final Frame f = new Frame ( "KeyListenerTest3 1" );
  final KeyListenerTest3 klt = new KeyListenerTest3();

  f.addWindowListener ( new WindowAdapter () {
   public void windowClosing ( WindowEvent e ) {
    f.dispose ();
    System.exit ( 0 );
   }
  } );
 
  f.add ( klt );
  // Make sure the components are realized and the event dispatch queue thread starts
 f.pack();

  // set the size of the frame.
 f.setSize ( 220, 220 );

  // now tell the component to request focus in the window.
 klt.requestFocusInWindow();

  // when we now show the window, the KeyListenerTest3 component (along with
 // it's KeyListener should have focus!  Yippee!
 f.setVisible ( true );
 }

 
 public void run () {
  Thread.currentThread ().setPriority ( Thread.MIN_PRIORITY );
  while ( true ) {
   try {
    Thread.sleep ( 500 );
   } catch ( Exception e ) {
   }
   repaint ();
  }
 }
 
 public KeyListenerTest3 () {
  setBackground ( Color.white );
  setLayout ( new BorderLayout () );
 
  //  Add a key listener which will just dump out info.
 addKeyListener ( new KeyListener () {
   public void keyPressed ( KeyEvent ke ) { System.out.println ( "Key Pressed: " + ke.getKeyChar () ); }
   public void keyReleased ( KeyEvent ke ) { System.out.println ( "Key Released: " + ke.getKeyChar () ); }
   public void keyTyped ( KeyEvent ke ) { System.out.println ( "Key Typed: " + ke.getKeyChar () ); }
  } );
 
  m_subThread = new Thread ( this );
  m_subThread.start ();
 }

 public Dimension getMinimumSize() {
  return new Dimension ( 220, 200 );
 }
 
 public void paintComponent ( Graphics g ) {
  Graphics2D g2 = (Graphics2D) g;
  g2.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
  g2.setPaint ( Color.orange );
  g2.fillOval ( 100, 100, 100, 100 );
 }
}


This solution seems more right to me.  I hope i'm correct.  Grin

Thanks.

...alex...
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (18 views)
2014-08-28 18:26:30

CopyableCougar4 (26 views)
2014-08-22 19:31:30

atombrot (39 views)
2014-08-19 09:29:53

Tekkerue (36 views)
2014-08-16 06:45:27

Tekkerue (33 views)
2014-08-16 06:22:17

Tekkerue (22 views)
2014-08-16 06:20:21

Tekkerue (33 views)
2014-08-16 06:12:11

Rayexar (70 views)
2014-08-11 02:49:23

BurntPizza (47 views)
2014-08-09 21:09:32

BurntPizza (38 views)
2014-08-08 02:01:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!