JPanel 按键侦听器

发布于 2024-10-13 12:07:34 字数 351 浏览 2 评论 0原文

我正在尝试添加一个包含 JTabbedPane 的关键侦听器。
当收到 ctrl + tab 时,它应该切换选项卡。
但按键事件永远不会发送 我尝试将其添加到面板和选项卡式对象中 - 但没有成功。

这是我的代码

SwitchTabsListener ctrlTabListener = new SwitchTabsListener(genericTabbedPanel);  
jMainFrame.addKeyListener(ctrlTabListener);  
genericTabbedPanel.addKeyListener(ctrlTabListener);  

I am trying to add a key listener that holds a JTabbedPane.
It should switch the tabs when ctrl + tab is received.
But the keypressed event is never sent
I tried adding it to the panel and to the tabbed object - but with no success.

Here is my code

SwitchTabsListener ctrlTabListener = new SwitchTabsListener(genericTabbedPanel);  
jMainFrame.addKeyListener(ctrlTabListener);  
genericTabbedPanel.addKeyListener(ctrlTabListener);  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

弥枳 2024-10-20 12:07:34

在典型的情况下,您的关键事件不会被正确的 Swing 组件拦截。您必须了解光标下方的第一个组件将接收键盘事件。如果您用键盘选择一个按钮,则该 JButton 将接收按键事件。

为了确保获得所有这些事件,您不必在组件上注册,而是使用 KeyboardFocusManager,无论按键事件发生在哪里,它将接收这些事件。

然后,您的代码需要以下元素,

KeyEventDispatcher myKeyEventDispatcher = new DefaultFocusManager();
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(myKeyEventDispatcher);

只要按下某个键,无论该键位于 UI 中的哪个位置,myKeyEventDispatcher 都会收到对 dispatchKeyEvent 的调用。这样,您可以确保您的代码被正确调用。

注册密钥侦听器的替代方法需要您使用 HierarchyListener 为了添加您的关键侦听器:删除到每个作为根组件的子组件添加/删除的 Swing 组件。这不仅写起来很麻烦,而且很难调试和理解。

这就是为什么我更喜欢更暴力,但将应用程序全局按键侦听器添加到特定键盘焦点管理器的相当优雅的方法。

In a typical fashion, your key event is not intercepted by the correct Swing component. You have to understand that the first component below the cursor will receive the keyboard event. Were you to select a button with your keyboard, it would be this JButton that would receive the key event.

To make sure you get all those events, you don't have to register on components, but rather by using a KeyboardFocusManager, which will receive key events wherever they occur.

Your code then require the following elements

KeyEventDispatcher myKeyEventDispatcher = new DefaultFocusManager();
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(myKeyEventDispatcher);

myKeyEventDispatcher will then receive calls to dispatchKeyEvent whenever a key is pressed, wherever it is in UI. This way, you can make sure your code is correctly called.

The alternative method of registering key listener would require you to use a HierarchyListener in order for your key listener to be added:removed to each and every swing component that appear to be added/removed as a child of your root component. This is not only cumbersome to write, but also really hard to debug and understand.

This is why I prefer the more brute-force, but although quite elegant way of adding application global key listener to a specific keyboard focus manager.

情定在深秋 2024-10-20 12:07:34

Ctrl+TabCtrl+Shift+Tab 允许您在 Windows LookAndFeel 中默认循环浏览选项卡:

UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

Ctrl+Tab and Ctrl+Shift+Tab allow you to cycle through tabs by default in the Windows LookAndFeel:

UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
廻憶裏菂餘溫 2024-10-20 12:07:34

这应该有效。这可能对您不起作用,因为

  1. 您没有选择正确的窗口。
  2. 其他组件捕获此事件。

这是我为您编写的代码。

public class Test {

    public static void main(String[] args) throws InterruptedException {
        JFrame f = new JFrame("aaaa");
        f.setSize(100, 100);
        f.setLocation(100, 100);
        JPanel p = new JPanel();
        f.add(p);

        f.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                System.out.println("pressed");
            }
        });

        p.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                System.out.println("pressed");
            }
        });
        f.setVisible(true);

    }

效果很好。尝试使用它并了解你的代码和我的代码之间有什么区别。如果失败,请将您的代码的较大片段发送给我们。

This should work. This probably does not work for you because

  1. You do not select the correct window.
  2. other component catches this event.

Here is the code I wrote for you.

public class Test {

    public static void main(String[] args) throws InterruptedException {
        JFrame f = new JFrame("aaaa");
        f.setSize(100, 100);
        f.setLocation(100, 100);
        JPanel p = new JPanel();
        f.add(p);

        f.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                System.out.println("pressed");
            }
        });

        p.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                System.out.println("pressed");
            }
        });
        f.setVisible(true);

    }

It works fine. Try to play with it and understand what is the difference between yours and my code. If you fail please send us larger snippet of your code.

晨与橙与城 2024-10-20 12:07:34

根据 Riduidel 的回答,这是一个完整的示例。我不确定如何确定该事件是来自按键还是按键释放。

import java.awt.KeyboardFocusManager;
import java.awt.KeyEventDispatcher;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;

public class Exit {
    public static void main(String[] args) {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new ExitKeyEventDispatcher());
        JFrame frame = new JFrame();
        frame.setBounds(50, 50, 200, 200);
        frame.setVisible(true);
    }
}
class ExitKeyEventDispatcher implements KeyEventDispatcher {
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            System.exit(0);
            e.consume();
        }
        return false;
    }
}

Building from Riduidel's answer, here's a full example. I'm not sure how to determine if the event is from a key press or key release though.

import java.awt.KeyboardFocusManager;
import java.awt.KeyEventDispatcher;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;

public class Exit {
    public static void main(String[] args) {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new ExitKeyEventDispatcher());
        JFrame frame = new JFrame();
        frame.setBounds(50, 50, 200, 200);
        frame.setVisible(true);
    }
}
class ExitKeyEventDispatcher implements KeyEventDispatcher {
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            System.exit(0);
            e.consume();
        }
        return false;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文