Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7122502

JSpinner throws ClassCastException when calling getNextValue() for bytes

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.7.0_01"
      Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
      Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows Developer Preview build winmain_win8102.8m3.110912-1733.92eb441821f0730

      A DESCRIPTION OF THE PROBLEM :
      When a javax.swing.JSpinner is instantiated with a less-than-32-bit integer as the contents, it will throw a java.lang.ClassCastException whenever javax.swing.JSpinner#getNextValue() is called and the spinner has reached its maximum value.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1: Create a program wherein at least one javax.swing.JSpinner is added to a heavyweight container so that it can be displayed, and a way to manually call the spinner's getNextValue() method.
      2: Make it so that the returned result of every call to getNextValue() is made the new value of the spinner. In other words, if you were to click a button, that button would store the result of getNextValue() to memory, then immediately use it in the spinner's setValue(Object value) method.
      3: Make it so that every time the spinner's value is set to its maximum, it is reset back to its minimum. This is important.
      4: Run the program
      5: Activate the aforementioned process that calls the aforementioned spinner's getNextValue() method and then sets that as that spinner's new value.
      5.1: Continue activating this process until the spinner has reached its maximum
      5.2: Call the process one more time. (This should throw a java.lang.ClassCastException. Subsequent repetitions of this step have the same result.)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The value would be reset to the minimum and you would be allowed to continue flipping through the values
      ACTUAL -
      The spinner stays at the minimum value and a java.lang.ClassCastException is thrown every time the exterior process attempts to increment the value

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.ClassCastException: java.lang.Byte cannot be cast to java.lang.Integer
      at java.lang.Integer.compareTo(Integer.java:52)
      at javax.swing.SpinnerNumberModel.incrValue(SpinnerNumberModel.java:349)
      at javax.swing.SpinnerNumberModel.getNextValue(SpinnerNumberModel.java:372)
      at javax.swing.JSpinner.getNextValue(JSpinner.java:375)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package com.bh.examples;

      import java.awt.event.MouseWheelEvent;
      import java.awt.event.MouseWheelListener;
      import javax.swing.JFrame;
      import javax.swing.JSpinner;
      import javax.swing.SpinnerNumberModel;
      import javax.swing.event.ChangeEvent;
      import javax.swing.event.ChangeListener;

      /**
       * Exemplifies a bug in Java's JSpinners. This particular example uses the scrolling of the mouse wheel as the trigger merely to simplify the program and its UI.
       */
      public class JSpinnerBug
      {
        static JFrame frame;
        static JSpinner spinner;

        public static void main(String[] args)
        {
          spinner = new JSpinner(new SpinnerNumberModel((byte)0, (byte)-1, (byte)11, (byte)1));
          spinner.addMouseWheelListener(new MouseWheelListener()
          {
            public void mouseWheelMoved(MouseWheelEvent e)
            {
              try
              {
                spinner.setValue(e.getWheelRotation() < 0 ? spinner.getNextValue() : spinner.getPreviousValue());
              }
              catch (IllegalArgumentException ex)
              {
                //They went too high or low.
              }
              catch (ClassCastException ex)
              {
                System.err.println("This is a bug with JSpinners.");
                ex.printStackTrace();
              }
            }
          });
          spinner.addChangeListener(new ChangeListener()
          {
            @Override
            public void stateChanged(ChangeEvent e)
            {
              if (getByteValue() < 0)
              {
                spinner.setValue((byte)10);
              }
              else if (getByteValue() > 10)
              {
                spinner.setValue((byte)0);
              }
            }
          });
          
          frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.add(spinner);
          frame.setVisible(true);
        }
        
        public static byte getByteValue()
        {
          return Byte.parseByte(spinner.getValue().toString());
        }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      manually clicking the spinner's BasicArrowButtons still works perfectly

            rupashka Pavel Porvatov (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: