Господа, не могу решить проблему, не хватает знания свинга.
Дано: форма с четырьмя текстовыми полями. Для всех полей определены InputVerifier-ы, которые не выпускают из поля, пока оно пустое. Нужно чтобы в зависимости от введённого значения в первом поле, по нажатию tab фокус перешёл или на третье или на четвёртое.
Например, я вешаю листенер на focusLost и там пытаюсь переместить фокус на третье или на четвёртое поле, однако фокус уже перешёл на второе поле и выйти из него не может, так как оно не пустое.
Задача имеет весьма практическое значение, например форма ввода платёжки, все поля обязательные, по вводу счёта получателя мы определяем свой ли это клиент и если это свой - информация о нём есть в БД и вводить её не нужно, переходим на другие поля, если счёт чужой - вводим.
Что делать?
Пример кода для демонстрации проблемы:
import javax.swing.InputVerifier;
import javax.swing.JComponent;
public class NewJDialog extends javax.swing.JDialog
{
public NewJDialog(java.awt.Frame parent, boolean modal)
{
super(parent, modal);
initComponents();
jTextField1.setInputVerifier( new InputVerifier() {
@Override public boolean verify( JComponent input ) {
return !jTextField1.getText().isEmpty();
}
});
jTextField2.setInputVerifier( new InputVerifier() {
@Override public boolean verify( JComponent input ) {
return !jTextField2.getText().isEmpty();
}
});
jTextField3.setInputVerifier( new InputVerifier() {
@Override public boolean verify( JComponent input ) {
return !jTextField3.getText().isEmpty();
}
});
jTextField4.setInputVerifier( new InputVerifier() {
@Override public boolean verify( JComponent input ) {
return !jTextField4.getText().isEmpty();
}
});
}
@SuppressWarnings("unchecked")
//
private void initComponents() {
jTextField1 = new javax.swing.JTextField();
jTextField2 = new javax.swing.JTextField();
jTextField3 = new javax.swing.JTextField();
jTextField4 = new javax.swing.JTextField();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
getContentPane().setLayout(new java.awt.GridLayout(2, 2, 5, 5));
jTextField1.setColumns(10);
jTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(java.awt.event.FocusEvent evt) {
jTextField1FocusLost(evt);
}
});
getContentPane().add(jTextField1);
jTextField2.setColumns(10);
getContentPane().add(jTextField2);
jTextField3.setColumns(10);
getContentPane().add(jTextField3);
jTextField4.setColumns(10);
getContentPane().add(jTextField4);
pack();
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
java.awt.Dimension dialogSize = getSize();
setLocation((screenSize.width-dialogSize.width)/2,(screenSize.height-dialogSize.height)/2);
}//
private void jTextField1FocusLost(java.awt.event.FocusEvent evt)
{
// если jTextField1 содержит "0" - пытаемся перейти к четвёртому полю, иначе к третьему
if ( jTextField1.getText().equals( "0" ) ) {
jTextField4.requestFocusInWindow();
}
else {
jTextField3.requestFocusInWindow();
}
}
public static void main(String args[])
{
NewJDialog dialog = new NewJDialog(new javax.swing.JFrame(), true);
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
@Override public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
} } );
dialog.setVisible(true);
}
// Variables declaration - do not modify
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
private javax.swing.JTextField jTextField4;
// End of variables declaration
}
UPD: вариант решения - использовать свой InputVerifier, вот примерно такой:
public abstract class MyInputVerifier extends InputVerifier
{
private static boolean enableYieldFocus = false;
@Override
public boolean shouldYieldFocus( JComponent input ) {
return ( enableYieldFocus || super.shouldYieldFocus( input ) );
}
public static boolean setFocus( JComponent comp )
{
try
{
enableYieldFocus = true;
return comp.requestFocusInWindow();
}
finally {
enableYieldFocus = false;
}
}
}
Так что "new InputVerifier()" меняем на "new MyInputVerifier()", а в jTextField1FocusLost() вместо "поле.requestFocusInWindow()" используем "MyInputVerifier.setFocus(поле)".
Однако, если есть ещё варианты решения - предлагайте.