簡體   English   中英

重畫線程在觸發業務功能時工作正常,但在被引用觸發時凍結

[英]Repaint thread works fine when triggering business function, but freezes when triggered by reference

有點難以解釋,但情況如下:

我正在編寫一個Cellular Automation程序,並具有一個mainScreen類,該類擴展了JFrame,並且JFrame包含自定義Jpanel,該Jpanel也是一個繼續重繪其自身的線程。 主類(App)創建mainScreen。

現在是奇怪的事情,當我從App類調用業務功能(即在while循環中將單元格展開)時,但是當我從MainScreen調用相同的功能時,它正在工作(世代的實時視圖)類(通過鍵盤輸入),則重畫不正確,但是我看到控制台輸出顯示了幾代人都在進化。而且該程序沒有響應窗口的關閉交叉,在其他情況下,它就像關閉運行算法時正常。

那么,為什么我的Jpanel不重新粉刷? 希望你們(女孩)能幫上忙。

類關系:App <-MainScreen <-MapPanel

應用程式

package Business;

import GUI.MainScreen;
import java.util.Random;

public class App {
    public static final int _CELL_SIZE = 5;
    public static final int _WIN_WIDTH = 800;
    public static final int _WIN_HEIGTH = 600;
    public static final int _HELP_HEIGTH = 72;
    public static final double _LIFE_START = 0.1F;

    private MainScreen _mainScreen;
    private Cell[][] _map;
    private int _generation;
    private Random _random;
    private boolean _running;

public App() {
    _generation = 0;
    _running = false;
    _random = new Random(System.currentTimeMillis());
    newMap();
    _mainScreen = new MainScreen(this);
    //envolveCells();
    //cout();
}

public void envolveCells() {
    _generation = 0;
    _running = true;
    Cell[][] newMap = new Cell[getNumOfRows()][getNumOfCells()];

    while(_running) {
        newMap = new Cell[getNumOfRows()][getNumOfCells()];

        //envolve cells
        for(int row = 0; row < getNumOfRows(); row++) {
            for(int cell = 0; cell < getNumOfCells(); cell++) {
                System.out.println(_map[row][cell].envolve());
                newMap[row][cell] = new Cell(_map[row][cell].envolve());
                newMap[row][cell].setNeighbors(_map[row][cell].getNeighbors());
            }
        }

        _map = newMap;
        _generation++;

        try {
            Thread.sleep(100);
        } catch(Exception ex) { }
    }
}

包GUI;

導入Business.App; 導入java.awt.event.KeyEvent; 導入java.awt.event.KeyListener; 導入javax.swing.JFrame;

公共類MainScreen擴展JFrame實現KeyListener {private App _app; 私人MapPanel _mapPanel;

public MainScreen(App app){
    _app = app;
    _mapPanel = new MapPanel(app);

    setTitle("Cellular Automaton sandbox - Sven van Zoelen");
    setSize(App._WIN_WIDTH, App._WIN_HEIGTH + App._HELP_HEIGTH);
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    add(_mapPanel);
    addKeyListener(this);

    setVisible(true);
}

public void keyTyped(KeyEvent e) {
    if(e.getKeyChar() == 'r') {
        System.out.println("Run mode");
        _app.envolveCells();
    }
}

地圖面板

package GUI;

import Business.App;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

public class MapPanel extends JPanel implements Runnable {
    private App _app;
    private Font _font = new Font("Arial", Font.PLAIN, 10);

public MapPanel(App app) {
    _font = new Font("Arial", Font.PLAIN, 10);
    _app = app;

    new Thread(this).start();
}
....
public void run() {
    while(true) {
        repaint();

        try {
            Thread.sleep(50);
        } catch(Exception ex) { }
    }
  }
}

您的“業務邏輯”看起來應該在與GUI不同的線程上運行。 因此,不要直接從GUI線程(在動作偵聽器中)調用它,而是將其放在那里的新線程中。

只要您的動作偵聽器(在這種情況下為鍵偵聽器)未返回,就不會繪制您的GUI,因為繪制與輸入處理在同一線程中進行。

public void keyTyped(KeyEvent e) {
    if(e.getKeyChar() == 'r') {
        new Thread("envolver") { public void run() {
           System.out.println("Run mode");
           _app.envolveCells();
        }).start();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM