3

我在大学学习 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;
}
4

0 回答 0