逃离基于文本字段的搜索栏

huangapple go评论67阅读模式
英文:

Escaping out of text field based search bar

问题

我有一个带有搜索栏的菜单栏,该搜索栏是使用JTextField实现的,如下所示:

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(); // 扩展JPanel的类,我在其中绘图

        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);
    }
}

我为DrawPanel类设置了KeyListener,这些工作正常。问题在于,当我像上面那样将搜索栏JTextField添加到菜单栏时,我键入的所有内容都会被写入文本字段,而我的按键侦听器不会触发。我无法“退出”文本字段,因此,如果我在绘图区域内单击,我按下的所有键仍然会被放入文本字段。

我尝试过为DrawPanel使用getFocus(),但无济于事。

如何解决这个问题?

编辑
以下是DrawPanel类,这样您就拥有运行它所需的所有类:

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) { }
    }
}
英文:

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) { }
    }
}

答案1

得分: 2

当启动你的 Swing 应用程序时,JTextField 最初具有键盘焦点。你可以通过在 JTextField 内看到闪烁的光标来确认这一点。

通过鼠标点击 DrawPanel 并不会将键盘焦点转移到 DrawPanel。你可以通过在 DrawPanel 内部点击鼠标后,仍然看到光标在 JTextField 内闪烁来确认这一点。

你可以通过在键盘上按下 TAB 键来将键盘焦点从 JTextField 转移到 DrawPanel,因为 TAB 键是默认的焦点遍历键。你可以通过在 JTextField 内不再看到闪烁的光标来确认它不再具有键盘焦点。

如果你真的希望通过在 DrawPanel 内部点击鼠标来使 DrawPanel 获得键盘焦点,你可以向 DrawPanel 添加一个 MouseListener,就像下面的代码演示的那样,这基本上是你的代码(对于 DrawPanel 类)添加了一个 MouseListener

请注意,我没有更改 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) {
    }
}

请注意,requestFocusInWindow() 方法在成功时返回 true

英文:

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.

huangapple
  • 本文由 发表于 2020年9月7日 19:13:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/63776489.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定