2014-04-02 46 views
0

我正在研究一個Java應用程序,並遇到了一個我自己無法解決的問題。強制JTextField字符串值,而DocumentFilter只允許數字

我已經設置DocumentFilterJTextField只允許數字輸入,但是,默認值是文本。我有一個按鈕,將JTextField重置爲默認值,並且由於DocumentFilter而不能正常工作。

我該如何克服這個問題?

感謝

+0

什麼是文本?它不包含數字嗎?文本的目的是什麼? – MadProgrammer

+0

這是一個字符文本。正如我所說這是默認值。 –

+0

@Yury Lankovskiy可能是一個有趣的問題,您的要求讓我感到自豪,但這裏將基於您的SSCCE/MCVE/MCTRE,短小的,可運行的,可編譯的局部變量值 – mKorbel

回答

2

一個字段,用戶只能輸入數字數據,但也需要顯示非數字值是矛盾的。

文本通過Document提供給字段,不區分內容的生成方式,無論是由用戶還是以編程方式生成。

如果你想在現場展示了「提示」,你可以可以看看PromptSupportSwingLabs SwingX Library

對於實例

Prompt fields

當領域有焦點時,「提示」將被隱藏,但是您可以控制它,直到用戶鍵入內容或獲得焦點時突出顯示。

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import org.jdesktop.swingx.prompt.BuddySupport; 
import org.jdesktop.swingx.prompt.PromptSupport; 

public class PromptSupportTest { 

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

    public PromptSupportTest() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      JTextField firstName = new JTextField(10); 
      PromptSupport.setPrompt("First Name", firstName); 
      PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, firstName); 

      JTextField lastName = new JTextField(10); 
      PromptSupport.setPrompt("Last Name", lastName); 
      PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, lastName); 

      JTextField picture = new JTextField(10); 
      PromptSupport.setPrompt("Picture", picture); 
      PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, picture); 

      JButton browse = new JButton("..."); 
      browse.setMargin(new Insets(0, 0, 0, 0)); 
      browse.setContentAreaFilled(false); 
      browse.setFocusPainted(false); 
      browse.setFocusable(false); 
      browse.setOpaque(false); 
      // Add action listener to brose button to show JFileChooser... 

      BuddySupport.addRight(browse, picture); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      gbc.weightx = 1; 

      add(firstName, gbc); 
      add(lastName, gbc); 
      add(picture, gbc); 

      gbc.anchor = GridBagConstraints.CENTER; 
      add(new JButton("Ok"), gbc); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

} 

我也加入BuddySupport其中一個例子是一樣的API,它可以讓你的「好友」與文本組件另一個組件的一部分。在這裏我已經完成了經典的「文件瀏覽器」組合,但我一直在「搜索」這樣的字段......

4

做一兩件事:

店默認的文檔的一些地方

final JTextField textField = new JTextField(); 
final Document defaultDocument=textField.getDocument(); 

在按鈕點擊第一個設置文件回默認爲禁用文本框驗證,然後設置默認文本

btn.addActionListener(new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     textField.setDocument(defaultDocument); 
     textField.setText("hi"); 
    } 
}); 

添加文件過濾器再次回到文本框中的焦點以驗證用戶輸入。

請看看How to implement in Java (JTextField class) to allow entering only digits?


- 編輯 -

您可以通過text field加入focus listener做到這一點。

如果文本字段中的值爲空,則將默認值設置爲提示。沒有必要按鈕點擊。

這裏是代碼:

final JTextField textField = new JTextField("First Name"); 

    final Document defaultDocument = textField.getDocument(); 

    final PlainDocument doc = new PlainDocument(); 
    doc.setDocumentFilter(new DocumentFilter() { 
     @Override 
     public void insertString(FilterBypass fb, int off, String str, AttributeSet attr) 
       throws BadLocationException { 
      fb.insertString(off, str.replaceAll("\\D++", ""), attr); // remove 
                    // non-digits 
     } 

     @Override 
     public void replace(FilterBypass fb, int off, int len, String str, 
       AttributeSet attr) throws BadLocationException { 
      fb.replace(off, len, str.replaceAll("\\D++", ""), attr); // remove 
                    // non-digits 
     } 
    }); 

    textField.addFocusListener(new FocusListener() { 

     @Override 
     public void focusLost(FocusEvent e) { 
      System.out.println("focus lost"); 
      if(textField.getText() == null || textField.getText().trim().length()==0){ 
       textField.setDocument(defaultDocument); 
       textField.setText("First Name"); 
      } 
     } 

     @Override 
     public void focusGained(FocusEvent e) { 
      System.out.println("focus gained"); 
      textField.setDocument(doc); 
     } 
    }); 
+0

我已更新我的文章。請看一看。 – Braj

+0

是的,OP可以在運行時做到這一點。 OP只需要兩個文件過濾器,一個用於默認,另一個用於數字。 – Braj

+0

謝謝,但我使用PromptSupport來代替,這很容易。 –

2

你可以使用類似PromptSupport

或者,也許Text Prompt類。它與PromptSupport類似,但可以在常規的JTextField上使用,因此您不需要整個SwingX項目。