Java, zbyt częste wywoływanie metody "repaint" z klasy JPanel

0

Witam
Mam taki problem prosty do wytłumaczenia.
Chodzi o to że wywołuje metodę "repaint" z wątku który sam utworzyłem. Zauważyłem że kiedy ustawię bardzo szybkie wywoływanie metody "repaint" to program jest przerywany po przez wyjątek "java.util.ConcurrentModificationException" co oznacza że "repaint" też musi wywoływać wątek który nie nadąża odmalować zawartości. Dodanie wyjątku nie działa, ponieważ prawdopodobnie wyjątek jest generowany gdzieś w klasie Graphics, tak tylko się domyślam. Pytanie jest takie czy da się kontrolować "repaint", np czekaj dopóki "repaint" skończy odmalowywać wtedy przejdź kolejnych instrukcji.

4

W tzw, innym wątku (nie głównym) rób:
SwingUtilities.invokeLater( ()-> { ... tu wywołuj repaint });

A to dlatego, że nie można Swingowego kodu wyoływac "z nieswingowego" wątku.

0

@jarekr000000: dalej to samo ; /

3

Pokaż ten wyjątek, z całym stacktrace. Pokaż kod.

0

@jarekr000000:

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Random;

public class PanelMatrix extends JPanel implements KeyListener, Runnable {
    private Random random = new Random();
    private Window window;

    private ArrayList<Character> characters = new ArrayList<>();

    public PanelMatrix(Window window) {
        this.window = window;

        addKeyListener(this);
        setFocusable(true);

        Thread t = new Thread(this);
        t.start();
    }

    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(0,0,getWidth(),getHeight());

        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        for(Character c : characters) {
            g.setFont(window.getChosenFont().deriveFont(20f));
            g.setColor(c.color);
            g.drawString(String.valueOf(c.character), (int)c.pX, (int)c.pY);
        }
        g.dispose();
    }


    @Override
    public void run() {
            long lastTime = System.nanoTime();
            final int FRAME_RATE = 100;
            final int WIDTH_CHARACTER = 20;
            ArrayList<Character> remove_characters = new ArrayList<>();

            final double speeds_arrays[] = new double[100];

            for(int i = 0; i < 100; i++) {
                int speed = random.nextInt(100);
                speeds_arrays[i] = ((double)speed) / 10;
            }


            int index = 0;
                while (true) {

                    if (lastTime + 1000000000l / FRAME_RATE < System.nanoTime()) {
                        lastTime = System.nanoTime();

                        index++;
                        if(index > 5) {
                            for (int i = 0; i < getWidth() / WIDTH_CHARACTER; i++) {
                                characters.add(new Character(i * WIDTH_CHARACTER, 50, random, speeds_arrays[i]));
                            }
                            index = 0;
                        }

                        for (Character c : characters) {
                            c.pY+=c.speed;
                            c.refresh();
                            if (c.pY > getHeight()) {
                                remove_characters.add(c);
                            }
                        }


                        characters.removeAll(remove_characters);
                        remove_characters.clear();
                        SwingUtilities.invokeLater( ()-> {repaint();});
                    }
                }
            }




    @Override
    public void keyTyped(KeyEvent e) {

    }
    boolean index = true;

    @Override
    public void keyPressed(KeyEvent e) {
        try {
            if (getGraphics() != null) {
                if (index) {

                }
            }
        }catch (ConcurrentModificationException ex) {}

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }



    public class Character {
        private double speed;
        private char character;

        private double pX;
        private double pY;
        private Color color;

        private final int countersChange = random.nextInt(100)+1;
        private int counter = 0;

        public Character(double pX, double pY, Random random, double speed) {
            this.pX = pX;
            this.pY = pY;
            this.speed = speed;
            if(random.nextBoolean()) {
                character = (char) (random.nextInt(10) + 48);
            }else {
                character = ' ';
            }

            color = Color.GREEN;//new Color(random.nextInt(255), random.nextInt(255),random.nextInt(255));
        }

        public void refresh() {
            if(character == ' ') {return;}
            counter ++;
            if(counter > countersChange) {
                counter = 0;
                character = (char) (random.nextInt(10) + 48);
            }
        }
    }
}
3

Na szybko.. Zamień
= new ArrayList<>()
Na
= new CopyOnWriteArrayList<>()

Moze pomoże.

1 użytkowników online, w tym zalogowanych: 0, gości: 1