JOptionPane showMessageDialog - 取消焦点 'OK' 按钮
JOptionPane showMessageDialog - Un-focus 'OK' button
我正在尝试创建只有一个按钮(即确定)的 showMessageDialog
。我希望那个按钮没有焦点。这意味着当对话框打开时,用户单击 Enter 键,对话框不应关闭。使用时必须单击 'OK' 按钮,然后只有对话框会消失。
但我现在得到的是 'OK' 按钮始终处于焦点状态。所以当对话框弹出时,用户没有看到并按下 Enter 键,对话框关闭。
为什么我需要这个:这不是错误消息。用户在继续之前必须看到的唯一信息性消息。在这种情况下,大显示器离用户位置有点远。我已经编写了在对话框出现时发出声音的代码,但用户可能听不到并按下 Enter 键。所以我希望用户看到对话框并单击“确定”按钮
示例代码:
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.Color;
import java.awt.Font;
public class MessageDialogInFrame extends JFrame{
public MessageDialogInFrame() {
getContentPane().setBackground(Color.DARK_GRAY);
setTitle("Message Dialog in Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
setSize(400, 300);
getContentPane().setLayout(null);
}
public static void main(String[] args){
ImageIcon icon = new ImageIcon("src/images/turtle64.png");
JTextArea commentTextArea = new JTextArea("Hello", 10, 50);
commentTextArea.setBackground(Color.YELLOW);
Font font = new java.awt.Font("Dialog", 0, 15);
commentTextArea.setFont(font);
commentTextArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(commentTextArea);
scrollPane.setBackground(Color.YELLOW);
JOptionPane.showMessageDialog(new MessageDialogInFrame(),
"I appear as part of the frame!!", "Customized Dialog",
JOptionPane.INFORMATION_MESSAGE, icon);
}
}
原码:
private static int showColoredDialog(int category, Component parentComp, String message, String title, int optionType, int messageType, Color color) {
JTextArea commentTextArea = new JTextArea(message, 10, 50);
commentTextArea.setBackground(color);
commentTextArea.setFont(UiFactory.getInfo().getLabelFont());
commentTextArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(commentTextArea);
scrollPane.setBackground(color);
switch (category) {
case 0:
JOptionPane.showMessageDialog(parentComp, scrollPane, title, messageType);
return 0;
case 1:
return JOptionPane.showConfirmDialog(parentComp, scrollPane, title, optionType, messageType);
}
return -1;
}
解决方案:
int result = JOptionPane.CLOSED_OPTION;
final JOptionPane pane = new JOptionPane(scrollPane, JOptionPane.WARNING_MESSAGE, JOptionPane.OK_OPTION, null, new String[] {"OK"});
JDialog dialog = pane.createDialog(null, title);
commentTextArea.requestFocus();
dialog.setVisible(true);
if (pane.getValue() != null) result = JOptionPane.OK_OPTION;
return result;
一种方法:通过其构造函数创建一个 JOptionPane 对象,递归地在其组件树中搜索 JButton,并将其设为 non-focusable:
JOptionPane optionPane = new JOptionPane();
optionPane.setMessage("Fubars Rule!");
optionPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
optionPane.setOptionType(JOptionPane.DEFAULT_OPTION);
recursiveUnfocusButtons(optionPane);
JDialog dialog = optionPane.createDialog(null, "Option Title");
dialog.setVisible(true);
System.exit(0);
还有魔术酱:
private static void recursiveUnfocusButtons(Component component) {
if (component instanceof JButton) {
component.setFocusable(false);
return;
} else if (component instanceof Container) {
for (Component c : ((Container) component).getComponents()) {
recursiveUnfocusButtons(c);
}
}
}
要取消输入操作,您需要更改 JOptionPane 中输入键的键绑定:
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class JOptionNoFocus {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JOptionPane optionPane = new JOptionPane();
optionPane.setMessage("Fubars Rule!");
optionPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
optionPane.setOptionType(JOptionPane.DEFAULT_OPTION);
KeyStroke enterStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
optionPane.getInputMap(JComponent.WHEN_FOCUSED).put(enterStroke, enterStroke.toString());
optionPane.getActionMap().put(enterStroke.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
// do nothing
}
});
recursiveUnfocusButtons(optionPane);
JDialog dialog = optionPane.createDialog(null, "Option Title");
dialog.setVisible(true);
System.exit(0);
});
}
private static void recursiveUnfocusButtons(Component component) {
if (component instanceof JButton) {
JButton button = (JButton) component;
button.setFocusable(false);
return;
} else if (component instanceof Container) {
for (Component c : ((Container) component).getComponents()) {
recursiveUnfocusButtons(c);
}
}
}
}
不过,一旦您开始创建更复杂的对话框,只需跳过创建 JDialog 的步骤,而是创建您自己的 JDialog,将组件放置在您想要的位置。如果您希望它们在处理之前停止应用程序,请将它们设置为模态。
我正在尝试创建只有一个按钮(即确定)的 showMessageDialog
。我希望那个按钮没有焦点。这意味着当对话框打开时,用户单击 Enter 键,对话框不应关闭。使用时必须单击 'OK' 按钮,然后只有对话框会消失。
但我现在得到的是 'OK' 按钮始终处于焦点状态。所以当对话框弹出时,用户没有看到并按下 Enter 键,对话框关闭。
为什么我需要这个:这不是错误消息。用户在继续之前必须看到的唯一信息性消息。在这种情况下,大显示器离用户位置有点远。我已经编写了在对话框出现时发出声音的代码,但用户可能听不到并按下 Enter 键。所以我希望用户看到对话框并单击“确定”按钮
示例代码:
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.Color;
import java.awt.Font;
public class MessageDialogInFrame extends JFrame{
public MessageDialogInFrame() {
getContentPane().setBackground(Color.DARK_GRAY);
setTitle("Message Dialog in Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
setSize(400, 300);
getContentPane().setLayout(null);
}
public static void main(String[] args){
ImageIcon icon = new ImageIcon("src/images/turtle64.png");
JTextArea commentTextArea = new JTextArea("Hello", 10, 50);
commentTextArea.setBackground(Color.YELLOW);
Font font = new java.awt.Font("Dialog", 0, 15);
commentTextArea.setFont(font);
commentTextArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(commentTextArea);
scrollPane.setBackground(Color.YELLOW);
JOptionPane.showMessageDialog(new MessageDialogInFrame(),
"I appear as part of the frame!!", "Customized Dialog",
JOptionPane.INFORMATION_MESSAGE, icon);
}
}
原码:
private static int showColoredDialog(int category, Component parentComp, String message, String title, int optionType, int messageType, Color color) {
JTextArea commentTextArea = new JTextArea(message, 10, 50);
commentTextArea.setBackground(color);
commentTextArea.setFont(UiFactory.getInfo().getLabelFont());
commentTextArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(commentTextArea);
scrollPane.setBackground(color);
switch (category) {
case 0:
JOptionPane.showMessageDialog(parentComp, scrollPane, title, messageType);
return 0;
case 1:
return JOptionPane.showConfirmDialog(parentComp, scrollPane, title, optionType, messageType);
}
return -1;
}
解决方案:
int result = JOptionPane.CLOSED_OPTION;
final JOptionPane pane = new JOptionPane(scrollPane, JOptionPane.WARNING_MESSAGE, JOptionPane.OK_OPTION, null, new String[] {"OK"});
JDialog dialog = pane.createDialog(null, title);
commentTextArea.requestFocus();
dialog.setVisible(true);
if (pane.getValue() != null) result = JOptionPane.OK_OPTION;
return result;
一种方法:通过其构造函数创建一个 JOptionPane 对象,递归地在其组件树中搜索 JButton,并将其设为 non-focusable:
JOptionPane optionPane = new JOptionPane();
optionPane.setMessage("Fubars Rule!");
optionPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
optionPane.setOptionType(JOptionPane.DEFAULT_OPTION);
recursiveUnfocusButtons(optionPane);
JDialog dialog = optionPane.createDialog(null, "Option Title");
dialog.setVisible(true);
System.exit(0);
还有魔术酱:
private static void recursiveUnfocusButtons(Component component) {
if (component instanceof JButton) {
component.setFocusable(false);
return;
} else if (component instanceof Container) {
for (Component c : ((Container) component).getComponents()) {
recursiveUnfocusButtons(c);
}
}
}
要取消输入操作,您需要更改 JOptionPane 中输入键的键绑定:
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class JOptionNoFocus {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JOptionPane optionPane = new JOptionPane();
optionPane.setMessage("Fubars Rule!");
optionPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
optionPane.setOptionType(JOptionPane.DEFAULT_OPTION);
KeyStroke enterStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
optionPane.getInputMap(JComponent.WHEN_FOCUSED).put(enterStroke, enterStroke.toString());
optionPane.getActionMap().put(enterStroke.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
// do nothing
}
});
recursiveUnfocusButtons(optionPane);
JDialog dialog = optionPane.createDialog(null, "Option Title");
dialog.setVisible(true);
System.exit(0);
});
}
private static void recursiveUnfocusButtons(Component component) {
if (component instanceof JButton) {
JButton button = (JButton) component;
button.setFocusable(false);
return;
} else if (component instanceof Container) {
for (Component c : ((Container) component).getComponents()) {
recursiveUnfocusButtons(c);
}
}
}
}
不过,一旦您开始创建更复杂的对话框,只需跳过创建 JDialog 的步骤,而是创建您自己的 JDialog,将组件放置在您想要的位置。如果您希望它们在处理之前停止应用程序,请将它们设置为模态。