3

私は大学で Java を学んでおり、これは私の課題からのものです。タスクは、それぞれ別のスレッドで実行される色の正方形のx x yグリッドを作成し、 kミリ秒ごとにその色をランダムな色に変更するか、隣接する色を平均化することです。

ここで、30 x 30 のグリッドを作成すると、すべて正常に動作します。ただし、40 x 40 で試してみると、アプリの起動時に 1 回、アプリを閉じるときに 1 回、次の例外が発生します。それとは別に、グリッドはウィンドウ内で少し間違って配置されているように見えますが、正しく実行されているように見えます (本来よりも狭いです)。

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)

ここに私のコードがあります: メインクラス Symlacja:

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