我正在尝试创建仅具有一个按钮的showMessageDialog
(即确定)。我希望该按钮不集中。这意味着当对话框打开时,如果用户单击Enter键,则对话框不应关闭。使用必须点击“确定”按钮,然后只有对话框会消失。
但是我现在总是将“确定”按钮对准焦点。因此,当对话框弹出时,用户看不到并按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;
答案 0 :(得分:1)
一种方法:通过其构造函数创建JOptionPane对象,递归地在其组件树中搜索JButton,并使它不可聚焦:
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);
}
}
}
要摆脱Enter操作,您需要在JOptionPane中更改Enter键的键绑定:
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);
}
}
}
}
但是,一旦您要创建更复杂的对话框,只需跳过创建JDialogs的步骤,而是创建自己的JDialog,将其放置在所需位置的组件即可。如果希望他们在处理之前停止应用程序,请将它们设为模态。