2011-12-26 11 views
5

Estoy intentando configurar un JSpinner utilizando un SpinnerNumberModel con valor = 0.0005, min = 0.0, max = 1.0 y tamaño de paso = 0.0005. Sin embargo, cuando creo un spinner con estos parámetros observo un comportamiento muy extraño. En lugar de comenzar en 0.0005 y aumentar en 0.0005 con cada clic de la flecha hacia arriba, el valor parece mantenerse en 0.Odd SpinnerNumberComportamiento del modelo en Java

Para asegurarse de que esto no sea solo un problema de formateo, imprimí el valor de la flecha después cada evento de cambio. Sin duda, por cada clic de la flecha hacia arriba, la consola muestra el valor como 0 y luego como 0.0005, independientemente de cuántas veces se haya hecho clic en la ruleta.

A continuación se muestra el código que he usado para probar esto, que incluye un girador con valores ligeramente diferentes que funcionan bien para fines de comparación.

import javax.swing.*; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import java.awt.*; 

public class Main { 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setSize(200, 80); 
     JPanel panel = new JPanel(); 
     panel.setLayout(new BorderLayout()); 
     final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0.0005, 0.0, 1.0, 0.0005)); 
     final JSpinner spinner2 = new JSpinner(new SpinnerNumberModel(0.05, 0.0, 1.0, 0.05)); 
     panel.add(spinner1, BorderLayout.NORTH); 
     panel.add(spinner2, BorderLayout.SOUTH); 
     frame.add(panel); 
     spinner1.addChangeListener(new ChangeListener() { 
      public void stateChanged(ChangeEvent e) { 
       System.out.println("spinner1: " + ((Number) spinner1.getValue()).doubleValue()); 
      } 
     }); 
     spinner2.addChangeListener(new ChangeListener() { 
      public void stateChanged(ChangeEvent e) { 
       System.out.println("spinner2: " + ((Number) spinner2.getValue()).doubleValue()); 
      } 
     }); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} 

¿Alguien puede explicarme por qué spinner2 funciona como se esperaba, pero spinner1 no?

Gracias.

Editar: Gracias a Peter por señalar que el formateo del campo de texto del control numérico realmente tiene un efecto sobre el valor almacenado. Para que la primera centrifugadora funcione como estaba previsto, agregué la línea: spinner1.setEditor(new JSpinner.NumberEditor(spinner1, "0.0000"));.

+0

Gracias por la entrada. El proyecto real donde encontré el problema por primera vez es mucho más complejo que esto. El código que publiqué aquí es un ejemplo muy escueto que demuestra el problema. –

+0

Muy bien, he editado el ejemplo para incluir un JPanel para contener los dos rotuladores. Desafortunadamente, todavía obtengo los mismos resultados flojos para el primer girador. –

+0

He usado un JPanel y el problema aún persiste. Intenté usar (0.001, 0.0001) como modelo de JSpinner (valor, paso) y (0.0001, 0.001) también. Ninguno de los dos funciona Pero (0.001, 0.001) funciona en su lugar. ¿Esto implica un problema de presentación de precisión de JSpinner? – xorange

Respuesta

9

el problema es esto en el JFormattedTextField utilizado por el spinner. En ese editor se puede encontrar:

public void commitEdit() throws ParseException { 
    AbstractFormatter format = getFormatter(); 

    if (format != null) { 
     setValue(format.stringToValue(getText()), false, true); 
    } 
} 

la pantalla spinner 0,0005 como 0.0, si se incrementará primera puso 0.0 en su modelo y luego se incrementa a 0,0005, su evento realmente captura, pero su campo de texto sólo ve 0,0

por lo que la solución será cambiar el formato del campo de texto spinner.

puede overide el editor

final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0.0005, 0.0, 1.0, 0.0005)) { 
     @Override 
     protected JComponent createEditor(SpinnerModel model) 
     { 
     return new NumberEditor(this, "0.0000");//needed decimal format 
     } 
    }; 
+0

Interesante ... Supuse que la ruleta mantenía el mismo valor de doble precisión independientemente de cómo fuera formateado por el campo de texto. ¡Gracias! –

+0

Gracias Peter. Edité mi pregunta para incluir una línea adicional que tiene un propósito similar. –