我在方法移动中重新绘制有问题。我不知道该怎么办,代码如下
import java.awt.*;
import java.io.*;
import java.text.*;
import java.util.*;
import javax.sound.sampled.*;
import javax.swing.*;
import javax.swing.Timer;
import java.awt.event.*;
import java.lang.*;
public class bbb extends JPanel
{
public Stack<Integer> stacks[];
public JButton auto, jugar, nojugar;
public JButton ok, ok2;
public JLabel info = new JLabel("Numero de Discos: ");
public JLabel instruc = new JLabel("Presiona la base de las torres para mover las fichas");
public JLabel instruc2 = new JLabel("No puedes poner una pieza grande sobre una pequenia!");
public JComboBox numeros = new JComboBox();
public JComboBox velocidad = new JComboBox();
public boolean seguir = false, parar = false, primera = true;
public int n1, n2, n3;
public int click1 = 0;
public int opcion = 1, tiempo = 50;
public int op = 1, continuar = 0, cont = 0;
public int piezas = 0;
public int posx, posy;
public int no;
public bbb() throws IOException
{
stacks = new Stack[3];
stacks[0] = new Stack<Integer>();
stacks[1] = new Stack<Integer>();
stacks[2] = new Stack<Integer>();
setPreferredSize(new Dimension(1366, 768));
ok = new JButton("OK");
ok.setBounds(new Rectangle(270, 50, 70, 25));
ok.addActionListener(new okiz());
ok2 = new JButton("OK");
ok2.setBounds(new Rectangle(270, 50, 70, 25));
ok2.addActionListener(new vel());
add(ok2);
ok2.setVisible(false);
auto = new JButton("Automatico");
auto.setBounds(new Rectangle(50, 80, 100, 25));
auto.addActionListener(new a());
jugar = new JButton("PLAY");
jugar.setBounds(new Rectangle(100, 100, 70, 25));
jugar.addActionListener(new play());
nojugar = new JButton("PAUSE");
nojugar.setBounds(new Rectangle(100, 150, 70, 25));
nojugar.addActionListener(new stop());
setLayout(null);
info.setBounds(new Rectangle(50, 50, 170, 25));
info.setForeground(Color.white);
instruc.setBounds(new Rectangle(970, 50, 570, 25));
instruc.setForeground(Color.white);
instruc2.setBounds(new Rectangle(970, 70, 570, 25));
instruc2.setForeground(Color.white);
add(instruc);
add(instruc2);
add(jugar);
add(nojugar);
jugar.setVisible(false);
nojugar.setVisible(false);
add(info);
info.setVisible(false);
add(ok);
ok.setVisible(false);
add(auto);
numeros.setBounds(new Rectangle(210, 50, 50, 25));
numeros.addItem(1);
numeros.addItem(2);
numeros.addItem(3);
numeros.addItem(4);
numeros.addItem(5);
numeros.addItem(6);
numeros.addItem(7);
numeros.addItem(8);
numeros.addItem(9);
numeros.addItem(10);
add(numeros);
numeros.setVisible(false);
velocidad.setBounds(new Rectangle(150, 50, 100, 25));
velocidad.addItem("Lenta");
velocidad.addItem("Intermedia");
velocidad.addItem("Rapida");
add(velocidad);
velocidad.setVisible(false);
}
public void Mover(int origen, int destino)
{
for (int i = 0; i < 3; i++)
{
System.out.print("stack " + i + ": ");
for (int n : stacks[i])
{
System.out.print(n + ";");
}
System.out.println("");
}
System.out.println("de <" + origen + "> a <" + destino + ">");
stacks[destino].push(stacks[origen].pop());
System.out.println("");
this.validate();
this.repaint();
}
public void hanoi(int origen, int destino, int cuantas)
{
while (parar)
{
}
if (cuantas <= 1)
{
Mover(origen, destino);
}
else
{
hanoi(origen, 3 - (origen + destino), cuantas - 1);
Mover(origen, destino);
hanoi(3 - (origen + destino), destino, cuantas - 1);
}
}
public void paintComponent(Graphics g)
{
ImageIcon fondo = new ImageIcon("fondo.jpg");
g.drawImage(fondo.getImage(), 0, 0, 1366, 768, null);
g.setColor(new Color((int) (Math.random() * 254),
(int) (Math.random() * 255),
(int) (Math.random() * 255)));
g.fillRect(0, 0, 100, 100);
g.setColor(Color.white);
g.fillRect(150, 600, 250, 25);
g.fillRect(550, 600, 250, 25);
g.fillRect(950, 600, 250, 25);
g.setColor(Color.red);
g.fillRect(270, 325, 10, 275);
g.fillRect(270 + 400, 325, 10, 275);
g.fillRect(270 + 800, 325, 10, 275);
int x, y, top = 0;
g.setColor(Color.yellow);
x = 150;
y = 580;
for (int ii : stacks[0])
{
g.fillRect(x + ((ii * 125) / 10), y - (((ii) * 250) / 10), ((10 - ii) * 250) / 10, 20);
}
x = 550;
y = 580;
for (int ii : stacks[1])
{
g.fillRect(x + ((ii * 125) / 10), y - (((ii) * 250) / 10), ((10 - ii) * 250) / 10, 20);
}
x = 950;
y = 580;
for (int ii : stacks[2])
{
g.fillRect(x + ((ii * 125) / 10), y - (((ii) * 250) / 10), ((10 - ii) * 250) / 10, 20);
}
System.out.println("ENTRO");
setOpaque(false);
}
private class play implements ActionListener //manual
{
public void actionPerformed(ActionEvent algo)
{
parar = false;
if (primera = true)
{
hanoi(0, 2, no);
primera = false;
}
}
}
private class stop implements ActionListener //manual
{
public void actionPerformed(ActionEvent algo)
{
parar = true;
}
}
private class vel implements ActionListener //manual
{
public void actionPerformed(ActionEvent algo)
{
if (velocidad.getSelectedItem() == "Lenta")
{
tiempo = 150;
}
else if (velocidad.getSelectedItem() == "Intermedia")
{
tiempo = 75;
}
else
{
tiempo = 50;
}
ok2.setVisible(false);
jugar.setVisible(true);
nojugar.setVisible(true);
}
}
private class a implements ActionListener //auto
{
public void actionPerformed(ActionEvent algo)
{
auto.setVisible(false);
info.setVisible(true);
numeros.setVisible(true);
ok.setVisible(true);
op = 3;
}
}
private class okiz implements ActionListener //ok
{
public void actionPerformed(ActionEvent algo)
{
no = Integer.parseInt(numeros.getSelectedItem().toString());
piezas = no;
if (no > 0 && no < 11)
{
info.setVisible(false);
numeros.setVisible(false);
ok.setVisible(false);
for (int i = no; i > 0; i--)
{
stacks[0].push(i);
}
opcion = 2;
if (op == 3)
{
info.setText("Velocidad: ");
info.setVisible(true);
velocidad.setVisible(true);
ok2.setVisible(true);
}
}
else
{
}
repaint();
}
}
}
下面的另一个类的代码如下:
import java.awt.*;
import java.io.*;
import java.net.URL;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.border.*;
import java.lang.*;
import java.awt.event.*;
public class aaa extends JPanel
{
private ImageIcon Background;
private JLabel fondo;
public static void main(String[] args) throws IOException
{
JFrame.setDefaultLookAndFeelDecorated(true);
final JPanel cp = new JPanel(new BorderLayout());
JFrame frame = new JFrame ("Torres de Hanoi");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setSize(550,550);
frame.setVisible(true);
bbb panel = new bbb();
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
最佳答案
假设您在println语句中看到了进度,但是在屏幕上却没有看到,那是因为重绘的调用是不同步的。 Swing有一个用于处理UI的特殊线程-称为事件调度线程。在该线程上调度的所有当前事件都已处理之后,对该线程的重绘调用由该线程处理,但是是异步处理的。
当您在actionPerformed中调用hanoi时,这是在同一UI线程上完成的。发生的事情是,直到您的递归完全完成,才将repaint()调用排队。一旦递归完成(并且所有堆栈都已在模型中移动),UI线程就会处理所有repaint()请求,从而绘制(我认为是这样)最终状态。
您需要做的是将模型处理分为一个单独的工作线程。在每个递归步骤上,发出repaint()调用并休眠几百毫秒。这将允许UI线程重新绘制模型的当前状态,并让用户实际跟踪进度。
关于java - 重绘(repaint)问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2968834/