JSpinner para Números Naturais (>=0)

Preciso que o JSpinner aceite qualquer Número >=0, ou seja Números Naturais, mas não vejo como fazer isso com ele.

Com o código abaixo ele aceita apenas Números Inteiros:

JSpinner spinner = new JSpinner(new SpinnerNumberModel()); //O SpinnerNumberModel criado sem argumentos não define um valor máximo nem um mínimo, eu preciso definir só o mínimo e deixar o máximo infinito
((DefaultFormatter) ((JSpinner.NumberEditor) spinner.getEditor()).getTextField().getFormatter()).setAllowsInvalid(false); //impede que se digite qualquer caracter não-numérico no spinner

Com o código abaixo, eu consigo definir que o valor Mínimo será Zero, mas sou forçado a definir um valor máximo (eu quero que o valor máximo seja infinito):

JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 9999, 1)); //O SpinnerNumberModel criado com estes argumentos define um valor máximo de 9999, eu preciso definir só o mínimo (que é Zero) e deixar o máximo infinito
((DefaultFormatter) ((JSpinner.NumberEditor) spinner.getEditor()).getTextField().getFormatter()).setAllowsInvalid(false); //impede que se digite qualquer caracter não-numérico no spinner

Tem como fazer um JSpinner que vá de Zero a Infinito (e sem aceitar Números de Ponto-Flutuante)?

Utilize as duas linhas abaixo.

new JSpinner(new SpinnerNumberModel(0, 0, Double.MAX_VALUE, 1)); //alterar o valor 9999 para Double.MAX_VALUE
this.spinner.setEditor(new JSpinner.NumberEditor(this.spinner, "#")); //Acrescentar essa linha

Obs.: todo número natural é um número inteiro, logo, creio que o adequado seria números reais.
Quanto ao valor infinito, use Double.POSITIVE_INFINITY.

1 curtida

Não quero permitir números de ponto flutuante (como Double), quero permitir Todos os Números Naturais e somente eles: [quote=“Douglas-Silva, post:1, topic:351012”]
Tem como fazer um JSpinner que vá de Zero a Infinito (e sem aceitar Números de Ponto-Flutuante)?
[/quote]

Eu encontrei outro Construtor que se propõe a permitir o que eu quero:

public SpinnerNumberModel(Number value,
                          Comparable minimum,
                          Comparable maximum,
                          Number stepSize)

O javadoc diz (negrito onde fala sobre como deixar em aberto os limites min/max):

Constructs a SpinnerModel that represents a closed sequence of numbers from minimum to maximum. The nextValue and previousValue methods compute elements of the sequence by adding or subtracting stepSize respectively. All of the parameters must be mutually Comparable, value and stepSize must be instances of Integer Long, Float, or Double.
The minimum and maximum parameters can be null to indicate that the range doesn’t have an upper or lower bound. If value or stepSize is null, or if both minimum and maximum are specified and minimum > maximum then an IllegalArgumentException is thrown. Similarly if (minimum <= value <= maximum) is false, an IllegalArgumentException is thrown.

Usando esse Construtor da forma abaixo o spinner vai de Zero à Long.MAX_VALUE (eu esperava que fosse até infinito, por passar null como limite máximo, mas por usar Long nos outros parâmetros ele assumiu o limite do Long mesmo):

spinner = new JSpinner(new SpinnerNumberModel(Long.valueOf(0), Long.valueOf(0), null, Long.valueOf(1)));

Esse código me serviu bem porque vou colocar o retorno do spinner em uma variável long.


Já o código sugerido pelo @campelo.m cria um JSpinner que aceita números de ponto flutuante maiores ou iguais a zero, e, parece aceitar números infinitos embora o comportamento seja estranho:

Veja no gif acima que quando se usa os botões de incremento/decremento funciona normal, mas quando eu começo a teclar “9” consecutivas vezes (eu teclei apenas “9”, nem “0” nem “1”) o valor acaba mudando sozinho após uma determinada quantidade de “Noves” (imagino que seja por causa de limitações do Double).

O código dele ficou assim:

spinner = new JSpinner(new SpinnerNumberModel(0, 0, Double.MAX_VALUE, 1));
this.spinner.setEditor(new JSpinner.NumberEditor(this.spinner, "#")); //O que é que essa linha faz?

@addller usar Double.POSITIVE_INFINITY no lugar de Double.MAX_VALUE sem a 2ª linha pareceu dar um resultado semelhante.


Conclusão Atual:

resolvi o meu problema com o código spinner = new JSpinner(new SpinnerNumberModel(Long.valueOf(0), Long.valueOf(0), null, Long.valueOf(1)));, mas esse código não resolve o problema da pergunta que na verdade é “como criar um JSpinner que aceita todos os Numeros Naturais e somente os Números Naturais?” (Não deve ter limite máximo [indo de zero a infinito], e não deve aceitar números com ponto-flutuante nem números negativos).

Nestas condições o maior valor que pode ser representado é Long.MAX_VALUE.
Nenhuma linguagem de programação vai representar o infinito numericamente, apenas simbolicamente, como na matemática, logo, cabe apenas se contentar com o possível.
Você vai ver relatos de números primos, portanto inteiros, com 20 e tantos milhões de casas decimais, mas isto não é para um spinner, nem para as classes numéricas em questão.

Tal representação é apenas simbólica, pois você deve saber que há vários infinitos.
Ex.: números fracionários de 0 a 1, não podem ser representados naturalmente, pois embora o intervalo seja teoricamente pequeno, há infinitas frações.

A variável long tem um limite, se não observar vai ter que corrigir a codificação futuramente.

Se o que vc procura é isto, saiba que vai travar o spinner, uma vez que ele trabalha com intervalos finitos respeitando os limites mínimos e máximos impostos.
Por fim, não será uma boa ideia forçar este objeto conforme o pretendido.

A codificação a seguir bloqueia a entrada de valores que não sejam “inteiros” utilizando apenas o teclado.

JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, Long.MAX_VALUE, 5));
        ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField().addKeyListener(new java.awt.event.KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent evt) {
                if (("" + evt.getKeyChar()).matches("\\D")) {
                    evt.consume();
                }
            }
        });

Obs.: terá que fazer implementações para impor um limite na entrada de valores e outra para impedir que o usuário cole um valor incompatível com dígitos, caso contrário o spinner pode se comportar como um campo de texto comum, perdendo sua funcionalidade e objetivo.
Quanto a isto de ao infinito e além as utilidades são outras, funcionais e de aplicação específica.
Té+.