我在大学学习 Java,这是我的作业。任务是创建一个x x y的颜色方块网格,每个网格在一个单独的线程中运行,并且每k ms 将其颜色更改为随机颜色或平均其邻居的颜色。
现在,如果我创建一个 30 x 30 的网格,一切运行正常。但是,如果我用 40 x 40 尝试它,我会在应用程序启动和关闭应用程序时收到以下异常。除此之外,它似乎运行正确,尽管网格在窗口内的位置似乎略有错误(它比应有的窄)。
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:747)
at java.util.TimSort.mergeAt(TimSort.java:483)
at java.util.TimSort.mergeCollapse(TimSort.java:410)
at java.util.TimSort.sort(TimSort.java:214)
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.getFirstComponent(SortingFocusTraversalPolicy.java:435)
at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(LayoutFocusTraversalPolicy.java:166)
at javax.swing.SortingFocusTraversalPolicy.getDefaultComponent(SortingFocusTraversalPolicy.java:515)
at java.awt.FocusTraversalPolicy.getInitialComponent(FocusTraversalPolicy.java:169)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:380)
at java.awt.Component.dispatchEventImpl(Component.java:4731)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
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:702)
at java.awt.EventQueue$4.run(EventQueue.java:700)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
at java.awt.SequencedEvent.dispatch(SequencedEvent.java:128)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
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:702)
at java.awt.EventQueue$4.run(EventQueue.java:700)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
这是我的代码:主类 Symulacja:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.Random;
// main class
@SuppressWarnings("serial")
public class Symulacja extends JPanel {
public Symulacja(int x, int y, int k, double p) {
super();
Field.delay = k;
Field.p = p;
Field.random = new Random();
setLayout(new GridLayout(y, x));
//creating Field objects and adding them to the panel
Field fv[][] = new Field[y][];
for (int i = 0; i<y; i++){
fv[i] = new Field[x];
for (int j = 0; j<x; j++){
fv[i][j] = new Field();
add(fv[i][j]);
}
}
//setting the neighbours in all Field objects
for (int i = 0; i<y; i++){
for (int j = 0 ; j<x; j++){
Field fv2[] = {fv[(i+1)%y][j], fv[(i+y-1)%y][j], fv[i][(j+1)%x], fv[i][(j+x-1)%x]};
fv[i][j].setArr(fv2);
}
}
//starting the threads
for (int i = 0; i<y; i++){
for (int j = 0 ; j<x; j++){
new Thread(fv[i][j]).start();
}
}
}
public static void main(String[] args) {
Symulacja s = new Symulacja(30,30,100,0); //works
//Symulacja s = new Symulacja(40,40,100,0); //throws exception
JFrame f = new JFrame();
f.setLayout(new BorderLayout());
f.add(s, BorderLayout.CENTER);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setSize(400, 400);
}
}
Field 类(单个网格元素):
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
@SuppressWarnings("serial")
class Field extends Canvas implements Runnable
{
Field()
{
color = nextInt();
randFlag = false;
//zmiana koloru na losowy po kliknięciu myszą
addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
randFlag = true;
}
});
}
void setArr(Field[] a)
{
fieldArr = a;
}
public void run()
{
while (true){
double rand = nextDouble();
int newcolor;
if (rand <= p || randFlag){ // losowy kolor lub kliknięcie myszą
newcolor = nextInt();
randFlag = false;
}
else{ // uśredniony kolor
newcolor = 0;
for (Field f: fieldArr)
newcolor+=f.getColor()/4;
}
if (newcolor!=getColor()){
setColor(newcolor);
repaint();
}
try {
Thread.sleep((long)((nextDouble() + 0.5)*delay));
} catch (InterruptedException e) {
return;
}
}
}
public void paint(Graphics g)
{
g.setColor(new Color(getColor()));
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
}
synchronized public int getColor()
{
return color;
}
synchronized private void setColor(int color)
{
this.color = color;
}
private int nextInt()
{
synchronized (random) {
return random.nextInt();
}
}
private double nextDouble()
{
synchronized (random) {
return random.nextDouble();
}
}
static public int delay;
static public double p;
Field fieldArr[];
private int color;
boolean randFlag;
static Random random;
}