В принципе, у вас есть несколько проблем, которые борются друг с другом, чтобы их решить :-)
- изначально сфокусированный компонент: использовать метод createOptionDialog для передачи нескольких пользовательских компонентов в поле сообщения, а начальный - как initialSelectionValue, немного хитро.
- настраиваемые кнопки: опять-таки это небольшая хитрость, чтобы передать пользовательский текст (или реальные кнопки, на самом деле не имеет значения) в качестве параметра параметров. Фактически, это должен быть выбор, доступный пользователю, один из которых является изначально выбранным (который затем получает фокус)
- действие над текстовым полем и первая кнопка (== кнопка по умолчанию во вложенной корневой панели): здесь само поле стоит так, чтобы разрешить и то и другое, так как оно съедает клавишу ввода
последнее может быть решено с помощью пользовательского подкласса JTextField, точно так же, как BasicOptionPaneUI использует для inputDialog, это показано в конце - полезно в контексте optionPane, только если первые два решены. Для которого я не нашел полностью удовлетворительного решения: смешивание понятия «сообщение» с понятием «параметры» путает optionPane с , а не установкой кнопки по умолчанию для корневой панели. Поэтому, в конце концов, вам может быть лучше не использовать этот первый трюк, придерживайтесь понятия «опции», а затем обманывайте фокус, запрашивая передачу в поле addNotify.
@Override
public void addNotify() {
super.addNotify();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
requestFocus();
}
});
}
Пользовательский JTextField, который не использует определенные нажатия клавиш. Он называется MultiplexingTextField и передает обработку keyStrokes, если настроен для этого:
public static class MultiplexingTextField extends JTextField {
private List<KeyStroke> strokes;
public MultiplexingTextField(int cols) {
super(cols);
}
/**
* Sets the KeyStrokes that will be additionally processed for
* ancestor bindings.
*/
public void addKeyStrokes(KeyStroke... keyStrokes) {
for (KeyStroke keyStroke : keyStrokes) {
getMultiplexingStrokes().add(keyStroke);
}
}
private List<KeyStroke> getMultiplexingStrokes() {
if (strokes == null) {
strokes = new ArrayList<KeyStroke>();
}
return strokes;
}
@Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
int condition, boolean pressed) {
boolean processed = super.processKeyBinding(ks, e, condition,
pressed);
if (processed && condition != JComponent.WHEN_IN_FOCUSED_WINDOW
&& getMultiplexingStrokes().contains(ks)) {
// Returning false will allow further processing
// of the bindings, eg our parent Containers will get a
// crack at them.
return false;
}
return processed;
}
}
использование в контролируемой среде:
Action fieldAction = new AbstractAction("fieldAction") {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("hello " + ((JTextComponent) e.getSource()).getText());
}
};
JTextField field = new JTextField("this is a normal field");
MultiplexingTextField multiplexing = new MultiplexingTextField(20);
multiplexing.addKeyStrokes(KeyStroke.getKeyStroke("ENTER"));
field.setAction(fieldAction);
multiplexing.setAction(fieldAction);
Action action = new AbstractAction("default button action") {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("hello - got default button");
}
};
JButton button = new JButton(action);
JPanel panel = new JPanel();
panel.add(field);
panel.add(multiplexing);
panel.add(button);
// this is swingx testing support, simply replace with normal frame creation
JXFrame frame = wrapInFrame(panel, "multiplex");
frame.getRootPane().setDefaultButton(button);