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:
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…
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.
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…