重画问题

发布于 2024-09-04 21:27:33 字数 8661 浏览 6 评论 0原文

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疯了 2024-09-11 21:27:33

假设您在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文