2013-05-19 30 views
1

需要创建具有以下功能的JSpinner带显示格式,仅限数字和手动编辑的JSpinner

  • 范围应该是0到1000,增量为10。
  • 显示格式应该是4位数。 (例如:10 - > 0010)
  • 它必须允许用户手动输入值。
  • 它不应该允许数字以外的字符。
  • 它不应该允许输入超过3位数的值。

这是我目前实施:

spinnerUpDown.setModel(new SpinnerNumberModel(0,0,1000,10)); 
spinnerUpDown.setEditor(new JSpinner.NumberEditor(spinnerUpDown,"0000")); 
JFormattedTextField txt = ((JSpinner.NumberEditor) spinnerUpDown.getEditor()).getTextField(); 
((NumberFormatter) txt.getFormatter()).setAllowsInvalid(false); 

问题与实现,它不会允许用户手动输入一个值。

如果我删除行:

((NumberFormatter) txt.getFormatter()).setAllowsInvalid(false); 

这将让我手动输入值,但它允许同时输入字母。

任何建议来解决这个问题。 谢谢!

+2

+1 1做)不知道,确实必须有输入掩码和掩码格式化程序和一些验证程序,不知道该怎么做,2.)'该实现的问题是,它不允许用户手动输入值。 '将通过DocumentFilter与模式解决(多次在这里提出,顺便说一句,我在这里发布了几次JSpinner&DocumentFilter) – mKorbel

+1

我发现你对容许值的描述很容易混淆。你能否展示一些符合所有规则的“样本值”? –

+0

@Andrew Thompson它应该允许0到1000之间的所有值。当前实现的问题是,当用户选择所有当前值并输入新值时,它将只接受第一个数字。例如:如果当前值是25,那么它将显示为0025。在用户选择所有4位数并尝试输入10之后,它将显示0001并丢失选择。 –

回答

2

JSpinner通常使用JTextComponent作为其编辑器。您可以获得编辑并将其应用DocumentFilter

这将允许您过滤进入文档的文本。

检查这些,经常被引用,examples

JFormattedTextField是安装它自己的DocumentFilter。您可以通过提供自己的PlainDocument返回它自己的过滤器

import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import javax.swing.JFrame; 
import javax.swing.JSpinner; 
import javax.swing.SpinnerNumberModel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.text.AbstractDocument; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DocumentFilter; 
import javax.swing.text.JTextComponent; 
import javax.swing.text.PlainDocument; 

public class TestSpinner01 { 

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

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

       JSpinner spinnerUpDown = new JSpinner(); 
       spinnerUpDown.setModel(new SpinnerNumberModel(0, 0, 1000, 10)); 
       spinnerUpDown.setEditor(new JSpinner.NumberEditor(spinnerUpDown, "0000")); 
       System.out.println(spinnerUpDown.getEditor()); 


       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new GridBagLayout()); 
       frame.add(spinnerUpDown); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       PlainDocument doc = new PlainDocument() { 
        private TestFilter filter; 
        @Override 
        public DocumentFilter getDocumentFilter() { 
         if (filter == null) { 
          filter = new TestFilter(); 
         } 
         return filter; 
        } 

       }; 

       JTextComponent txt = ((JSpinner.DefaultEditor) spinnerUpDown.getEditor()).getTextField(); 
       txt.setDocument(doc); 
      } 
     }); 
    } 

    public class TestFilter extends DocumentFilter { 

     @Override 
     public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException { 
      System.out.println("remove"); 
      super.remove(fb, offset, length); 
     } 

     @Override 
     public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { 
      System.out.println("insert"); 
      super.insertString(fb, offset, string, attr); 
     } 

     @Override 
     public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { 
      System.out.println("Replace..."); 
      super.replace(fb, offset, length, text, attrs); 
     } 
    } 
} 

奇怪的是,你的示例代码的工作很适合我克服这一点,但实际上我的问题是与格式

+0

我只是尝试添加一个DocumentFilter:JFormattedTextField txt =((JSpinner.NumberEditor)spinnerUpDown.getEditor())。getTextField( );((AbstractDocument)txt.getDocument())。setDocumentFilter(new NumericAndLengthFilter(4))'但似乎从来没有使用过滤器。我用JTextField尝试相同的文档过滤器,它工作正常。 –

+0

谢谢你的代码示例。它完美的作品。唯一不同的是我直接设置DocumentFilter,并使用过滤器设置Document。我知道为什么它的行为如此。任何方式感谢您的答案。 –

0

注册KeyListener对于JFormattedTextField。在keyPressed()方法中,如果键入的键是非数字字符,则可以将KeyEvent的字符设置为空字符串。所以没有什么会出现在JFormattedTextField

+2

你应该永远不要我们的KeyListener来尝试和过滤文本组件 – MadProgrammer