krise
krise

Reputation: 535

Escaping out of text field based search bar

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 KeyListeners 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

Answers (1)

Abra
Abra

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

Related Questions