2014-04-02 42 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项目。