为什么这个线程代码不能在GUI中正常工作?[Java Swing][线程]
我的项目使用JavaSwing作为GUI。我正在制作河内塔的游戏。我刚刚让GUI全部正常工作,但是我的solve命令无法正常工作 如果没有线程化调用,它会按照预期立即解决塔楼问题。我添加了两个线程。waits希望它一步一步地解决这个问题,这样用户就可以看到它是如何做的,但它会等待一段时间,然后立即解决整个难题。我在想它可能不会重新粉刷,但我不知道为什么。有人知道发生了什么事吗 以下是解决方案的代码:为什么这个线程代码不能在GUI中正常工作?[Java Swing][线程],java,swing,awt,border-layout,towers-of-hanoi,Java,Swing,Awt,Border Layout,Towers Of Hanoi,我的项目使用JavaSwing作为GUI。我正在制作河内塔的游戏。我刚刚让GUI全部正常工作,但是我的solve命令无法正常工作 如果没有线程化调用,它会按照预期立即解决塔楼问题。我添加了两个线程。waits希望它一步一步地解决这个问题,这样用户就可以看到它是如何做的,但它会等待一段时间,然后立即解决整个难题。我在想它可能不会重新粉刷,但我不知道为什么。有人知道发生了什么事吗 以下是解决方案的代码: public class Solver { public Solver() { //
public class Solver {
public Solver() {
// nothing
}
public void solve(
int numberBlocks,
int startPin,
int auxiliaryPin,
int endPin) {
if (numberBlocks == 1) {
movePin(startPin, endPin);
try {
Thread.sleep(200);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
solve(numberBlocks - 1, startPin, endPin, auxiliaryPin);
movePin(startPin, endPin);
try {
Thread.sleep(200);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
solve(numberBlocks - 1, auxiliaryPin, startPin, endPin);
}
}
private void movePin(int startPin, int endPin) {
TowersOfHanoiGame.moveTopBlock(startPin, endPin);
}
以下是GUI中执行此工作的代码:
我知道它写得很糟糕,这是我第一次用JavaSwing写作,我边学边写。如果有人对如何更好地构建这个有任何建议,我也很乐意听到。
我正在粘贴整个类,但重要的方法是initListeners和moveTopBlock,以及它们调用的方法
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class TowersOfHanoiGame {
private static JFrame mainWindow;
private static JPanel mainContentPanel;
private static JPanel content;
private static ArrayList<Block> pegOneBlocks = new ArrayList<Block>();
private static ArrayList<Block> pegTwoBlocks = new ArrayList<Block>();
private static ArrayList<Block> pegThreeBlocks = new ArrayList<Block>();
private Color[] randomColors = new Color[8];
private Dimension menuSize = new Dimension(100, 100);
private static final int DISCSTEXTSIZE = 20;
private static final int MOVESTEXTSIZE = 30;
private ActionListener downButtonListener;
private ActionListener upButtonListener;
private ActionListener solveButtonListener;
private JLabel discs;
private JLabel moves;
private int discsNumber = 3;
private int movesNumber = 0;
private Solver solver = new Solver();
public TowersOfHanoiGame() {
// do nothing
initRandomColors();
initBlocks(3);
}
/**
* Initialize and display the game
*/
public void display() {
initListeners();
initWindow();
mainWindow.setVisible(true);
}
private void initListeners() {
downButtonListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if (discsNumber > 3) {
discsNumber--;
updateLabels();
// clearContentFrame();
clearBlockArrays();
initBlocks(discsNumber);
reDrawContentFrame();
}
}
};
upButtonListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (discsNumber < 8) {
discsNumber++;
updateLabels();
// clearContentFrame();
clearBlockArrays();
initBlocks(discsNumber);
reDrawContentFrame();
}
}
};
solveButtonListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
solver.solve(discsNumber, 0, 1, 2);
}
};
}
private void updateLabels() {
discs.setText("DISCS: " + discsNumber);
moves.setText("MOVES: " + movesNumber);
}
/**
* Init the main window
*/
private void initWindow() {
mainWindow = new JFrame("Towers Of Hanoi");
initContentPanel();
mainWindow.setContentPane(mainContentPanel);
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.setSize(1000, 1000);
mainWindow.setResizable(false);
mainWindow.getContentPane().setBackground(Color.WHITE);
}
/**
* Init the main content panel
*/
private void initContentPanel() {
mainContentPanel = new JPanel(new BorderLayout(50, 50));
JPanel menu = initMenuFrame();
content = initContentFrame();
mainContentPanel.add(menu, BorderLayout.PAGE_START);
mainContentPanel.add(content, BorderLayout.CENTER);
}
private static JPanel initContentFrame() {
JPanel ret = new JPanel(new BorderLayout());
JPanel pegs = new JPanel(new BorderLayout());
pegs.setBackground(Color.WHITE);
ret.setBackground(Color.WHITE);
Peg peg1 = new Peg(25, 500, 1.2);
Peg peg2 = new Peg(50, 500, 1.2);
Peg peg3 = new Peg(0, 500, 1.2);
peg1.addBlocks(pegOneBlocks);
peg2.addBlocks(pegTwoBlocks);
peg3.addBlocks(pegThreeBlocks);
pegs.add(peg1, BorderLayout.LINE_START);
pegs.add(peg2, BorderLayout.CENTER);
pegs.add(peg3, BorderLayout.LINE_END);
ret.add(pegs, BorderLayout.CENTER);
return ret;
}
private Color randomColor() {
int R = (int)(Math.random() * 256);
int G = (int)(Math.random() * 256);
int B = (int)(Math.random() * 256);
Color color = new Color(R, G, B); // random color, but can be bright or
// dull
// to get rainbow, pastel colors
Random random = new Random();
final float hue = random.nextFloat();
final float saturation = 0.9f;// 1.0 for brilliant, 0.0 for dull
final float luminance = 1.0f; // 1.0 for brighter, 0.0 for black
color = Color.getHSBColor(hue, saturation, luminance);
return color;
}
private void initRandomColors() {
for (int i = 0; i < 8; i++) {
randomColors[i] = randomColor();
}
}
private void initBlocks(int numBlocks) {
int startWidth = Block.LONGESTWIDTH;
for (int i = 0; i < numBlocks; i++) {
Block b = new Block((startWidth - (i * 15)), randomColors[i]);
pegOneBlocks.add(b);
}
}
private static void clearContentFrame() {
mainContentPanel.remove(content);
mainContentPanel.repaint();
}
private void clearBlockArrays() {
pegOneBlocks.clear();
pegTwoBlocks.clear();
pegThreeBlocks.clear();
}
public static void reDrawContentFrame() {
content = initContentFrame();
mainContentPanel.add(content, BorderLayout.CENTER);
mainContentPanel.repaint();
}
public static void moveTopBlock(int startPin, int destinationPin) {
Block b = null;
if (startPin == 0) {
b = pegOneBlocks.get(pegOneBlocks.size() - 1);
pegOneBlocks.remove(pegOneBlocks.size() - 1);
}
else if (startPin == 1) {
b = pegTwoBlocks.get(pegTwoBlocks.size() - 1);
pegTwoBlocks.remove(pegTwoBlocks.size() - 1);
}
else if (startPin == 2) {
b = pegThreeBlocks.get(pegThreeBlocks.size() - 1);
pegThreeBlocks.remove(pegThreeBlocks.size() - 1);
}
if (destinationPin == 0) {
pegOneBlocks.add(b);
}
else if (destinationPin == 1) {
pegTwoBlocks.add(b);
}
else if (destinationPin == 2) {
pegThreeBlocks.add(b);
}
reDrawContentFrame();
content.validate();
mainContentPanel.validate();
mainWindow.validate();
}
/**
* Build the menu panel
*
* @return menu panel
*/
private JPanel initMenuFrame() {
JPanel ret = new JPanel(new BorderLayout());
ret.setPreferredSize(menuSize);
// left
JPanel left = new JPanel(new FlowLayout());
left.setPreferredSize(menuSize);
JLabel label = new JLabel("DISCS: 3");
discs = label;
label.setFont(new Font("Serif", Font.BOLD, DISCSTEXTSIZE));
Button down = new Button("Decrease");
down.addActionListener(downButtonListener);
Button up = new Button("Increase");
up.addActionListener(upButtonListener);
left.add(label);
left.add(up);
left.add(down);
// mid
moves = new JLabel("MOVES: 0");
moves.setHorizontalAlignment(JLabel.CENTER);
moves.setFont(new Font("Serif", Font.BOLD, MOVESTEXTSIZE));
// right
JPanel right = new JPanel(new FlowLayout());
Button solve = new Button("Solve");
solve.addActionListener(solveButtonListener);
Button reset = new Button("Reset");
right.add(solve);
right.add(reset);
// sync
JPanel menu = new JPanel(new BorderLayout());
menu.add(left, BorderLayout.LINE_START);
menu.add(moves, BorderLayout.CENTER);
menu.add(right, BorderLayout.LINE_END);
ret.add(menu, BorderLayout.CENTER);
return ret;
}
}
导入java.awt.BorderLayout;
导入java.awt.Button;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.FlowLayout;
导入java.awt.Font;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
哈尼加姆公共级塔楼{
私有静态JFrame主窗口;
私有静态JPanel mainContentPanel;
私有静态JPanel内容;
私有静态ArrayList pegOneBlocks=新ArrayList();
私有静态ArrayList pegTwoBlocks=new ArrayList();
私有静态ArrayList pegThreeBlocks=新ArrayList();
私有颜色[]随机颜色=新颜色[8];
私有维度菜单化=新维度(100100);
专用静态最终int DISCSTEXTSIZE=20;
私有静态最终int-MOVESTEXTSIZE=30;
私有ActionListener downButtonListener;
私有ActionListener upButtonListener;
私有ActionListener solveButtonListener;
私人JLabel光盘;
私人JLabel移动;
专用int DISCSNUBER=3;
私有int movesNumber=0;
私有解算器=新解算器();
哈尼加梅公共塔楼(){
//无所事事
初始化随机颜色();
初始块(3);
}
/**
*初始化并显示游戏
*/
公共空间显示(){
initListeners();
初始化窗口();
mainWindow.setVisible(true);
}
私有void initListeners(){
downButtonListener=新建ActionListener(){
@凌驾
已执行的公共无效操作(操作事件arg0){
如果(盘数>3){
discsNumber--;
updateLabels();
//clearContentFrame();
clearBlockArrays();
初始化块(discsNumber);
重画contentframe();
}
}
};
upButtonListener=新建ActionListener(){
已执行的公共无效操作(操作事件arg0){
如果(盘数<8){
discsNumber++;
updateLabels();
//clearContentFrame();
clearBlockArrays();
初始化块(discsNumber);
重画contentframe();
}
}
};
solveButtonListener=新建ActionListener(){
已执行的公共无效操作(操作事件arg0){
求解(discsNumber,0,1,2);
}
};
}
私有void updateLabels(){
discs.setText(“discs:+discsNumber”);
moves.setText(“moves:+movesNumber”);
}
/**
*初始化主窗口
*/
私有窗口(){
主窗口=新JFrame(“河内塔”);
initContentPanel();
设置内容窗格(mainContentPanel);
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
主窗口。设置大小(10001000);
mainWindow.SetResizeable(假);
mainWindow.getContentPane().setBackground(颜色:白色);
}
/**
*初始化主内容面板
*/
私有void initContentPanel(){
mainContentPanel=新的JPanel(新的边界布局(50,50));
JPanel menu=initMenuFrame();
content=initContentFrame();
mainContentPanel.add(菜单、边框布局、页面开始);
mainContentPanel.add(内容、边框布局、中心);
}
私有静态JPanel initContentFrame(){
JPanel ret=新的JPanel(新的BorderLayout());
JPanel pegs=newjpanel(newborderlayout());
销钉。退根地面(颜色。白色);
后退地面(颜色为白色);
peg1=新Peg(25500,1.2);
Peg peg2=新Peg(50,500,1.2);
Peg peg3=新Peg(0,500,1.2);
peg1.添加块(pegOneBlocks);
peg2.添加块(PEGTOWBLOCKS);
peg3.添加块(peg3块);
pegs.add(peg1,BorderLayout.LINE_START);
pegs.add(peg2,BorderLayout.CENTER);
pegs.add(peg3,边界布局。线_末端);
ret.add(销钉、边框布局、中心);
返回ret;
}
私有颜色{
int R=(int)(Math.random()*256);
int G=(int)(Math.random()*256);
intb=(int)(Math.random()*256);
Color Color=新颜色(R、G、B);//随机颜色,但可以是明亮的或
//沉闷的
//要得到彩虹,柔和的颜色
随机=新随机();
最终浮动色调=random.nextFloat();
最终浮点数饱和度=0.9f;//辉煌为1.0,沉闷为0.0
最终浮动亮度=1.0f;//1.0表示更亮,0.0表示黑色
颜色=颜色。getHSBColor(色调、饱和度、亮度);
返回颜色;
}
私有void initrandomColor(){
对于(int i=0;i<8;i++){
randomColor[i]=randomColor();
}
}
私有void initBlocks(int numBlocks){
int startWidth=Block.LONGESTWIDTH;
对于(int i=0;isolveButtonListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
solver.solve(discsNumber, 0, 1, 2);
}
};