Reputation: 535
I have a menu bar with a search-bar that is implemented with a JTextField
like this:
public class Ui_Frame {
private static JFrame f;
private static DrawPanel drawPanel;
public static void main(String[] args) {
SwingUtilities.invokeLater(Ui_Frame::createAndShowGUI);
}
private static void createAndShowGUI() {
f = new JFrame("Frame");
drawPanel = new DrawPanel(); //A class that extends JPanel where I draw
JMenuBar menubar = new JMenuBar();
JMenu j_menu_data = new JMenu("Data");
JTextField j_menu_searchfield = new JTextField();
j_menu_searchfield.setSize(new Dimension(100,20));
menubar.add(j_menu_data);
menubar.add(j_menu_searchfield);
f.setJMenuBar(menubar);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(drawPanel);
f.pack();
f.setVisible(true);
}
}
I have KeyListener
s for the DrawPanel
class, these work just fine. The problem is that when I add the search bar JTextField
to the menu bar as above, everything I write is being written to the text field and my key listeners do not trigger. I cannot "get out" of the text field, so If I click inside the area where I am drawing all the keys I press are still put into the text field.
I have tried getFocus()
for the DrawPanel
but to no avail.
How to solve this?
EDIT: DrawPanel class so you have all the classes you need to run it:
public class DrawPanel extends JPanel {
public DrawPanel() {
addKeyListener(new CustomKeyListener());
this.setBackground(new Color(220,220,220));
setBorder(BorderFactory.createLineBorder(Color.black));
setFocusable(true);
setVisible(true);
}
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
protected void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
super.paintComponent(g2D);
}
class CustomKeyListener implements KeyListener {
@Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_SPACE) {
System.out.println("Pressed SPACE");
}
}
@Override
public void keyPressed(KeyEvent e) { }
@Override
public void keyReleased(KeyEvent e) { }
}
}
Upvotes: 0
Views: 114
Reputation: 20923
When you launch your Swing application, the JTextField
initially has the keyboard focus. You know this because you see the cursor flashing inside the JTextField
.
Clicking on the DrawPanel
with the mouse does not transfer the keyboard focus to the DrawPanel
. You know this because after clicking the mouse inside the DrawPanel
, the cursor is still flashing inside the JTextField
.
You can transfer the keyboard focus from the JTextField
to the DrawPanel
by hitting the TAB key on the keyboard since that is the default focus traversal key. You know that the JTextField
no longer has keyboard focus because there is no flashing cursor in it.
If you really want the DrawPanel
to gain keyboard focus by clicking the mouse in it, you can add a MouseListener
to DrawPanel
, as demonstrated in the below code which is essentially your code (for class DrawPanel
) with a MouseListener
added.
Note that I did not change class Ui_Frame
.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
public class DrawPanel extends JPanel implements MouseListener {
public DrawPanel() {
addKeyListener(new CustomKeyListener());
addMouseListener(this);
this.setBackground(new Color(220,220,220));
setBorder(BorderFactory.createLineBorder(Color.black));
setFocusable(true);
setVisible(true);
}
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
protected void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
super.paintComponent(g2D);
}
class CustomKeyListener implements KeyListener {
@Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_SPACE) {
System.out.println("Pressed SPACE");
}
}
@Override
public void keyPressed(KeyEvent e) { }
@Override
public void keyReleased(KeyEvent e) { }
}
@Override
public void mouseClicked(MouseEvent mouseEvent) {
System.out.println(this.requestFocusInWindow());
}
@Override
public void mousePressed(MouseEvent mouseEvent) {
}
@Override
public void mouseReleased(MouseEvent mouseEvent) {
}
@Override
public void mouseEntered(MouseEvent mouseEvent) {
}
@Override
public void mouseExited(MouseEvent mouseEvent) {
}
}
Note that method requestFocusInWindow()
returns true
if it succeeds.
Upvotes: 2