禁用 JButton 时 JFrame 焦点问题
Issue with JFrame focus when disabling JButton
我的 Java 应用程序遇到了一个非常奇怪的问题。我正在使用 Netbeans,所以我有一个带有主面板的 frameview,其中有一些按钮可以选择串行端口并连接到它。它还有一个菜单栏可以打开一堆不同的框架。
问题是:有时当我打开另一个框架时,如果我点击回到我的主面板,焦点会立即回到打开的框架(而不是我刚刚点击的面板)。当它执行此操作时,它还会突出显示此打开的框架中的 JComponents,基本上是通过在主面板上每次单击和释放鼠标来切换它们。所以总而言之,焦点不断从我点击的框架跳开。我正在使用 autoRequestFocus。
我缩小了范围,发现这只发生在我点击连接到串行端口按钮后打开的第一帧。所以我会:
启动应用程序->连接到串口->从菜单栏打开不同的框架->点击回到主面板,但我的焦点立即回到打开的框架
所以我意识到它必须是我连接到串行端口 JToggleButton 方法中的东西。最后,我发现如果我注释掉一行代码,问题就解决了。那一行是:
refreshPortsButton.setEnabled(false);
refreshPortsButton
填充可用串口列表,我不希望人们在连接后这样做。
我有一个变通方法,将按钮的可见性设置为 false,但我宁愿将按钮显示为灰色,这种行为对我来说太奇怪了,我真的很想弄明白。启用按钮的状态怎么可能搞乱事情的焦点。
这是一个SSCCE,我尽量简化了它,对不起长initComponents
FocusSSCCEApp.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);
}
}
FocusSSCCEView.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 应用程序遇到了一个非常奇怪的问题。我正在使用 Netbeans,所以我有一个带有主面板的 frameview,其中有一些按钮可以选择串行端口并连接到它。它还有一个菜单栏可以打开一堆不同的框架。
问题是:有时当我打开另一个框架时,如果我点击回到我的主面板,焦点会立即回到打开的框架(而不是我刚刚点击的面板)。当它执行此操作时,它还会突出显示此打开的框架中的 JComponents,基本上是通过在主面板上每次单击和释放鼠标来切换它们。所以总而言之,焦点不断从我点击的框架跳开。我正在使用 autoRequestFocus。
我缩小了范围,发现这只发生在我点击连接到串行端口按钮后打开的第一帧。所以我会: 启动应用程序->连接到串口->从菜单栏打开不同的框架->点击回到主面板,但我的焦点立即回到打开的框架
所以我意识到它必须是我连接到串行端口 JToggleButton 方法中的东西。最后,我发现如果我注释掉一行代码,问题就解决了。那一行是:
refreshPortsButton.setEnabled(false);
refreshPortsButton
填充可用串口列表,我不希望人们在连接后这样做。
我有一个变通方法,将按钮的可见性设置为 false,但我宁愿将按钮显示为灰色,这种行为对我来说太奇怪了,我真的很想弄明白。启用按钮的状态怎么可能搞乱事情的焦点。 这是一个SSCCE,我尽量简化了它,对不起长initComponents
FocusSSCCEApp.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);
}
}
FocusSSCCEView.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());
}