IP Field

weljo

Bekanntes Mitglied
Hi leute war auf der suche nach einem eingabefeld für ip adressen ... da ich nur ASIPAddressField finden konnte und das nicht kostenfrei ist hab ich mir einfach selber etwas geschrieben.
der code ist zwar noch etwas quick&dirty, es entspricht nicht der ip-eingabe von windows aber es funktioniert und könnte sicher für den ein oder anderen nützlich sein.


freu mich bereits auf feedback ... bin für alle verbesserungsvorschläge offen.

hf

Java:
import java.awt.Toolkit;

import javax.swing.JOptionPane;
import javax.swing.text.BadLocationException;
 
// (c) JohnVonWelebil
//IPv4
public class IP 
{
    public final static int ONE = 0, TWO =1, THREE =2, FOUR =3; //um direktes verändern zu verhinden
    private String one, two, three, four; //string damit ich auch nichts drin stehen haben kann... könnte natürlich auch im toString berücksichtigt werden
 
    public IP()
    {
        reset();
    }
    
    public IP(String ip) throws BadLocationException
    {
        if(!setIP(ip)) reset();
    }
    
    public static boolean isIp(String ip)
    {
        int counterOfDot = 0;
        for (int i = 0; i < ip.length(); i++) 
        {
            if(ip.charAt(i) == '.') counterOfDot++;
            if(!('0' <= ip.charAt(i) && ip.charAt(i) <= '9' || ip.charAt(i) == '.')) return false;
        }
        if(counterOfDot != 3) return false;
        
        int beginIndex = 0, endIndex = 0, num;
        String temp;
        int position = IP.ONE;
        while(endIndex >= 0 && position<=IP.FOUR) // überprüft ob die zahlen im bereich einer ip sind
        {
            endIndex = ip.indexOf('.', beginIndex);                
            if(endIndex < 0) endIndex = ip.length();
            
            temp = ip.substring(beginIndex, endIndex);
            if(temp.compareTo("") != 0) 
            {
                num = Integer.parseInt(temp);
                correctNumber(num, position);
            }
            beginIndex = endIndex + 1;            
            
            position++;
        }
        return true;
    }
    
    private static int correctNumber(int number,int position)
    {
    	 if(number<0 || number>255)
         {
             if(number<=0)number=0;
             else number = 255;   
     		Toolkit.getDefaultToolkit().beep();
         }
         if((number<=0 || number>=255) && position == FOUR)// kein broadcast und normales netzwerk
         {
             if(number<=0)number=1;
             else number = 254;
     		Toolkit.getDefaultToolkit().beep();
         } 
         if(number>223 && position == ONE) //wikipedia.org
         {
             number = 223;
     		Toolkit.getDefaultToolkit().beep();
         } 
         
         return number;
    }
    
    public boolean setIP(String ip) throws BadLocationException
    {
        if(!isIp(ip)) return false;
        
        int beginIndex = 0, endIndex = 0, position = IP.ONE;
        String temp;
        while(endIndex < ip.length()) 
        {
            endIndex = ip.indexOf('.', beginIndex);
            
            if(endIndex < 0) endIndex = ip.length();
            
            temp = ip.substring(beginIndex, endIndex);
            if(temp.compareTo("") == 0) resetElementAt(position);
            else setElementAt(Integer.parseInt(temp), position);
            
            beginIndex = endIndex + 1;      
            position++;
        }
        return true;
    }
    
    public boolean setElementAt(Integer number, int position)
    {
    	number = correctNumber(number, position);
 
        switch(position)
        {
            case ONE: one = number.toString();break;
            case TWO: two = number.toString();break;
            case THREE: three = number.toString();break;
            case FOUR: four = number.toString();break;
        }
        return true;
    }
    
    public void reset()
    {
        for(int i=0; i<4; i++)
        {
            resetElementAt(i);
        }
    }
    
    public void resetElementAt(int position)
    {
        switch(position)
        {
            case ONE: one = ""; break;
            case TWO: two = ""; break;
            case THREE: three = ""; break;
            case FOUR: four = ""; break;
        }
    }
 
    public String getElementAt(int position)
    {
        switch(position)
        {
            case ONE: return one;
            case TWO: return two;
            case THREE: return three;
            case FOUR: return four;
            default: return null;
        }
    }
    
    public Integer getNumberAt(int position)
    {
        switch(position)
        {
            case ONE: return Integer.parseInt(one);
            case TWO: return Integer.parseInt(two);
            case THREE: return Integer.parseInt(three);
            case FOUR: return Integer.parseInt(four);
            default: return null;
        }
    }
    
    public String getIP()
    {
        return toString();
    }
    
    public String toString()
    {
        return one+"."+two+"."+three+"."+four;
    }
}

Java:
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
 
// (c) JohnVonWelebil
public class IPDocument extends PlainDocument
{
    IP ip;
    private IPField field;    
    int cursor;
    AttributeSet a;
 
    public IPDocument(IPField field) throws BadLocationException
    {
        super();
        ip = new IP();
        this.field = field;
        reload();
    }
    
    public IPDocument(IPField field, String ipAddress) throws BadLocationException
    {
        super();
        ip = new IP();
        this.field = field;
        ip.setIP(ipAddress);
        reload();
    }
    
    
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
    {
        String text = field.getText();      
        this.cursor = offs;
        this.a = a;
        
        str.trim();
        
        for (int i = 0; i < str.length(); i++) 
        {
            if(!('0' <= str.charAt(i) && str.charAt(i) <= '9' || str.charAt(i) == '.')) return;
        }
        
        if(str.length() > 15) return;
        else if(IP.isIp(str))
        {
            ip.setIP(str);  
            reload();
        }
        else if(str.charAt(0)== '.' && str.length()==1)
        {
            field.setCaretPosition(text.indexOf(".", cursor)+1);
        }
        else if(Integer.parseInt(str)<=254)
        {
            int position = IP.ONE; 
            int search = text.indexOf(".",0);  
            while(cursor>search && search!=-1)
            {
                search = text.indexOf(".",search+1);
                position++;
            }
            
            String number = ip.getElementAt(position);
            int length = number.length();
            if(number == null) return;
            if (search == -1)search = text.length();
            number = number.substring(0, length-(search-cursor))+str+number.substring(length-(search-cursor), length);//zahl dazufügen
            if(!ip.setElementAt(Integer.parseInt(number), position)) return;
            
            if(number.length()==3 && position != IP.FOUR) cursor++;
            cursor++;
            reload();
        }
    }
 
    public void remove(int offs, int len) throws BadLocationException
    {
      String selected = field.getText().substring(offs, offs+len);
      String dots = "";
      for (int i = 0; i < selected.length(); i++) 
      {
          if(selected.charAt(i) == '.') dots+=".";
      }
      super.remove(offs, len);
      super.insertString(offs, dots, null);
      ip.setIP(field.getText());
    }
    
    private void reload() throws BadLocationException
    {
        super.remove(0, field.getText().length());
        super.insertString(0, ip.toString(), a);
        if(cursor > 15)cursor = 15;
        field.setCaretPosition(cursor);
    }
}

Java:
import javax.swing.JTextField;
import javax.swing.text.BadLocationException;
 
// (c) JohnVonWelebil
public class IPField extends JTextField
{   
    public IPField() throws BadLocationException
    {
        super(15);
        setDocument(new IPDocument(this));
        setHorizontalAlignment(JTextField.CENTER);
    }
    
    public IPField(String ip) throws BadLocationException
    {
        super(15);
        setDocument(new IPDocument(this, ip));
        setHorizontalAlignment(JTextField.CENTER);
    }
}
 
Zuletzt bearbeitet:
G

Gast2

Gast
Java:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: bad position: 16
	at javax.swing.text.JTextComponent.setCaretPosition(JTextComponent.java:1650)
	at IPDocument.reload(IPDocument.java:126)
	at IPDocument.insertString(IPDocument.java:72)
	at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:655)
	at javax.swing.text.JTextComponent.replaceSelection(JTextComponent.java:1351)
	at javax.swing.text.DefaultEditorKit$DefaultKeyTypedAction.actionPerformed(DefaultEditorKit.java:859)
	at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
	at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
	at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
	at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
	at java.awt.Component.processEvent(Component.java:6040)
	at java.awt.Container.processEvent(Container.java:2041)
	at java.awt.Component.dispatchEventImpl(Component.java:4630)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:704)
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:969)
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:841)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:668)
	at java.awt.Component.dispatchEventImpl(Component.java:4502)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Window.dispatchEventImpl(Window.java:2475)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Und das ist die Exception wenn man am Ende ankommt und noch was eingibt ;)...
Und eine Nachricht würde ich auch net ausgeben...
und rauslöschen dann man auch nichts mehr...
 

weljo

Bekanntes Mitglied
hmm mit was hast du kompiliert ... bekomm keine exception ... das mit der nachricht ausgeben hab ich auch bereits überdacht und werde statdessen eine exception machen auf die jeder reagieren kann wie er will ... und das mit dem rauslöschen funktioniert bei mir auch perfekt. Wenn du etwas markiertst und löscht funktioniert es bei mir so, dass vom markierten bereich nur noch die punkte über bleiben
 
G

Gast2

Gast
hmm mit was hast du kompiliert ... bekomm keine exception ... das mit der nachricht ausgeben hab ich auch bereits überdacht und werde statdessen eine exception machen auf die jeder reagieren kann wie er will ... und das mit dem rauslöschen funktioniert bei mir auch perfekt. Wenn du etwas markiertst und löscht funktioniert es bei mir so, dass vom markierten bereich nur noch die punkte über bleiben

ich hab das kompiliert was du gepostet hast...nach dem 15 zeichen kommt eine exception kannst ja oben inder fehlermeldung ablesen...
und zum löschen muss man was makieren mhm^^... also ich kann hier sachen löschen ohne dass ich etwas makieren muss...

warum eine exception schmeissen? wen man nichts mehr eingeben kann sollte ein beep kommen...
 

weljo

Bekanntes Mitglied
die exception darum, dass du mit deinem beep reagieren kannst und ich mit meinem fenster, so kann jeder selber entscheiden.

werden den geposteten code gleich nochmal probieren ... denn die version auf meinem pc funktioniert einwandfrei
 

weljo

Bekanntes Mitglied
hab eine zeile hinzugefügt und die exception ist nun weck ...

thx für das problem mit dem löschen ... werde mich gleich um das problem kümmern. hab bis jetzt nur mit markieren gelöscht
 
G

Gast2

Gast
hab eine zeile hinzugefügt und die exception ist nun weck ...

thx für das problem mit dem löschen ... werde mich gleich um das problem kümmern. hab bis jetzt nur mit markieren gelöscht

versuch lieber mal wenn du am ende bist noch paar zeichen einzugeben ob du da einen fehler bekommst....
wie gesagt ich würde keine exception schmeissen das ist ungewöhnlich wenn man ende des textes ist sollte keine fehlermeldung kommen...du kannst ein property event oder so feuern, aber ich finde es überflüßig, weil wenn du bei nem Textfeld eine länge eingrenzt und es geht nicht weiter dann ist es so und es kommt ein beep um den user zu sagen eingabe nicht gültig
 

weljo

Bekanntes Mitglied
hätte die exception auch nicht am schluss gemacht .. die war nur noch ein fehler der jetzt behoben ist ... hätte die exception anstatt meiner fehlermeldung out of range.(0-255) geworfen ...

der fehler mit dem löschen ist nun auch ausgemärzt und ich hab damit auch gleich den code um einiges verkürzt.
NEUE VERSION oben!!!!
 
Zuletzt bearbeitet:
G

Gast2

Gast
hätte die exception auch nicht am schluss gemacht .. die war nur noch ein fehler der jetzt behoben ist ... hätte die exception anstatt meiner fehlermeldung out of range.(0-255) geworfen ...

der fehler mit dem löschen ist nun auch ausgemärzt und ich hab damit auch gleich den code um einiges verkürzt.
NEUE VERSION oben!!!!

schau ich mir mal an...
ja wie gesagt üblich ist eigentlich falsche eingabe beep ^^...fertig

EDIT: Hab mit den Code mal angeschaut...
1. Find ich es häßlich das man dein Textfeld nur mit try catch initialisieren kann
2. Übergibst du dein Textfeld(GUI) deinem Model diese Beziehung solltest du vermeiden und dein Textfeld NICHT dem Document übergeben... Wie ich gesehen hab brauchst du das um die CaretPos zu verändern... Das kannst du mit dem argument offs in der insert String methode erreichen

EDIT2: Die Usability wird besser ;) ABER
1. man kann kein setText auf das textfield aufrufen... Du solltest noch einbauen wenn bei der insert Methode der strin größer als 1 ist eine regex einführen die die gültigkeit überprüft für ip adressen findest die mask im net.
2.wenn man bei der letzten zahl ist und noch etwas eingibt ändert er die letzte Zahl 254
3. warum kann die erste zahl nicht 255 werden?
4. wenn mein "." löscht könntest du noch ein caret nach vorne springen...
 
Zuletzt bearbeitet von einem Moderator:

weljo

Bekanntes Mitglied
hab alle änderungen durchgeführt, wobei Edit2.1.2 bereits vorhanden war .... (man kann auch gültige ip hineinkopieren)

hab nur ein problem mit dem curser setzen. habs mit super.insertString(cursor, "", null); und super.insertString(cursor, null, null);probiert funktioniert jedoch nicht.

achja und wegen dem ersten feld mit 223 --> IP-Adresse ? Wikipedia
 
Zuletzt bearbeitet:
G

Gast2

Gast
hineinkopieren und setText aufrufen ist für mich was anderes...

die insert methode sollte nur ienen super aufruf drin haben und das ganz am schluß... bis dahin musst du eben deinen offset zählen und da setzt er dir dann deinen cursor hin... su darfst keinen leeren strin glaub mitgeben sonst löscht er dir einen text wieder raus der da sein sollte quasi deinen punkt...
 

weljo

Bekanntes Mitglied
das mit hineinkopieren hast du falsch verstanden ... hab jetzt die methode setText für mein IPField geschrieben ... und das hineinkopieren ist extra ... meinte damit auch nicht das selbe gg.

zur insert methode ... wie der name bereits sagt ist sie für insert zuständig also ersetzt sie mir keinen text wenn ich nichts mitgebe sonder sollte eigentlich beim offs "keinen text" einfügen und den cursor dort hin setzen(deine beschreibung passt aus replace oder update).
in meinem fall mache ich es so, dass ich immer nur mein object IP veränder und danach reload aufrufe.
reload löscht zuerst alles aus dem dokument und fügt ip mit insert wieder hinzu(wobei offs beschreibt an welcher stelle des Dokuments hinzugefügt wird.). nach dem hinzufügen ist der curser an letzter stelle.
jetzt will ich noch den curser an die richtige stelle setzen und habs deshalb mit super.insertString(cursor, "", null) versucht.

hab super.insertString jetzt 2 mal aufgerufen 1x um den inhalt zu setzen und das 2. mal um den curser zu setzen, jedoch funktioniert das mit dem curser nochnicht ganz.

ps: ich glab bei den super.insertString methoden im vorigem post hast du mich auch falsch verstanden, da ich da beide probiert hab, jedoch unabhängig voneinander.

ich posten den aktuellen code nochmal oben, es besteht halt noch das problem dass nach jeder eingabe der cursor an letzter stelle steht

edit: kann meinen ersten post irgendwie nicht mehr ändern
 
Zuletzt bearbeitet:

weljo

Bekanntes Mitglied
Java:
import java.awt.Toolkit;
 
// (c) JohnVonWelebil
//IPv4
public class IP 
{
    public final static int ONE = 0, TWO =1, THREE =2, FOUR =3; //um direktes verändern zu verhinden
    private String one, two, three, four; //string damit ich auch nichts drin stehen haben kann... könnte natürlich auch im toString berücksichtigt werden
 
    public IP()
    {
        reset();
    }
    
    public IP(String ip)
    {
        if(!setIP(ip)) reset();
    }
    
    public static boolean isIp(String ip)
    {
        int counterOfDot = 0;
        for (int i = 0; i < ip.length(); i++) 
        {
            if(ip.charAt(i) == '.') counterOfDot++;
            if(!('0' <= ip.charAt(i) && ip.charAt(i) <= '9' || ip.charAt(i) == '.')) return false;
        }
        if(counterOfDot != 3) return false;
        
        int beginIndex = 0, endIndex = 0, num;
        String temp;
        int position = IP.ONE;
        while(endIndex >= 0 && position<=IP.FOUR) // überprüft ob die zahlen im bereich einer ip sind
        {
            endIndex = ip.indexOf('.', beginIndex);                
            if(endIndex < 0) endIndex = ip.length();
            
            temp = ip.substring(beginIndex, endIndex);
            if(temp.compareTo("") != 0) 
            {
                num = Integer.parseInt(temp);
                correctNumber(num, position);
            }
            beginIndex = endIndex + 1;            
            
            position++;
        }
        return true;
    }
    
    private static int correctNumber(int number,int position)
    {
    	 if(number<0 || number>255)
         {
             if(number<=0)number=0;
             else number = 255;   
     		Toolkit.getDefaultToolkit().beep();
         }
         if((number<=0 || number>=255) && position == FOUR)// kein broadcast und normales netzwerk
         {
             if(number<=0)number=1;
             else number = 254;
     		Toolkit.getDefaultToolkit().beep();
         } 
         if(number>223 && position == ONE) //wikipedia.org
         {
             number = 223;
     		Toolkit.getDefaultToolkit().beep();
         } 
         
         return number;
    }
    
    public boolean setIP(String ip)
    {
        if(!isIp(ip)) return false;
        
        int beginIndex = 0, endIndex = 0, position = IP.ONE;
        String temp;
        while(endIndex < ip.length()) 
        {
            endIndex = ip.indexOf('.', beginIndex);
            
            if(endIndex < 0) endIndex = ip.length();
            
            temp = ip.substring(beginIndex, endIndex);
            if(temp.compareTo("") == 0) resetElementAt(position);
            else setElementAt(Integer.parseInt(temp), position);
            
            beginIndex = endIndex + 1;      
            position++;
        }
        return true;
    }
    
    public boolean setElementAt(Integer number, int position)
    {
    	number = correctNumber(number, position);
 
        switch(position)
        {
            case ONE: one = number.toString();break;
            case TWO: two = number.toString();break;
            case THREE: three = number.toString();break;
            case FOUR: four = number.toString();break;
        }
        return true;
    }
    
    public void reset()
    {
        for(int i=0; i<4; i++)
        {
            resetElementAt(i);
        }
    }
    
    public void resetElementAt(int position)
    {
        switch(position)
        {
            case ONE: one = ""; break;
            case TWO: two = ""; break;
            case THREE: three = ""; break;
            case FOUR: four = ""; break;
        }
    }
 
    public String getElementAt(int position)
    {
        switch(position)
        {
            case ONE: return one;
            case TWO: return two;
            case THREE: return three;
            case FOUR: return four;
            default: return null;
        }
    }
    
    public Integer getNumberAt(int position)
    {
        switch(position)
        {
            case ONE: return Integer.parseInt(one);
            case TWO: return Integer.parseInt(two);
            case THREE: return Integer.parseInt(three);
            case FOUR: return Integer.parseInt(four);
            default: return null;
        }
    }
    
    public String getIP()
    {
        return toString();
    }
    
    public String toString()
    {
        return one+"."+two+"."+three+"."+four;
    }
}
Java:
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
 
// (c) JohnVonWelebil
public class IPDocument extends PlainDocument
{
    IP ip;
    int cursor=0;
    AttributeSet a;
 
    public IPDocument() throws BadLocationException
    {
        super();
        ip = new IP();
        reload();
    }
    
    public IPDocument(String ipAddress) throws BadLocationException
    {
        super();
        ip = new IP();
        ip.setIP(ipAddress);
        reload();
    }
    
    public void setIP(String ipAddress)
    {
    	ip.setIP(ipAddress);
    }
    
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
    {
    	String text = getText(0, getLength());
        this.cursor = offs;
        this.a = a;
        
        str.trim();
        
        for (int i = 0; i < str.length(); i++) 
        {
            if(!('0' <= str.charAt(i) && str.charAt(i) <= '9' || str.charAt(i) == '.')) return;
        }
        
        if(str.length() > 15) return;
        else if(IP.isIp(str))
        {
            ip.setIP(str);  
            reload();
        }
        else if(str.charAt(0)== '.' && str.length()==1) super.insertString((text.indexOf(".", offs)+1),"", null);
        else if(Integer.parseInt(str)<=254)
        {
            int position = IP.ONE; 
            int search = text.indexOf(".",0);  
            while(cursor>search && search!=-1)
            {
                search = text.indexOf(".",search+1);
                position++;
            }
            
            String number = ip.getElementAt(position);
            int length = number.length();
            if(length>=3)return;
            if(number == null) return;
            if (search == -1)search = text.length();
            number = number.substring(0, length-(search-cursor))+str+number.substring(length-(search-cursor), length);//zahl dazufügen
            if(!ip.setElementAt(Integer.parseInt(number), position)) return;
            
            if(number.length()==3 && position != IP.FOUR) cursor++;
            cursor++;
            reload();
        }
    }
 
    public void remove(int offs, int len) throws BadLocationException
    {
      String selected = getText(0, getLength()).substring(offs, offs+len);
      String dots = "";
      for (int i = 0; i < selected.length(); i++) 
      {
          if(selected.charAt(i) == '.') dots+=".";
      }
      super.remove(offs, len);
      super.insertString(offs, dots, null);
      ip.setIP(getText(0, getLength()));
    }
    
    private void reload() throws BadLocationException
    {
        super.remove(0, getLength());
        if(cursor > 15)cursor = 15;
        super.insertString(0, ip.toString(), a);
        super.insertString(cursor, null, a);
    }
}

Java:
import javax.swing.JTextField;
import javax.swing.text.BadLocationException;
 
// (c) JohnVonWelebil
public class IPField extends JTextField
{   
	IPDocument document;
    public IPField()
    {
        super(15);
        try
        {
        	setDocument(document = new IPDocument());
        }catch(BadLocationException e)
        {
        	e.printStackTrace();
        }
        setHorizontalAlignment(JTextField.CENTER);
    }
    
    public IPField(String ip)
    {
        super(15);
        try
        {
        	setDocument(document = new IPDocument(ip));
	    }catch(BadLocationException e)
	    {
	    	e.printStackTrace();
	    }
        setHorizontalAlignment(JTextField.CENTER);
    }
    
    public void setText(String ip)
    {
    	document.setIP(ip);
    }
}
 

Ähnliche Java Themen


Oben