Java Swing:如何停止不需要的 Shift-Tab 击键操作

2024-04-13

当我在 JPanel 中有一个 JTextField 并且它具有焦点时,按“tab”不会执行任何操作...但按“shift-tab”会导致焦点丢失(FocusEvent.getOppositeComponent() 为 null)。

如果 JPanel 上(或者更确切地说,在“焦点循环根”下)有其他可聚焦组件,则不会发生这种情况:相反,它们将焦点放在 Shift-Tab 上。

在下面的 SSCCE 中,我演示了这一点...每次在搜索框中按 Return 键时,都会向 JTable 添加一行,这会使其变得可聚焦。您还可以取消注释使 JRadioButtons 无法聚焦的行。

我还查看了InputMaps,看看shift-tab是否以某种方式参与其中......根本没有。

我还尝试用 FocusTraversalPolicy 进行实验,看看我是否能理解这个问题。没有喜悦。

我的目标:当焦点循环根的范围内有单个可聚焦组件时,阻止“shift-tab”导致焦点丢失(焦点消失)。

later

解决方法是添加行

if( oppComp == null ){ impl.searchBox.requestFocus(); }

在搜索框的 FocusListener 的 focusLost 方法的末尾...但对我来说这只是一种解决方法... 1)它并没有通过理解焦点遍历机制来解决问题; 2)当你需要从搜索框中失去焦点时,可能会出现这种情况......

import java.awt.*;
import java.awt.event.*;
import java.lang.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

class BackTabProb {

    JFrame mainFrame;
    JTextField searchBox;
    JTable resultsTable;

    public static void print(String msg) {
        System.out.println(msg);
    }

    public static void main(String[] a_args) throws InvocationTargetException, InterruptedException {
        final BackTabProb impl = new BackTabProb();

        class Show implements Runnable {
            public void run() {
                impl.mainFrame = new JFrame("Back Tab problem");
                impl.mainFrame.addWindowListener(new WindowAdapter() {
                    public void windowClosing(WindowEvent windowEvent) {
                        impl.mainFrame.dispose();
                    }

                });

                impl.resultsTable = new JTable();
                impl.resultsTable.setFocusable(false);
                Vector<Object> dataVector = new Vector<Object>();
                Vector<Object> colIdentifiers = new Vector<Object>(Arrays.asList(new String[] { "ONE", "TWO" }));
                ((DefaultTableModel) impl.resultsTable.getModel()).setDataVector(dataVector, colIdentifiers);
                JScrollPane jsp = new JScrollPane(impl.resultsTable);
                JPanel northPanel = new JPanel();
                northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.X_AXIS));
                impl.searchBox = new JTextField("Enter search text", 10);
                JLabel label = new JLabel("Search:");
                label.setLabelFor(impl.searchBox);
                northPanel.add(label);
                northPanel.add(impl.searchBox);
                ButtonGroup buttonGroup = new ButtonGroup();
                ArrayList<JRadioButton> indexButtons = new ArrayList<JRadioButton>();
                for (int i = 0; i < 2; i++) {
                    JRadioButton indexButton = new JRadioButton(i == 0 ? "Stemmer" : "Simple");

                    // commenting this out means back-tabbing from search box does not result
                    // in focus going "nowhere"
                    indexButton.setFocusable(false);

                    buttonGroup.add(indexButton);
                    northPanel.add(indexButton);

                }
                impl.mainFrame.getContentPane().setLayout(new BorderLayout());
                impl.mainFrame.getContentPane().add(northPanel, BorderLayout.NORTH);
                impl.mainFrame.getContentPane().add(jsp, BorderLayout.CENTER);
                impl.mainFrame.pack();
                impl.mainFrame.setVisible(true);
                print("=== visible");
            }
        }

        EventQueue.invokeAndWait(new Show());

        class AddMore implements Runnable {
            public void run() {
                impl.mainFrame.setFocusTraversalPolicyProvider(true);
                class SearchBoxFocusListener implements FocusListener {
                    public void focusGained(FocusEvent focusEvent) {
                        print("=== search box got focus");
                        impl.searchBox.selectAll();

                    }

                    public void focusLost(FocusEvent focusEvent) {
                        Component oppComp = focusEvent.getOppositeComponent();
                        print(String.format("=== search box lost focus to %s",
                                oppComp == null ? "nowhere" : oppComp.getClass()));
                    }
                }
                impl.searchBox.addFocusListener(new SearchBoxFocusListener());

                class SearchBoxActionListener implements ActionListener {
                    public void actionPerformed( ActionEvent actionEvent ){
                        if( actionEvent.getSource() != null ){
                            ((DefaultTableModel)impl.resultsTable.getModel()).insertRow( 0, new Object[]{ "blip", "blap" });

                            // as soon as the table has at least one row it is set to "focusable"

                            // commenting this out means back-tabbing from search box results
                            // in focus going "nowhere"
                            impl.resultsTable.setFocusable( true );
                        }
                    }
                }
                impl.searchBox.addActionListener( new SearchBoxActionListener() );

                ActionMap am = impl.searchBox.getActionMap();
                print("=== ActionMap");
                for (Object key : am.allKeys()) {
                    print(String.format("  === action key %s", key));
                }
                for (int i = 0; i < 3; i++) {
                    print(String.format("=== InputMap type %d", i));
                    InputMap im = impl.searchBox.getInputMap(i);
                    KeyStroke[] allKeys = im.allKeys();
                    if (allKeys != null) {
                        for (KeyStroke ks : allKeys) {
                            print(String.format("  === keystroke %s object %s", ks, im.get(ks)));
                        }
                    }
                }

                // various experiments with FocusTraversalPolicy... NB LayoutTraversalPolicy
                // is what the framework uses here by default

                class MainFrameFocusTraversalPolicy extends LayoutTraversalPolicy {
                    public Component getComponentAfter(Container arg0, Component arg1) {
                        Component comp = super.getComponentAfter(arg0, arg1);
                        print(String.format("=== comp after %s", comp == null ? "Null" : comp.getClass()));
                        return comp;
                    }

                    public Component getComponentBefore(Container arg0, Component arg1) {
                        Component comp = super.getComponentBefore(arg0, arg1);
                        print(String.format("=== comp before %s", comp == null ? "Null" : comp.getClass()));
                        return comp;
                    }

                    public Component getDefaultComponent(Container arg0) {
                        Component comp = super.getDefaultComponent(arg0);
                        print(String.format("=== default comp %s", comp == null ? "Null" : comp.getClass()));
                        return comp;
                    }

                    public Component getFirstComponent(Container arg0) {
                        Component comp = super.getFirstComponent(arg0);
                        print(String.format("=== first comp %s", comp == null ? "Null" : comp.getClass()));

                        return comp;
                        // return impl.searchBox;
                    }

                    public Component getLastComponent(Container arg0) {
                        Component comp = super.getLastComponent(arg0);
                        print(String.format("=== last comp %s", comp == null ? "Null" : comp.getClass()));
                        return comp;
                    }

                    protected boolean accept(Component comp) {
                        boolean accept = super.accept(comp);
                        print(String.format("=== accept %s? %s", comp == null ? "Null" : comp.getClass(), accept));
                        return accept;
                    }
                }
                impl.mainFrame.setFocusTraversalPolicy(new MainFrameFocusTraversalPolicy());
            }
        }
        EventQueue.invokeAndWait(new AddMore());

    }

}

也许你可以使用容器#setFocusTraversalKeys(...) http://docs.oracle.com/javase/8/docs/api/java/awt/Container.html#setFocusTraversalKeys-int-java.util.Set- method:

Set<AWTKeyStroke> backwardKeys = Collections.emptySet();
//alone JTextField(pointed out by @mKorbel): impl.mainFrame.setFocusTraversalKeys(
impl.searchBox.setFocusTraversalKeys(
    KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java Swing:如何停止不需要的 Shift-Tab 击键操作 的相关文章

随机推荐

  • 如何获取打开的文件弹出窗口

    现在 我有一个设置的类路径 但我想要弹出一个打开的文件 并且用户选择要打开的文件 我尝试过 JFileChooser 但到目前为止还没有成功 这是我的代码 public static void main String args throws
  • 在 PHP 中删除数组项的最佳方法是什么?

    您能告诉我从数组中删除项目的方法吗 你觉得这样好吗 那要看 a1 array a gt 1 b gt 2 c gt 3 unset a1 b array a gt 1 c gt 3 a2 array 1 2 3 unset a2 1 arr
  • 可以在 t4 模板中使用全局变量吗?

    如何在 TT 文件中使用全局变量 如果我在标头中声明一个变量 并且在函数中引用它 则会出现编译错误 lt template debug false hostspecific false language C gt lt output ext
  • 如何使用Delphi在活动显示器的右下角显示消息窗口

    这些天你看到很多软件显示活动屏幕右下角的消息窗口几秒钟或直到单击关闭按钮 例如诺顿在检查下载后执行此操作 我想使用以下方法来做到这一点Delphi 7 如果可能的话德尔福2010 因为我正在慢慢地将代码迁移到最新版本 我在这里找到了一些关于
  • 将日期转换为 GMT - php

    我遇到了一个奇怪的问题 也许你可以帮忙 我正在尝试将日期转换为 GMT 时间 这就是我正在做的事情 date 2010 05 27 23 02 01 gmt date gmdate Y m d H i s date 但产量 gmt date
  • 如何对 Newtonsoft JArray 进行排序?

    是否可以排序JArray下面由col2例如 col1 thiscol col2 thisval col1 thiscol2 col2 thisval2 col1 thiscol3 col2 thisval3 如果将其转换为Array是唯一的
  • 如何在“if x in range”语句中使用浮点数

    我正在尝试写一个if将浮点数作为范围的语句 x 8 2 if x in range 0 4 4 print one if x in range 4 5 8 print two if x in range 8 1 9 9 print thre
  • 更新对象值 Ramda

    在上一个问题中 我尝试按父 ID 对数组进行分组 然后从每个对象中删除它们 按父 ID 对象 Ramda 对数组进行分组 https stackoverflow com q 58682137 9464680 但现在我有一个新问题 例如 我想
  • Android 致命信号 11 (SIGSEGV) at 0x00000040 (code=1) 错误

    我正在开发一个 Android 应用程序 我正在其中获取用户照片图像 5张图像 使用opencv2 4 2具有面部检测功能的相机 并使用 Web 服务保存到服务器中的数据库中 为此 我使用 Opencv2 4 2 人脸检测示例 Ksoap2
  • 裁剪以适合 svg 图案

    我有一些图案 每个图案中都有一个图像 我需要将图像缩放到其容器 即路径 的完整宽度或高度 同时保留其比例 本质上 如果您设置它们 它们的行为就需要像 html 图像一样min width 100 min height 100 我以前没有太多
  • swfupload 不允许我从一台服务器上传到另一台服务器

    我们有两个网络服务器 并且我们在这两个服务器之间专门执行任务 我们决定将所有 asp aspx 页面放入一台服务器中 并将 upload aspx sql 服务器放入另一台服务器中 这是服务器的名称 http server1 somecom
  • 为什么活动需要代表?为什么我们需要事件?

    过去几周我对发生的事情感到困惑 我了解代表如何工作 但不了解其详细工作方式 但足以了解这一点delegate datatype是单个演员委托 delegate void是一个多播委托 对方法的引用列表 我知道委托类型编译为类 但不幸的是我仍
  • 如何制作 npm 安装包并忽略一个(或所有)对等依赖项?

    I have email protected cdn cgi l email protection安装 我要安装vuex module decorators latest 其对等依赖性为vuex 3 not gt 3 我有一种感觉 这会很好
  • 从其他文件调用 php 类

    我正在研究一些自定义帖子类型 我完成了第一个 并意识到我正在使用的元框代码可以被其他未来的自定义帖子类型 以及页面 帖子等 重复使用 因此 我将该类放入其自己的 php 文件中 并将其包含在我的子主题的functions php 文件中 我
  • Haskell:无法导入 System.Random

    我已经按照找到的说明在 MacOS Mojave 上安装了 Haskellhere https www haskell org platform 即使用stack命令 然而 import System Random 带入ghci错误信息找不
  • 如何在 Oracle/SQL 中检索给定序列中的行?

    我有一个带有主键 MY PK 的表 MY TABLE 然后 我有一个有序主键列表 例如 17 13 35 2 9 现在我想检索具有这些主键的所有行 并以与给定键列表相同的方式保持行的顺序 我最初做的是 SELECT FROM MY TABL
  • 如何知道是否发生欠拟合或过拟合?

    我正在尝试用两个类进行图像分类 我有 1000 张具有平衡类别的图像 当我训练模型时 我得到了较低的恒定验证准确性 但验证损失却在减少 这是过度拟合或欠拟合的迹象吗 我还应该注意到 我正在尝试使用新类和不同的数据集重新训练 Inceptio
  • 无需外部库即可在 C# 中播放动态创建的简单声音

    我需要能够使用 C 动态生成波形并播放它 无需任何外部库 也无需在硬盘上存储声音文件 延迟不是问题 声音将在应用程序需要之前生成 实际上 如果不是微软表示 64 位版本的 Windows 不支持 Console Beep 方法 它可能会满足
  • 调用 getNextException 查看原因:How to make Hibernate / JPA show the DB server message for an exception

    我正在使用 Postgresql Hibernate 和 JPA 每当数据库中出现异常时 我都会得到类似的信息 这不是很有帮助 因为它没有显示数据库服务器上真正出了什么问题 Caused by java sql BatchUpdateExc
  • Java Swing:如何停止不需要的 Shift-Tab 击键操作

    当我在 JPanel 中有一个 JTextField 并且它具有焦点时 按 tab 不会执行任何操作 但按 shift tab 会导致焦点丢失 FocusEvent getOppositeComponent 为 null 如果 JPanel