2010-06-03 65 views
0

我在重绘方法移动时出现问题。我不知道斗什么,代码如下重绘问题

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); 
    } 
} 
+5

而问题是什么? – mob 2010-06-03 18:48:16

回答

3

假设你看到println语句的进展,但不在屏幕上,这是因为重绘的调用不是同步的。 Swing有一个用于处理UI的特殊线程 - 称为Event Dispatch Thread。重绘的调用由该线程处理,但异步 - 处理该线程上计划的所有当前事件之后。

当你在你的actionPerformed中调用hanoi时,这是在同一个UI线程上完成的。会发生的是,直到递归完成,repaint()调用才会排队。一旦递归完成(并且所有堆栈已经在模型中移动),UI线程将处理所有repaint()请求,绘制 - 我所假设的 - 最终状态。

你需要做的是将模型处理分离成单独的工作线程。在每个递归步骤中,发出repaint()调用并休眠几百毫秒。这将允许UI线程重新绘制模型的当前状态并让用户实际跟踪进度。

+0

不仅如此,'while(parar)'循环在'hanoi'中有一个潜在的无限循环。 – akf 2010-06-03 23:13:05