java中的focuslost问题

时间:2014-11-29 16:34:31

标签: java netbeans jtextfield

我有以下代码在我看来正常工作,但是当我尝试输入新记录时,在包机字段和字段名称之间开始闪烁,这会在执行验证以查看jtexfiedl是否为空时发生。

这里的代码。

public void validarCedula(JTextField txt, JLabel lblMensaje) {
    texto = txt.getText().trim();
    tamanio = texto.length();
    lblMensaje.setText("");        
    try{
    if (texto.isEmpty()) 
    {
        lblMensaje.setText("Cedula Vacio");
        lblMensaje.setForeground(Color.red);
        txt.requestFocus();
    }
    else if (tamanio > 0 && tamanio < 9) {
        lblMensaje.setText("Cedula Incorrecta");
        lblMensaje.setForeground(Color.red);
        txt.requestFocus();
    } else if (tamanio == 10) {
        lblMensaje.setText("Cedula Correcta");
        lblMensaje.setForeground(Color.white);
    } else if (tamanio > 11 && tamanio < 13) {
        lblMensaje.setText("RUC Incorrecto");
        lblMensaje.setForeground(Color.red);
        txt.requestFocus();
    } else if (tamanio == 13) {
        lblMensaje.setText("R.U.C Correcto");
        lblMensaje.setForeground(Color.WHITE);
    }
    }catch(Exception ex)
    {
        JOptionPane.showMessageDialog(null, ex);
    }
}


public void validarNombre(JTextField txt, JLabel lblMensaje) {
    texto = txt.getText().trim();
    tamanio = texto.length();   
    try{
    if (texto.isEmpty()) 
    {
        lblMensaje.setText("Nombre Vacio");
        lblMensaje.setForeground(Color.red);
        txt.requestFocus();
    }
    else if (tamanio > 0 && tamanio < 7) {
            lblMensaje.setText("Debe Ingresar 2 Nombres");
            lblMensaje.setForeground(Color.red);
            txt.requestFocus();
        } else if (tamanio > 7 && tamanio < 24) {
            lblMensaje.setText("Nombre Correcto");
            lblMensaje.setForeground(Color.WHITE);
        } else if (tamanio > 25) {
            lblMensaje.setText("Nombre Incorrecto");
            lblMensaje.setForeground(Color.red);
            txt.requestFocus();
        }
    }catch(Exception ex)
    {
        JOptionPane.showMessageDialog(null, ex);
    }
}

在每个jtexfield focusLost事件的主类中调用这些方法。

有人可以帮我找到解决方案吗?

1 个答案:

答案 0 :(得分:0)

您的代码会锁定,因为当一个字段失去焦点时,另一个字段获得焦点。您的FocusListener尝试将焦点重新放回第一个字段,但它不能,因为第二个侦听器正在尝试执行相同操作,将焦点重新放回其字段,从而导致连续调用两个验证方法,锁定你的计划。

添加两个System.out.println(...)来电来证明这一点:

public void validarCedula(JTextField txt, JLabel lblMensaje) {
    System.out.println("Dentro do validarCedula");  // ***** add this *****
    texto = txt.getText().trim();

    //...
}


public void validarNombre(JTextField txt, JLabel lblMensaje) {
   System.out.println("Dentro do validarNombre");  // ***** add this *****

   // ....
}

解决方案:使用我的评论中提到的InputVerifier。

测试我断言的代码:

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;

import javax.swing.*;

public class Foo3b extends JPanel {
   private String texto;
   private int tamanio;
   private JTextField cedulaField = new JTextField(10);
   private JTextField nombreField = new JTextField(10);
   private JLabel mensajeLabel = new JLabel(" ");

   public Foo3b() {
      JPanel panel = new JPanel();
      panel.add(new JLabel("Cedula:"));
      panel.add(cedulaField);
      panel.add(new JLabel("Nombre:"));
      panel.add(nombreField);

      JPanel mensajePanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
      mensajePanel.add(new JLabel("Mensaje:"));
      mensajePanel.add(mensajeLabel);

      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(panel);
      add(mensajePanel);

      cedulaField.addFocusListener(new FocusAdapter() {
         @Override
         public void focusLost(FocusEvent e) {
            validarCedula(cedulaField, mensajeLabel);
         }
      });

      nombreField.addFocusListener(new FocusAdapter() {
         @Override
         public void focusLost(FocusEvent e) {
            validarNombre(nombreField, mensajeLabel);
         }
      });
   }

   public void validarCedula(JTextField txt, JLabel lblMensaje) {
      System.out.println("Dentro do validarCedula");
      texto = txt.getText().trim();
      tamanio = texto.length();
      lblMensaje.setText("");        
      try{
      if (texto.isEmpty()) 
      {
          lblMensaje.setText("Cedula Vacio");
          lblMensaje.setForeground(Color.red);
          txt.requestFocus();
      }
      else if (tamanio > 0 && tamanio < 9) {
          lblMensaje.setText("Cedula Incorrecta");
          lblMensaje.setForeground(Color.red);
          txt.requestFocus();
      } else if (tamanio == 10) {
          lblMensaje.setText("Cedula Correcta");
          lblMensaje.setForeground(Color.white);
      } else if (tamanio > 11 && tamanio < 13) {
          lblMensaje.setText("RUC Incorrecto");
          lblMensaje.setForeground(Color.red);
          txt.requestFocus();
      } else if (tamanio == 13) {
          lblMensaje.setText("R.U.C Correcto");
          lblMensaje.setForeground(Color.WHITE);
      }
      }catch(Exception ex)
      {
          JOptionPane.showMessageDialog(null, ex);
      }
  }


  public void validarNombre(JTextField txt, JLabel lblMensaje) {
     System.out.println("Dentro do validarNombre");
      texto = txt.getText().trim();
      tamanio = texto.length();   
      try{
      if (texto.isEmpty()) 
      {
          lblMensaje.setText("Nombre Vacio");
          lblMensaje.setForeground(Color.red);
          txt.requestFocus();
      }
      else if (tamanio > 0 && tamanio < 7) {
              lblMensaje.setText("Debe Ingresar 2 Nombres");
              lblMensaje.setForeground(Color.red);
              txt.requestFocus();
          } else if (tamanio > 7 && tamanio < 24) {
              lblMensaje.setText("Nombre Correcto");
              lblMensaje.setForeground(Color.WHITE);
          } else if (tamanio > 25) {
              lblMensaje.setText("Nombre Incorrecto");
              lblMensaje.setForeground(Color.red);
              txt.requestFocus();
          }
      }catch(Exception ex)
      {
          JOptionPane.showMessageDialog(null, ex);
      }
  }

  private static void createAndShowGui() {
     Foo3b mainPanel = new Foo3b();

     JFrame frame = new JFrame("Foo3");
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
     frame.getContentPane().add(mainPanel);
     frame.pack();
     frame.setLocationByPlatform(true);
     frame.setVisible(true);
  }

  public static void main(String[] args) {
     SwingUtilities.invokeLater(new Runnable() {
        public void run() {
           createAndShowGui();
        }
     });
  }


}

返回:

Dentro do validarCedula
Dentro do validarNombre
Dentro do validarCedula
Dentro do validarNombre
Dentro do validarCedula
Dentro do validarNombre
Dentro do validarCedula
Dentro do validarNombre
Dentro do validarCedula
Dentro do validarNombre
Dentro do validarCedula
Dentro do validarNombre
Dentro do validarCedula
Dentro do validarNombre
.
.
. 
etc

更好的是:

import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.*;

public class Foo3b extends JPanel {
   public static final int CEDULA_TAMANIO_CORRECTO1 = 10;
   public static final int CEDULA_TAMANIO_CORRECTO2 = 13;
   public static final Color COLOR_INCORRECTO = Color.RED;
   public static final Color COLOR_CORRECTO = Color.BLUE;
   public static final int NOMBRE_TAMANIO_MIN = 8;
   public static final int NOMBRE_TAMANIO_MAX = 24;
   private JTextField cedulaField = new JTextField(10);
   private JTextField nombreField = new JTextField(10);
   private JLabel mensajeLabel = new JLabel(" ");

   public Foo3b() {
      JPanel panel = new JPanel();
      panel.add(new JLabel("Cedula:"));
      panel.add(cedulaField);
      panel.add(new JLabel("Nombre:"));
      panel.add(nombreField);

      JPanel mensajePanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
      mensajePanel.add(new JLabel("Mensaje:"));
      mensajePanel.add(mensajeLabel);

      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(panel);
      add(mensajePanel);

      cedulaField.setInputVerifier(new CedulaVerifier());

      nombreField.setInputVerifier(new NombreVerifier());
   }

   private class CedulaVerifier extends InputVerifier {
      private String texto = "";
      private int tamanio = 0;

      @Override
      public boolean verify(JComponent input) {
         texto = ((JTextField) input).getText().trim();
         tamanio = texto.length();

         if (texto.isEmpty()) {
            return false;
         } else if (tamanio != CEDULA_TAMANIO_CORRECTO1
               && tamanio != CEDULA_TAMANIO_CORRECTO2) {
            return false;
         }
         // default
         return true;
      }

      @Override
      public boolean shouldYieldFocus(JComponent input) {
         texto = ((JTextField) input).getText().trim();
         tamanio = texto.length();
         if (verify(input)) {
            mensajeLabel.setForeground(COLOR_CORRECTO);
            if (tamanio == CEDULA_TAMANIO_CORRECTO1) {
               mensajeLabel.setText("Cedula Correcta");
            } else if (tamanio == CEDULA_TAMANIO_CORRECTO2) {
               mensajeLabel.setText("R.U.C Correcto");
            }

            return true;
         } else {
            mensajeLabel.setForeground(COLOR_INCORRECTO);

            if (texto.isEmpty()) {
               mensajeLabel.setText("Cedula Vacio");
            } else if (tamanio > 0 && tamanio < 9) {
               mensajeLabel.setText("Cedula Incorrecta");
            } else if (tamanio > 11 && tamanio < 13) {
               mensajeLabel.setText("RUC Incorrecto");
            } else if (tamanio > 13) {
               mensajeLabel.setText("R.U.C INcorrecto");
            }
         }
         return false;
      }

   }

   private class NombreVerifier extends InputVerifier {
      private String texto = "";
      private int tamanio = 0;

      @Override
      public boolean verify(JComponent input) {
         texto = ((JTextField) input).getText().trim();
         tamanio = texto.length();

         if (texto.isEmpty()) {
            return false;
         } else if (tamanio < NOMBRE_TAMANIO_MIN
               || tamanio > NOMBRE_TAMANIO_MAX) {
            return false;
         }
         // default
         return true;

      }

      @Override
      public boolean shouldYieldFocus(JComponent input) {
         texto = ((JTextField) input).getText().trim();
         tamanio = texto.length();
         if (verify(input)) {
            mensajeLabel.setForeground(COLOR_CORRECTO);
            mensajeLabel.setText("Nombre Correcto");            
            return true;
         } else {
            mensajeLabel.setForeground(COLOR_INCORRECTO);
            if (texto.isEmpty()) {
               mensajeLabel.setText("Nombre Vacio");
            } else if (tamanio < NOMBRE_TAMANIO_MIN) {
               mensajeLabel.setText("Debe Ingresar 2 Nombres");
            } else if (tamanio > NOMBRE_TAMANIO_MAX) {
               mensajeLabel.setText("Nombre Incorrecto");
            }            
            return false;
         }
      }
   }

   private static void createAndShowGui() {
      Foo3b mainPanel = new Foo3b();

      JFrame frame = new JFrame("Foo3");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }

}