繁体   English   中英

从其他类中的线程调用时不重新出现

[英]Repaint not occurring when called from thread in a different class

我正在尝试制作一个简单的火炮游戏,并在点击按钮时打印一个在圆弧中移动的圆圈。

点击后,我创建一个线程并计算“射弹”的位置,并在计算x和y位置打印出一个圆圈。

当我从一个类执行代码时,它调用重绘并绘制“射弹”的轨迹,但是当我设置一个单独的类来调用它并在点击按钮时将其打印出来时它不会从中调用重绘环。

当我执行下面的类本身显示我想要的。

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Pong4 extends JPanel implements Runnable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private ScreenLocation location;

    private boolean renderBulit = false;

    public static void main(String[] args)
    {
        Pong4 p = new Pong4();

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(p);
        frame.setSize(800, 600);
        frame.setVisible(true);

        Thread thread = new Thread(p);
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException ex) {
            // TODO Auto-generated catch block
            ex.printStackTrace();
        }
    }

    public Pong4()
    {
    }

    public ScreenLocation updatePosition(ScreenLocation location, double xSpeed, double ySpeed, double time) 
    {   
        return new ScreenLocation((int)(location.getX() + xSpeed * time), (int)(location.getY() - ySpeed * time));
    }


    @Override
    public void run()
    {

        double time = 0;
        location = new ScreenLocation(100, 400);
        renderBulit = true;

        double xSpeed = 50;
        double ySpeed = 50;

        while (location.getX() >= 0 && 800 > location.getX() && 400 >= location.getY())
        {       
            repaint();

            System.out.println("test");

            try {
                Thread.sleep(15);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            time += 0.01;
            location = updatePosition(location, xSpeed, ySpeed, time);
            ySpeed = ySpeed - Constants.GRAVITY * time;
        }

        renderBulit = false;
        repaint();

    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponents(g); 
        Graphics2D g2d = (Graphics2D)g;

        // Paint a gradient from top to bottom
        GradientPaint gp = new GradientPaint( 0, 0, Color.BLACK,
            0, getHeight( ), new Color(0, 0, 255).darker( ).darker() );

        g2d.setPaint( gp );
        g2d.fillRect( 0, 0, getWidth( ), getHeight( ) );

        if (renderBulit)
        {
            // draw circle (color already set to foreground)
            g.setColor(Color.red);
            g.fillOval(location.getX(), location.getY(), 4, 4);
            g.drawOval(location.getX(), location.getY(), 4, 4);


            //Image image = new ImageIcon("src/au/com/tankwarz/view/resources/images/BULIT0.GIF").getImage();
            //g.drawImage(image, location.getX(), location.getY(), this); 
        }
        g2d.dispose();       
    }

    public class ScreenLocation 
    {
        private int x;

        private int y;

        public ScreenLocation (int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }


    }
}

但是,当我尝试以下时,它不会显示。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.jdesktop.application.Application;

public class Pong3 extends JPanel{

    public static void main(String[] args)
    {

        new Pong3();
    }

    private static final long serialVersionUID = 2944576178447230562L;

    private JButton fireButton;
    private JPanel controlsPanel;

    private Pong4 pong;

    public Pong3() {
        super();
        initGUI();

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(this);
        frame.setSize(800, 600);
        frame.setVisible(true);
    }

    private void initGUI() {
        try {
            this.setPreferredSize(new java.awt.Dimension(800, 600));
            this.setSize(800, 600);
            this.setLayout(null);
            {
                pong = new Pong4();
                this.add(pong);
                pong.setLayout(null);
                pong.setBounds(0, 0, 800, 450);
            }           
            {
                controlsPanel = new JPanel();
                this.add(controlsPanel);
                GridBagLayout controlsPanelLayout = new GridBagLayout();
                controlsPanelLayout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1};
                controlsPanelLayout.rowHeights = new int[] {7, 7, 7, 7};
                controlsPanelLayout.columnWeights = new double[] {0.1, 0.1, 0.1, 0.1};
                controlsPanelLayout.columnWidths = new int[] {7, 7, 7, 7};
                controlsPanel.setLayout(controlsPanelLayout);
                controlsPanel.setBounds(0, 450, 800, 110);
                controlsPanel.setName("controlsPanel");

                {
                    fireButton = new JButton();
                    controlsPanel.add(fireButton, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
                    fireButton.setName("fireButton");
                    fireButton.setText("Fire");
                    fireButton.setPreferredSize(new java.awt.Dimension(104, 51));
                    fireButton.addActionListener(new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {            
                            Thread thread = new Thread(pong);
                            thread.start();
                            try {
                                thread.join();
                            } catch (InterruptedException ex) {
                                // TODO Auto-generated catch block
                                ex.printStackTrace();
                            }


                        }
                    });
                }
            }
            Application.getInstance().getContext().getResourceMap(getClass()).injectComponents(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

非常感谢任何帮助,为什么这样做。

你的thread.join()通过将“后台”线程与当前线程绑在一起来解除尝试使用后台线程的所有好处,因此你不应该这样做。 事情似乎在第一个代码中工作的唯一原因是由于你的代码最初不在事件派发线程中运行,所以你的join()调用将线程连接到主线程,而不是EDT,因此不会冻结美东时间。 无论哪种方式, join()都出错了。

我认为更好的解决方案是使用Swing Timer。 这将消除显式使用后台线程的需要。

顺便说一句:如果要创建具有强大,灵活和美观的布局的GUI,请避免使用空布局。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM