views:

154

answers:

1

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);
    }
}
+2  A: 

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.

Kirill
not only that, there is a potential infinite loop in `hanoi` with the `while(parar)` loop.
akf