重画问题
我在 move 方法中重新绘制时遇到问题。我不知道该怎么做,代码位于
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);
}
}
I have a problem with my repaint in the method move. I dont know what to doo, the code is below
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();
}
}
}
the code of the other class that calls the one up is below:
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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
假设您在 println 语句中看到进度,但在屏幕上看不到,这是因为对 repaint 的调用不同步。 Swing 有一个特殊的线程用于处理 UI - 称为事件调度线程。对重绘的调用由该线程处理,但异步处理 - 在该线程上安排的所有当前事件都已处理之后。
当您在 actionPerformed 中调用 hanoi 时,这是在同一个 UI 线程上完成的。发生的情况是,在递归完全完成之前, repaint() 调用只是排队。一旦递归完成(并且所有堆栈都已在模型中移动),UI 线程就会处理所有 repaint() 请求,绘制 - 我假设的 - 最终状态。
您需要做的是将模型处理分离到单独的工作线程中。在每个递归步骤中,发出 repaint() 调用并休眠几百毫秒。这将允许 UI 线程重新绘制模型的当前状态,并让用户实际跟踪进度。
Assuming that you see the progress in the println statements but not on the screen, it is because a call to repaint is not synchronous. Swing has a special thread for handling UI - called Event Dispatch Thread. A call to repaint is handled by that thread, but asynchronously - after all the current events scheduled on that thread have been processed.
When you call hanoi in your actionPerformed, that is done on the same UI thread. What happens is that until your recursion is fully done, repaint() calls are just queued. Once the recursion completes (and all stacks have been moved in the model), the UI thread processes all repaint() requests, painting - what i assume - the final state.
What you need to do is to separate the model processing into a separate worker thread. On every recursion step, issue a repaint() call and sleep for a few hundred milliseconds. This will allow the UI thread to repaint the current state of the model and let the user actually trace the progress.