重绘问题 [英] repaint problem

查看:82
本文介绍了重绘问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在方法 move 中的重绘有问题.我不知道该怎么办,代码在下面

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

推荐答案

假设您在 println 语句中看到进度,但在屏幕上看不到,这是因为对重绘的调用不是同步的.Swing 有一个用于处理 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.

当您在 actionPerformed 中调用 hanoi 时,这是在同一个 UI 线程上完成的.发生的情况是,在您的递归完全完成之前, repaint() 调用只是排队.一旦递归完成(并且模型中的所有堆栈都已移动),UI 线程将处理所有 repaint() 请求,绘制 - 我假设 - 最终状态.

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.

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

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.

这篇关于重绘问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆