强制JTextField为字符串值,而DocumentFilter仅允许数字

我正在研究一个Java应用程序并遇到了一个我自己似乎无法解决的问题。

我在JTextField上设置了一个DocumentFilter ,只允许数字输入,但默认值是文本。 我有一个按钮将JTextField重置为默认值,并且由于DocumentFilter而无法正常工作。

我怎样才能克服这个问题?

谢谢

用户只能输入数字数据,但也需要显示非数字值的字段是矛盾的。

文本通过Document提供给字段,用户或编程方式无法区分内容的生成方式。

如果您在该字段中尝试显示“提示”,则可以查看SwingLabs SwingX Library中的 PromptSupport

例如

提示字段

当字段具有焦点时,“提示”将被隐藏,但您可以控制它,使其显示直到用户键入内容或在获得焦点时突出显示。

 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的一部分,它允许您与文本组件“伙伴”另一个组件。 在这里,我已经完成了经典的“文件浏览器”组合,但我一直在“搜索”这样的样式字段……

做一件事:

将默认文档存储在哪里

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

在按钮上单击首先将文档设置回默认值以禁用文本字段上的validation,然后设置默认文本

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

在文本域中的焦点上再次添加文档filter以validation用户输入。

请查看如何在Java中实现(JTextField类)以仅允许输入数字? 。


– 编辑 –

您可以通过在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); } }); 

你可以使用像PromptSupport这样的东西

或者也许是Text Prompt类。 它类似于PromptSupport,但可以在常规JTextField上使用,因此您不需要整个SwingX项目。

Interesting Posts