java - 禁用 JButton 时 JFrame 焦点问题

标签 java jframe focus jbutton

我的 Java 应用程序遇到了一个非常奇怪的问题。我正在使用 Netbeans,因此我有一个带有主面板的框架 View ,其中有一些按钮用于选择串行端口并连接到它。它还有一个菜单栏可以打开一堆不同的框架。

问题是:有时当我打开另一个框架时,如果我单击回到主面板,焦点会立即返回到打开的框架(而不是我刚刚单击的面板)。当它执行此操作时,它还会突出显示此打开的框架中的 JComponent,基本上是通过每次在主面板上单击并释放鼠标来按 Tab 键浏览它们。总而言之,焦点不断从我点击的框架上跳开。我正在使用 autoRequestFocus。

我缩小了范围,发现这只发生在我点击“连接到串行端口”按钮后打开的第一个框架上。所以我会: 启动应用程序->连接到串行端口->从菜单栏打开不同的框架->单击返回主面板,但让我的焦点立即返回到打开的框架

所以我意识到它必须是我的连接到串行端口 JToggleButton 方法中的某些内容。最后我发现,如果我注释掉一行代码,问题就解决了。该行是:

refreshPortsButton.setEnabled(false);

refreshPortsButton 填充可用串行端口的列表,我不希望人们在连接后执行此操作。

我有一个解决方法,将按钮的可见性设置为 false,但我宁愿将按钮变灰,这种行为对我来说太奇怪了,我真的很想弄清楚。按钮启用状态怎么可能会扰乱事物的焦点。 这是一个 SSCCE,我尝试尽可能简化它,抱歉 initComponents 太长了

焦点SSCCEApp.java

package focussscce;

import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;

public class FocusSSCCEApp extends SingleFrameApplication {

    @Override protected void startup() {
        show(new FocusSSCCEView(this));
    }


    @Override protected void configureWindow(java.awt.Window root) {
    }


    public static FocusSSCCEApp getApplication() {
        return Application.getInstance(FocusSSCCEApp.class);
    }


    public static void main(String[] args) {
        launch(FocusSSCCEApp.class, args);
    }
}

焦点SSCCEView.java

package focussscce;

import java.awt.Color;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import java.awt.event.ItemEvent;

/**
 * The application's main frame.
 */
public class FocusSSCCEView extends FrameView {

    public final static Color DARK_GREEN = new Color(0, 150, 0);

    public FocusSSCCEView(SingleFrameApplication app) {
        super(app);

        initComponents();
        this.getFrame().setResizable(false);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        mainPanel = new javax.swing.JPanel();
        refreshPortsButton = new javax.swing.JButton();
        connectToggleButton = new javax.swing.JToggleButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu prefMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem prefMenuItem = new javax.swing.JMenuItem();
        preferencesFrame = new javax.swing.JFrame();
        textField1 = new javax.swing.JTextField();
        textField2 = new javax.swing.JTextField();

        mainPanel.setMaximumSize(new java.awt.Dimension(150, 50));
        mainPanel.setName("mainPanel"); // NOI18N
        mainPanel.setPreferredSize(new java.awt.Dimension(493, 50));
        mainPanel.setLayout(new java.awt.GridLayout());

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(focussscce.FocusSSCCEApp.class).getContext().getResourceMap(FocusSSCCEView.class);
        refreshPortsButton.setText(resourceMap.getString("refreshPortsButton.text")); // NOI18N
        refreshPortsButton.setName("refreshPortsButton"); // NOI18N
        refreshPortsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshPortsButtonActionPerformed(evt);
            }
        });
        mainPanel.add(refreshPortsButton);

        connectToggleButton.setText(resourceMap.getString("connectToggleButton.text")); // NOI18N
        connectToggleButton.setFocusPainted(false);
        connectToggleButton.setFocusable(false);
        connectToggleButton.setName("connectToggleButton"); // NOI18N
        connectToggleButton.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                connectToggleButtonItemStateChanged(evt);
            }
        });
        mainPanel.add(connectToggleButton);

        menuBar.setName("menuBar"); // NOI18N

        prefMenu.setText(resourceMap.getString("prefMenu.text")); // NOI18N
        prefMenu.setName("prefMenu"); // NOI18N

        prefMenuItem.setText(resourceMap.getString("prefMenuItem.text")); // NOI18N
        prefMenuItem.setName("prefMenuItem"); // NOI18N
        prefMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                prefMenuItemActionPerformed(evt);
            }
        });
        prefMenu.add(prefMenuItem);

        menuBar.add(prefMenu);

        preferencesFrame.setTitle(resourceMap.getString("preferencesFrame.title")); // NOI18N
        preferencesFrame.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        preferencesFrame.setMinimumSize(new java.awt.Dimension(100, 70));
        preferencesFrame.setName("preferencesFrame"); // NOI18N
        preferencesFrame.setResizable(false);
        preferencesFrame.getContentPane().setLayout(new java.awt.GridLayout());

        textField1.setName("textField1"); // NOI18N
        textField1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                textField1MouseEntered(evt);
            }
        });
        preferencesFrame.getContentPane().add(textField1);

        textField2.setName("textField2"); // NOI18N
        textField2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                textField2MouseEntered(evt);
            }
        });
        preferencesFrame.getContentPane().add(textField2);

        setComponent(mainPanel);
        setMenuBar(menuBar);
    }// </editor-fold>                        

    private void refreshPortsButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                   
        //populateCommPort();
    }                                                  

    private void connectToggleButtonItemStateChanged(java.awt.event.ItemEvent evt) {                                                     
        if (evt.getStateChange() == ItemEvent.SELECTED) {

            //connect();
            connectToggleButton.setText("Disconnect");
            connectToggleButton.setForeground(DARK_GREEN);
            refreshPortsButton.setEnabled(false); //Disabling this remedies the problem
        } else if (evt.getStateChange() == ItemEvent.DESELECTED) {
            //disconnect();
            refreshPortsButton.setEnabled(true);
            connectToggleButton.setText("Connect");
            connectToggleButton.setForeground(Color.BLACK);
        }
    }                                                    

    private void textField1MouseEntered(java.awt.event.MouseEvent evt) {                                        
        textField1.setToolTipText( textField1.getText() );
    }                                       

    private void prefMenuItemActionPerformed(java.awt.event.ActionEvent evt) {                                             
        preferencesFrame.setVisible( true );
        preferencesFrame.requestFocusInWindow();
        preferencesFrame.pack();
    }                                            

    private void textField2MouseEntered(java.awt.event.MouseEvent evt) {                                        
        textField2.setToolTipText( textField2.getText() );
    }                                       

    // Variables declaration - do not modify                     
    private javax.swing.JToggleButton connectToggleButton;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JFrame preferencesFrame;
    private javax.swing.JButton refreshPortsButton;
    private javax.swing.JTextField textField1;
    private javax.swing.JTextField textField2;
    // End of variables declaration                   
}

最佳答案

我相信当你的框架上有一个可聚焦的组件时,java会在它上面绘制焦点矩形。

我添加了另一个按钮,一旦禁用 refreshPortsButton 按钮,焦点就会自动跳转到下一个可聚焦的按钮。

我禁用了refreshPortsButton上的focusPaint,它工作得很好。启用按钮后,您可以重新启用它。

private void bConnectActionPerformed(ActionEvent evt) {                                   
    refresh.setEnabled(!refresh.isEnabled());
    refresh.setFocusPainted(refresh.isEnabled());
    if (refresh.isEnabled()) {
        refresh.requestFocus();
    }
    b2.setEnabled(!b2.isEnabled());
    b2.setFocusPainted(b2.isEnabled());
} 

关于java - 禁用 JButton 时 JFrame 焦点问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29975171/

相关文章:

java - Parceler:无法找到 ForeignCollection 类型的读/写生成器

java - find 挂起应用程序后 EntityManager 仍保留

java - Android中Activity之间的异常解析

java - 如何修复位于另一个预先绘制的 JPanel 之上的 JPanel 上的动态移动图像的闪烁?

java - Swing 检查窗口是否打开

javascript - jQuery 微醉插件。焦点触发不起作用

javascript - 避免点击触发焦点偏离

java - 作为非阻塞 Java 运行外部进程

java - 将 JPanel 嵌入框架中

Qt4:调整哪个小部件专注于开始