英文:
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 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) { }
}
}
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论