1

I was trying to help a friend debug but I can't seem to figure out the issue.

The specs of the code are very explicit:

  1. Use buttons to draw a race track
  2. Use threads to move buttons as JRacers
  3. Implement JSpinners to carry information on # of laps and # of racers

For some reason his program appears to work fine yet Java still throws an error at him involving violating a contract...

Here is the error:

> Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.TimSort.mergeHi(TimSort.java:868)
    at java.util.TimSort.mergeAt(TimSort.java:485)
    at java.util.TimSort.mergeForceCollapse(TimSort.java:426)
    at java.util.TimSort.sort(TimSort.java:223)
    at java.util.TimSort.sort(TimSort.java:173)
    at java.util.Arrays.sort(Arrays.java:659)
    at java.util.Collections.sort(Collections.java:217)
    at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(SortingFocusTraversalPolicy.java:136)
    at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(SortingFocusTraversalPolicy.java:110)
    at javax.swing.SortingFocusTraversalPolicy.getComponentAfter(SortingFocusTraversalPolicy.java:280)
    at javax.swing.LayoutFocusTraversalPolicy.getComponentAfter(LayoutFocusTraversalPolicy.java:106)
    at javax.swing.plaf.basic.BasicSpinnerUI$ArrowButtonHandler.focusSpinnerIfNecessary(BasicSpinnerUI.java:812)
    at javax.swing.plaf.basic.BasicSpinnerUI$ArrowButtonHandler.mousePressed(BasicSpinnerUI.java:770)
    at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:280)
    at java.awt.Component.processMouseEvent(Component.java:6502)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6270)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4489)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:723)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:682)
    at java.awt.EventQueue$3.run(EventQueue.java:680)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:696)
    at java.awt.EventQueue$4.run(EventQueue.java:694)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:693)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

Here is the code:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

class CntlPanel extends JPanel implements ChangeListener
{
    static JSpinner tempjs;
    static JSpinner js = new JSpinner();
    static JLabel jl = new JLabel();
    static JSpinner js2 = new JSpinner();
    static JLabel jl2 = new JLabel();
    static JButton start = new JButton();
    static JButton set = new JButton();
    public CntlPanel()        
    {
        setSize(150,125); 
        setBackground(Color.LIGHT_GRAY);
        setLocation(425,230);
    }
    public void buttonset(int next)
    {
        if (next == 0)
        {
            js2.setPreferredSize(new Dimension(45,25));
            jl2.setPreferredSize(new Dimension(50,25));    
            js.setPreferredSize(new Dimension(45,25));
            jl.setPreferredSize(new Dimension(50,25));
            set.setPreferredSize(new Dimension(100,35));

            jl.setText("Racers");
            set.setText("Set Racers");
            js.setValue(1);

            jl2.setText("Laps");
            js2.setValue(1);

            js.addChangeListener(this);
            js2.addChangeListener(this);
            add(js);
            add(jl);   
            add(js2);
            add(jl2);
            add(set);
        }
        if (next == 1)
        {
            JLabel jl1 = new JLabel();
            jl1.setPreferredSize(new Dimension(50,25));
            System.out.print("Bye");
            start.setPreferredSize(new Dimension(100,35));
            start.setText("START");
            add(jl1);
            add(start);
        }
    }

    @Override
    public void stateChanged(ChangeEvent e)
    {
        if (e.getSource()== js) 
        { 
            if ((int)js.getValue() < 1)
            {
                js.setValue(1);
            }
            if ((int)js.getValue() > 4)
            {
                js.setValue(4);
            }
        }

        if (e.getSource() == js2)
        { 
            if ((int)js2.getValue() < 1)
            {
                js2.setValue(1);
            } 
        }
    }
}

What I have been able to determine:

  1. The contract error involves non-transitivity of a compare method
  2. He never edits or messes around with the compare method... I questioned whether the use == to compare certain objects was a problem but after switching to the .equals() notation the error persisted

I am quite lost as to how to debug this.

mwerschy
  • 1,698
  • 1
  • 15
  • 26
Sidharth Ghoshal
  • 658
  • 9
  • 31
  • @sigpwned Timsort is described here: http://de.wikipedia.org/wiki/Timsort it's part of the JDK – mschenk74 May 24 '13 at 16:30
  • It seems to me that the swing mechanisms are trying to sort the components of the GUI to determine which is the next for focus traversal. This sorting requires the components to be comparable. The exception now tells us that there is some component that violates this requirement. But I don't see if it is the CntlPanel or some other component. – mschenk74 May 24 '13 at 16:37
  • 1
    Check this out: http://stackoverflow.com/questions/13575224/comparison-method-violates-its-general-contract-timsort-and-gridlayout – Genzer May 24 '13 at 16:44

0 Answers0