2017-03-15 1 views
1

Mon code à barres inclut "1039723170303CC15-78" La raison pour laquelle j'ai utilisé DocumentFilter est que je souhaite limiter le nombre à 7 digit uniquement. Et le reste du nombre va automatiquement à 2nd textField.Numérisation de codes à barres à l'aide de DocumentFilter en Java

Mon code ne fonctionne que sur 7 chiffres seulement et tout le reste du numéro ne passe pas au champ de texte suivant. (C.-à-"1039723" go 1er textField et "70303CC15-78" go 2ème textFiled "1" manque dans la 2ème textFiled

Comment puis-je résoudre ce

lblTest = new JLabel("Testing : "); 
panel.add(lblText, "cell 0 1,alignx trailing"); 

txtTest = new JTextField(7); 

AbstractDocument d = (AbstractDocument) txtTest.getDocument(); 
d.setDocumentFilter(new DocumentFilter() { 
    @Override 
     public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException 
     { 
      if(fb.getDocument().getLength()+string.length()>7) 
      {      
       return;      
      } 
      fb.insertString(offset, string, attr);     
     } 


     @Override 
     public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException 
     {     
      fb.remove(offset, length); 
     } 


     @Override 
     public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs)throws BadLocationException 
     { 
       if(fb.getDocument().getLength()+text.length()>7) 
       { 
        txtTest.transferFocus(); 
        System.out.println("print.." +txtTest.getText()); 
        return; 
       } 
       fb.insertString(offset, text, attrs); 
     } 
}); 

copie papier de vente:..?

print Mo No.:1039723 
print Mo No.:1039723 
print Mo No.:1039723 
+0

Le point où vous décidez de transférer le focus, la valeur ('1' dans ce cas) est maintenant ignoré, mais il a déjà été lu.Vous devez utiliser la valeur 'text' transmise à la méthode' replace' et l'appliquer au champ suivant. – MadProgrammer

+0

Vous devez également savoir que si le champ a une valeur de '12345' et que j'ajoute' 56789' (en le collant pour exemple), votre code va rejeter le texte entier – MadProgrammer

Répondre

0

Le Le problème de base que vous avez, c'est que le text que vous vérifiez a été rejeté et n'a jamais été appliqué à quoi que ce soit

Par exa mple, si le texte entré est (en supposant un caractère à la fois) 123456789, alors 8 sera ignoré, car 9 sera envoyé à l'autre champ.

Ce que vous devez faire, est de définir manuellement le texte du champ suivant avec le texte que vous allez ignorer. Maintenant, votre courant a deux défauts fondamentaux.

  1. Il ne tient pas compte du fait que replace devrait supprimer tous les caractères sélectionnés
  2. ne prend pas en compte ce qui serait arrivé si le texte a été ajouté au champ
  3. ne prend pas en compte si le texte était inséré dans un autre décalage à la fin du champ

Cet exemple tente de répondre à toutes ces questions

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.text.AbstractDocument; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DocumentFilter; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame("Test"); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      JTextField field1 = new JTextField(7); 
      JTextField field2 = new JTextField(7); 
      ((AbstractDocument) field1.getDocument()).setDocumentFilter(new LimitDocumentFilter(field2)); 
      add(field1); 
      add(field2); 
     } 

    } 

    public class LimitDocumentFilter extends DocumentFilter { 

     private JTextField next; 

     public LimitDocumentFilter(JTextField next) { 
      this.next = next; 
     } 

     @Override 
     public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { 
      super.insertString(fb, offset, text, attr); 
      String textValue = fb.getDocument().getText(0, fb.getDocument().getLength()); 
      if (textValue.length() > 7) { 
       remove(fb, 7, fb.getDocument().getLength() - 7); 
       String overflow = textValue.substring(7); 
       next.requestFocusInWindow(); 
       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         next.setText(overflow); 
         next.setCaretPosition(overflow.length()); 
        } 
       }); 
      } 
     } 

     @Override 
     public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { 
      fb.remove(offset, length); 
      insertString(fb, offset, text, attrs); 
     } 
    } 

} 

Ce que cela a vraiment besoin est un modèle de délégué, où par la place de l'DocumentFilter changement d'orientation sur le terrain, il délègue cette responsabilité à un autre observateur, faisant passer le texte de trop-plein

Mise à jour

Ok, donc c'est une version mise à jour qui fournit trois façons que le texte peut être réglé:

  1. directement via setText
  2. Collé du presse-papiers
  3. coups clés injectés dans la mémoire tampon du clavier via Robot

Cela fournit le meilleur exemple possible de la façon dont un scanner de code-barres « pourrait » travailler

import java.awt.AWTException; 
import java.awt.Robot; 
import java.awt.Toolkit; 
import java.awt.datatransfer.Clipboard; 
import java.awt.datatransfer.StringSelection; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.FocusListener; 
import java.awt.event.KeyEvent; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.UIDefaults; 
import javax.swing.UIManager; 
import javax.swing.text.AbstractDocument; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DocumentFilter; 
import javax.swing.text.DocumentFilter.FilterBypass; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame("Test"); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      JTextField field1 = new JTextField(7); 
      JTextField field2 = new JTextField(7); 
      LimitDocumentFilter filter = new LimitDocumentFilter(); 
      filter.add(new LimitListener() { 
       @Override 
       public void limitReached(LimitDocumentFilter filter, String overflow) { 
        // This is to overcome the issue of MacOS autoselecting the 
        // text when it gets focus ... dumb 
        FocusListener[] listeners = field2.getFocusListeners(); 
        for (FocusListener listener : listeners) { 
         field2.removeFocusListener(listener); 
        } 
        field2.setText(overflow); 
        field2.requestFocusInWindow(); 
        field2.setCaretPosition(overflow.length()); 
        SwingUtilities.invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          for (FocusListener listener : listeners) { 
           field2.addFocusListener(listener); 
          } 
         } 
        }); 
       } 
      }); 
      ((AbstractDocument) field1.getDocument()).setDocumentFilter(filter); 
      add(field1); 
      add(field2); 

      JButton sim = new JButton("Simulate"); 
      sim.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        field1.setText(null); 
        field2.setText(null); 
        field1.requestFocusInWindow(); 
        SwingUtilities.invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          Thread t = new Thread(new Simulator()); 
          t.start(); 
         } 
        }); 
       } 
      }); 
      JButton paste = new JButton("Paste"); 
      paste.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        field1.setText(null); 
        field2.setText(null); 
        String text = "1234567abcdefg"; 
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 
        clipboard.setContents(new StringSelection(text), null); 
        field1.requestFocusInWindow(); 
        SwingUtilities.invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          field1.paste(); 
         } 
        }); 
       } 
      }); 
      JButton set = new JButton("Set"); 
      set.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        field1.setText(null); 
        field2.setText(null); 
        field1.setText("1234567abcdefghijklmnopqrstuvwxyz"); 
       } 
      }); 

      add(sim); 
      add(paste); 
      add(set); 
     } 

    } 

    public class Simulator implements Runnable { 

     @Override 
     public void run() { 
      try { 
       Robot bot = new Robot(); 
       type(KeyEvent.VK_1, bot); 
       type(KeyEvent.VK_2, bot); 
       type(KeyEvent.VK_3, bot); 
       type(KeyEvent.VK_4, bot); 
       type(KeyEvent.VK_5, bot); 
       type(KeyEvent.VK_6, bot); 
       type(KeyEvent.VK_7, bot); 

       type(KeyEvent.VK_A, bot); 
       type(KeyEvent.VK_B, bot); 
       type(KeyEvent.VK_C, bot); 
       type(KeyEvent.VK_D, bot); 
       type(KeyEvent.VK_E, bot); 
       type(KeyEvent.VK_F, bot); 
       type(KeyEvent.VK_G, bot); 
      } catch (AWTException ex) { 
       ex.printStackTrace(); 
      } 
     } 

     protected void type(int keyStoke, Robot bot) { 
      bot.keyPress(keyStoke); 
      bot.keyRelease(keyStoke); 
     } 

    } 

    public interface LimitListener { 

     public void limitReached(LimitDocumentFilter filter, String overflow); 
    } 

    public class LimitDocumentFilter extends DocumentFilter { 

     private List<LimitListener> listeners = new ArrayList<>(25); 

     public LimitDocumentFilter() { 
     } 

     public void add(LimitListener listener) { 
      listeners.add(listener); 
     } 

     public void remove(LimitListener listener) { 
      listeners.remove(listener); 
     } 

     protected void limitReached(String overflow) { 
      for (LimitListener listener : listeners) { 
       listener.limitReached(this, overflow); 
      } 
     } 

     @Override 
     public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { 
      super.insertString(fb, offset, text, attr); 
      String textValue = fb.getDocument().getText(0, fb.getDocument().getLength()); 
      if (textValue.length() > 7) { 
       remove(fb, 7, fb.getDocument().getLength() - 7); 
       String overflow = textValue.substring(7); 
       limitReached(overflow); 
      } 
     } 

     @Override 
     public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { 
      fb.remove(offset, length); 
      insertString(fb, offset, text, attrs); 
     } 
    } 

} 
+0

..... "String overflow = textValue.substring (7);" 'a eu une erreur de débordement, donc je dois le faire comme' "final String overflow = textValue.substring (7); "' – Augustine

+0

Toujours en utilisant Java 6? C'est là qu'un modèle de délégué aiderait;) – MadProgrammer

+0

@MadProgrammer ... il ne limite que les 7 premiers chiffres, après 7 chiffres, tout le nombre saute aléatoirement dans le champ de texte suivant .... = ( – Augustine