/**
* IP地址文本框.<br/>
* 可隨意複製粘貼
*
* @author [email protected] 2014-8-6
*/
public class IPAddressArea extends JTextField
{
private static final long serialVersionUID = -1738690267989023760L;
/**
* 字符的正則表達式
*/
public static final String AbsRegx = "[0-9a-zA-Z]+";
/**
* IP地址的正則表達式
*/
public final static String IPREGEX = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
public inal Border emptyBorder = BorderFactory.createEmptyBorder();
{
private static final long serialVersionUID = 2508417082430336855L;
@Override
public void insertString(int offs, final String str, final AttributeSet a) throws BadLocationException
{
if (offs > 15)
{
Toolkit.getDefaultToolkit().beep();
return;
}
String text = IPAddressArea.this.getText();
// 原始內容爲空則直接輸入,前提條件由setText保證
if (text.isEmpty())
{
super.insertString(offs, str, a);
return;
}
String[] ips = text.split("\\.", -1);
if (str.length() == 1)
{
// 允許輸入 , . 用於左移位和右移位
if (str.charAt(0) == '.')
{
if (offs >= text.length())
{
// 右移到末尾後跳到首位
IPAddressArea.this.setCaretPosition(0);
}
else
{
IPAddressArea.this.setCaretPosition(offs + 1);
}
return;
}
if (str.charAt(0) == ',')
{
if (offs < 1)
{
//右移位到首位後跳到末尾
IPAddressArea.this.setCaretPosition(text.length());
}
else
{
IPAddressArea.this.setCaretPosition(offs - 1);
}
return;
}
if (!str.matches(DigitRegx))
{
// 不允許輸入非數字字符
Toolkit.getDefaultToolkit().beep();
return;
}
// 分四段進行處理
if (offs <= ips[0].length())
{
this.insertIPSegment(offs, str, a, ips[0], 0);
return;
}
else if (offs <= (ips[0].length() + 1 + ips[1].length()))
{
this.insertIPSegment(offs, str, a, ips[1], ips[0].length() + 1);
return;
}
else if (offs <= (ips[0].length() + 1 + ips[1].length() + 1 + ips[2].length()))
{
this.insertIPSegment(offs, str, a, ips[2], ips[0].length() + 1 + ips[1].length() + 1);
return;
}
else if (offs <= (ips[0].length() + 1 + ips[1].length() + 1 + ips[2].length() + 1 + ips[3].length()))
{
this.insertIPSegment(offs, str, a, ips[3],
ips[0].length() + 1 + ips[1].length() + 1 + ips[2].length() + 1);
return;
}
else
{
Toolkit.getDefaultToolkit().beep();
return;
}
}
// 一個字符一個字符輸入以簡化處理
for (int i = 0, len = str.length(); i < len; i++)
{
if (str.charAt(i) == '.')
{
continue;
}
this.insertString(offs + i, str.charAt(i) + "", a);
}
}
private void insertIPSegment(int offs, final String str, final AttributeSet a, String ipSeg, int startPos)
throws BadLocationException
{
// 針對IP地址的每一段的四個可能的位置進行處理
if (offs - startPos == 0)
{
String s1 = str + ipSeg;
if (Integer.parseInt(s1) > 255)
{
String s2 = str + ipSeg.substring(1);
if (Integer.parseInt(s2) <= 255)
{
if (s2.length() > 3)
{
IPAddressArea.this.setCaretPosition(IPAddressArea.this.getCaretPosition() + 1);
this.insertString(offs + 1, str, a);
}
else
{
super.remove(0 + startPos, 1);
super.insertString(0 + startPos, str, a);
}
return;
}
Toolkit.getDefaultToolkit().beep();
return;
}
if (s1.length() > 3)
{
IPAddressArea.this.setCaretPosition(IPAddressArea.this.getCaretPosition() + 1);
this.insertString(offs + 1, str, a);
}
else
{
super.insertString(offs, str, a);
}
}
else if (offs - startPos == 1)
{
String s1 = ipSeg.charAt(0) + str + ipSeg.substring(1);
if (Integer.parseInt(s1) > 255)
{
String s2 = ipSeg.charAt(0) + str + ipSeg.substring(2);
if (Integer.parseInt(s2) <= 255)
{
if (s2.length() > 3)
{
IPAddressArea.this.setCaretPosition(IPAddressArea.this.getCaretPosition() + 1);
this.insertString(offs + 1, str, a);
}
else
{
super.remove(1 + startPos, 1);
super.insertString(1 + startPos, str, a);
}
return;
}
Toolkit.getDefaultToolkit().beep();
return;
}
if (s1.length() > 3)
{
IPAddressArea.this.setCaretPosition(IPAddressArea.this.getCaretPosition() + 1);
this.insertString(offs + 1, str, a);
}
else
{
super.insertString(offs, str, a);
}
}
else if (offs - startPos == 2)
{
String s1 = ipSeg.charAt(0) + "" + ipSeg.charAt(1) + str + ipSeg.substring(2);
if (Integer.parseInt(s1) > 255)
{
String s2 = ipSeg.charAt(0) + "" + ipSeg.charAt(1) + str;
if (Integer.parseInt(s2) <= 255)
{
if (s2.length() > 3)
{
IPAddressArea.this.setCaretPosition(IPAddressArea.this.getCaretPosition() + 1);
this.insertString(offs + 1, str, a);
}
else
{
super.remove(2 + startPos, 1);
super.insertString(2 + startPos, str, a);
}
return;
}
Toolkit.getDefaultToolkit().beep();
return;
}
if (s1.length() > 3)
{
IPAddressArea.this.setCaretPosition(IPAddressArea.this.getCaretPosition() + 1);
this.insertString(offs + 1, str, a);
}
else
{
super.insertString(offs, str, a);
}
}
else
{
if (offs >= IPAddressArea.this.getText().length())
{
Toolkit.getDefaultToolkit().beep();
return;
}
IPAddressArea.this.setCaretPosition(IPAddressArea.this.getCaretPosition() + 1);
this.insertString(offs + 1, str, a);
}
}
@Override
public void remove(final int offs, final int len) throws BadLocationException
{
String text = IPAddressArea.this.getText();
// (全選刪除的情況)無論怎麼刪除都保留 ...
if (text.length() < 3)
{
Toolkit.getDefaultToolkit().beep();
return;
}
if (len == 1)
{
// 處理異常
if (text.split("\\.", -1).length > 4)
{
super.remove(offs, len);
return;
}
// 刪除單個字符,保留 .
if (text.charAt(offs) != '.')
{
super.remove(offs, len);
return;
}
if (offs >= 0)
{
// 按退格鍵時光標左移一位
IPAddressArea.this.setCaretPosition(offs);
return;
}
Toolkit.getDefaultToolkit().beep();
return;
}
// 選中多個字符進行刪除
String substr = text.substring(offs, offs + len);
// 按照 . 分割,一段一段進行刪除,保留 .
String[] substrs = substr.split("\\.", -1);
int length = len;
for (int i = substrs.length - 1; i >= 0; i--)
{
length = length - substrs[i].length();
super.remove(offs + length, substrs[i].length());
// 保留小數點
length--;
}
IPAddressArea.this.setCaretPosition(offs);
}
}
/**
* 判斷是否爲合法IP
*
* @return the ip
*/
public final static boolean isIPAddress(final String ipAddress)
{
// String ip = "((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)";
// Pattern pattern = Pattern.compile(ip);
// Matcher matcher = pattern.matcher(ipAddress);
// return matcher.matches();
return ipAddress.matches(IPREGEX);
}
public final boolean isIPAddress()
{
return isIPAddress(this.getText());
}
public static void main(final String[] args)
{
javax.swing.JFrame frame = new javax.swing.JFrame("JIPAddressField Demo");
frame.setSize(300, 100);
frame.setLocation(600, 400);
frame.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
frame.getContentPane().setLayout(new java.awt.FlowLayout());
IPAddressArea test = new IPAddressArea();
test.setText("192.168.0.1");
// IPAddressArea test2 = new IPAddressArea();
// IPAddressArea test3 = new IPAddressArea();
frame.getContentPane().add(test);
// frame.getContentPane().add(test2);
// frame.getContentPane().add(test3);
frame.setVisible(true);
}
public JPopupMenu popupMenu = new JPopupMenu();
private final Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
/**
* 使用默認的參數進行構造行數 構造方法
*/
public IPAddressArea()
{
this.enableInputMethods(false);
this.setText("...");
this.setDocument(new IPAddressDocument());
// this.setBounds(0, 0, 200, 50);
int width = 150, height = 25;
this.setSize(width, height);
Dimension size = new Dimension(width, height);
this.setMinimumSize(size);
this.setPreferredSize(size);
this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
this.initTextPopupMenu();
}
/**
*
* 獲得IP地址,僅限與內部使用.<br/>
* 組裝成一串數據
*
*/
public String getIpAddress()
{
String ip = this.getText();
if (IPAddressArea.isIPAddress(ip))
{
String[] ips = ip.split("\\.", -1);
ip = "";
for (String s : ips)
{
ip = "." + s;
}
return ip.substring(1);
}
return "";
}
private void initTextPopupMenu()
{
this.setBorder(lineBorder);
JMenuItem copyMenuItem = new JMenuItem("複製(C)");
copyMenuItem.setMnemonic(KeyEvent.VK_C);
copyMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(final ActionEvent e)
{
StringSelection ssel = new StringSelection(IPAddressArea.this.getText());
systemClipboard.setContents(ssel, ssel);
}
});
JMenuItem pasteMenuItem = new JMenuItem("粘貼(V)");
pasteMenuItem.setMnemonic(KeyEvent.VK_V);
pasteMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(final ActionEvent e)
{
String str = null;
try
{
str = (String) (systemClipboard.getContents(this).getTransferData(DataFlavor.stringFlavor));
}
catch (Exception e1)
{
e1.printStackTrace();
}
IPAddressArea.this.setText(str);
}
});
this.popupMenu.add(copyMenuItem);
this.popupMenu.add(pasteMenuItem);
this.popupMenu.setBorder(lineBorder);
this.popupMenu.setOpaque(true);
initMouseInputListener(this, this.popupMenu, false);
this.addKeyListener(new KeyAdapter()
{
@Override
public void keyReleased(final KeyEvent keyevent)
{
if (keyevent.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)
{
Rectangle rec = null;
try
{
rec = IPAddressArea.this.modelToView(IPAddressArea.this.getCaretPosition());
}
catch (BadLocationException e)
{
e.printStackTrace();
}
IPAddressArea.this.popupMenu.show(IPAddressArea.this, rec.x, IPAddressArea.this.getHeight() / 2);
}
}
});
}
/**
*
* 設置IP地址.
*
* @see javax.swing.text.JTextComponent#setText(java.lang.String)
*/
@Override
public void setText(final String ip)
{
if (IPAddressArea.isIPAddress(ip))
{
super.setText(ip);
}
else
{
super.setText("0.0.0.0");
}
}
}