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:
- Use buttons to draw a race track
- Use threads to move buttons as JRacers
- 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:
- The contract error involves non-transitivity of a compare method
- 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.