为了在输入对话框中有自定义按钮标题,我创建了以下代码:
String key = null;
JTextField txtKey = new JTextField();
int answerKey = JOptionPane.showOptionDialog(this, new Object[] {pleaseEnterTheKey, txtKey}, decryptionKey, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] {okCaption, cancelCaption}, okCaption);
if (answerKey == JOptionPane.OK_OPTION && txtKey.getText() != null) {
key = txtKey.getText();
}
如何在显示对话框时将焦点(光标)移动到文本字段?
更新
这对我不起作用,我的意思是文本字段没有焦点: 操作系统:Fedora - Gnome
public class Test {
public static void main(String[] args) {
String key = null;
JTextField txtKey = new JTextField();
txtKey.addAncestorListener(new RequestFocusListener());
int answerKey = JOptionPane.showOptionDialog(null, new Object[]{"Please enter the key:", txtKey}, "Title", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[]{"OKKK", "CANCELLLL"}, "OKKK");
if (answerKey == JOptionPane.OK_OPTION && txtKey.getText() != null) {
key = txtKey.getText();
}
}
}
答案 0 :(得分:14)
Dialog Focus显示了如何轻松地将焦点设置在模态对话框中的任何组件上。
答案 1 :(得分:8)
public static String getPassword(String title) {
JPanel panel = new JPanel();
final JPasswordField passwordField = new JPasswordField(10);
panel.add(new JLabel("Password"));
panel.add(passwordField);
JOptionPane pane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
@Override
public void selectInitialValue() {
passwordField.requestFocusInWindow();
}
};
pane.createDialog(null, title).setVisible(true);
return passwordField.getPassword().length == 0 ? null : new String(passwordField.getPassword());
}
答案 2 :(得分:5)
传递null作为最后一个参数是解决方案。至少它对我有用。
String key = null;
JTextField txtKey = new JTextField();
int answerKey = JOptionPane.showOptionDialog(this, new Object[] {pleaseEnterTheKey, txtKey}, decryptionKey, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] {okCaption, cancelCaption}, null);
if (answerKey == JOptionPane.OK_OPTION && txtKey.getText() != null) {
key = txtKey.getText();
}
但即便是这个解决方案也会带来另一个问题:
专注组件和默认组件不同。默认组件或默认按钮是按下ENTER KEY
时触发其onclick的按钮。最后一个参数定义了获得焦点的默认组件,并且传递null会带来没有默认组件的问题!
我通过这种方式为我的代码解决了它,但我想这不是最佳实践:
String key = null;
final JTextField txtKey = new JTextField();
txtKey.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == 10) { //enter key
Container parent = txtKey.getParent();
while (!(parent instanceof JOptionPane)) {
parent = parent.getParent();
}
JOptionPane pane = (JOptionPane) parent;
final JPanel pnlBottom = (JPanel) pane.getComponent(pane.getComponentCount() - 1);
for (int i = 0; i < pnlBottom.getComponents().length; i++) {
Component component = pnlBottom.getComponents()[i];
if (component instanceof JButton) {
final JButton okButton = ((JButton)component);
if (okButton.getText().equalsIgnoreCase(okCaption)) {
ActionListener[] actionListeners = okButton.getActionListeners();
if (actionListeners.length > 0) {
actionListeners[0].actionPerformed(null);
}
}
}
}
}
}
});
答案 3 :(得分:4)
我遇到同样的问题,RequestFocusListener()无法在Linux上运行,在对http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5018574进行讨论之后,我发现添加一个invokeLater现在修复了它...
public class RequestFocusListener implements AncestorListener
{
public void ancestorAdded(final AncestorEvent e)
{
final AncestorListener al= this;
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
JComponent component = (JComponent)e.getComponent();
component.requestFocusInWindow();
component.removeAncestorListener( al );
}
});
}
public void ancestorMoved(AncestorEvent e) {}
public void ancestorRemoved(AncestorEvent e) {}
}
答案 4 :(得分:2)
诀窍是(a)在文本组件上使用AncestorListener来请求焦点,当焦点再次丢失时(赋予默认按钮),请在文本组件上使用FocusListener再次请求焦点(但在此之后不要继续寻求关注):
final JPasswordField accessPassword = new JPasswordField();
accessPassword.addAncestorListener( new AncestorListener()
{
@Override
public void ancestorRemoved( final AncestorEvent event )
{
}
@Override
public void ancestorMoved( final AncestorEvent event )
{
}
@Override
public void ancestorAdded( final AncestorEvent event )
{
// Ask for focus (we'll lose it again)
accessPassword.requestFocusInWindow();
}
} );
accessPassword.addFocusListener( new FocusListener()
{
@Override
public void focusGained( final FocusEvent e )
{
}
@Override
public void focusLost( final FocusEvent e )
{
if( isFirstTime )
{
// When we lose focus, ask for it back but only once
accessPassword.requestFocusInWindow();
isFirstTime = false;
}
}
private boolean isFirstTime = true;
} );
答案 5 :(得分:1)
试试这个
String key = null;
JTextField txtKey = new JTextField();
Object[] foo = {pleaseEnterTheKey, txtKey};
int answerKey = JOptionPane.showOptionDialog(this, foo, decryptionKey, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] {okCaption, cancelCaption}, foo[1]);
if (answerKey == JOptionPane.OK_OPTION && txtKey.getText() != null) {
key = txtKey.getText();
}
答案 6 :(得分:1)
更好的方法:使用构造函数创建JOptionPane,覆盖selectInitialValue以设置焦点,然后使用createDialog构建对话框。
// Replace by the constructor you want
JOptionPane pane = new JOptionPane(panel, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
@Override
public void selectInitialValue() {
textArea.requestFocusInWindow();
}
};
JDialog dialog = pane.createDialog(owner, title);
dialog.setVisible(true);
答案 7 :(得分:0)
我找到了解决方案! 非常原始,但有效。
通过java.awt跳转到该字段。机器人使用键&#34; Tab&#34;。 例如:
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(100);
robot.keyRelease(KeyEvent.VK_TAB);
如果你应该多按几次&#34; Tab&#34;要获得您的组件,您可以使用以下方法:
GUIUtils.pressTab(3);
定义:
public static void pressTab(int amountOfClickes)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
Robot robot = new Robot();
int i = amountOfClickes;
while (i-- > 0)
{
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(100);
robot.keyRelease(KeyEvent.VK_TAB);
}
}
catch (AWTException e)
{
System.out.println("Failed to use Robot, got exception: " + e.getMessage());
}
}
});
}
如果你的Component位置是动态的,你可以无限制地运行while循环,但是在组件上添加一些焦点监听器,一旦到达它就停止循环。