这有点难以解释,但情况如下:
我正在编写一个Cellular Automation程序,并且有一个扩展JFrame的mainScreen类,而JFrame包含自定义Jpanel,它也是一个继续重绘自己的线程。主类(App)创建主屏幕。
当我从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; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame;
公共类MainScreen扩展JFrame实现KeyListener { 私人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();
}
}
MapPanel
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) { }
}
}
}
答案 0 :(得分:1)
您的“业务逻辑”看起来应该在与GUI不同的线程上运行。因此,不要直接从GUI线程(在动作侦听器中)调用它,而是将其放在新的Thread中。
只要您的动作侦听器(或本例中的键侦听器)未返回,您的GUI就不会被绘制,因为绘制发生在与输入处理相同的线程中。
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == 'r') {
new Thread("envolver") { public void run() {
System.out.println("Run mode");
_app.envolveCells();
}).start();
}
}