【问题标题】:Painting to a panel using threads in Java在 Java 中使用线程绘制到面板
【发布时间】:2014-04-04 02:20:44
【问题描述】:

不知道为什么在我的运行方法中没有进行打印。我调用 repaint 并在 horsethread 类中覆盖它。这是我的代码。当我运行程序并点击 Run Race 时,它​​没有在面板上绘制任何内容,有什么想法吗?

import javax.swing.JFrame;



public class HorseTester {
  public static void main(String[] args) 
    {
        JFrame frame = new HorsePanel();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

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

import java.awt.GridLayout;
import java.util.ArrayList;

public class HorsePanel extends JFrame
{
    private JPanel panel;
    private JButton reset;
    private JButton quit;
    private JButton run;
    private ActionListener listener;
    private static final int NUM_OF_HORSES = 5;
    public static final int FRAME_WIDTH = 400;
    public static final int FRAME_HEIGHT = 400;
    private ArrayList<Thread> allThreads = new ArrayList<Thread>();
    private ArrayList<HorseThread> horses = new ArrayList<HorseThread>();

    public HorsePanel() 
    {
        //Allocating the memory for horses
        for(int i=0;i<NUM_OF_HORSES;i++)
            horses.add(new HorseThread(i+1));

        //Adding them to thread pool
        for(int i=0;i<NUM_OF_HORSES;i++)
            allThreads.add( new Thread(horses.get(i)));

        createPanel();
        createRunRace();
        createQuit();
        setSize(FRAME_WIDTH, FRAME_HEIGHT);
    }






    public void createRunRace()
    {

        class RunRace implements ActionListener
        {
            public void actionPerformed(ActionEvent rightEvent)
            {
                run.setEnabled(false);
                for(int i=0;i<NUM_OF_HORSES;i++)
                    allThreads.get(i).start();

            }
        }

        ActionListener a = new RunRace();
        this.run.addActionListener(a);
    }

    public void createQuit()
    {           
        class QuitRace implements ActionListener
        {
            public void actionPerformed(ActionEvent rightEvent)
            {
                System.exit(0);             
            }
        }

        ActionListener b = new QuitRace();
        this.quit.addActionListener(b);
    }
    public void createPanel()
    {
        panel = new JPanel(new BorderLayout());
        JPanel drawingPanel = new JPanel();
        this.run = new JButton("Run Race");
        this.quit = new JButton("Quit");
        this.reset = new JButton("Reset");
        JPanel topPanel = new JPanel();


        topPanel.setLayout(new GridLayout(1, 3));
        topPanel.add(run);
        topPanel.add(reset);
        topPanel.add(quit);
        panel.add(topPanel, BorderLayout.NORTH);
        panel.add(drawingPanel, BorderLayout.SOUTH);

        add(panel);
    }
}



import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;

public class HorseThread extends JComponent implements Runnable
{
public static final int X_START = 10;
public static final int Y_START = 20;

private Horse horse;
private int xpos, ypos;

public HorseThread(int offset) 
{
    xpos = X_START;
    ypos = Y_START * offset;
    horse = new Horse(xpos, ypos);
}

public void paintComponent(Graphics g) 
{
    Graphics2D g2 = (Graphics2D) g;
    horse.draw(g2);
}

/**
 * Run method that thread executes and makes horses go across
 * the screen racing.
 */
public void run() 
{
    repaint();
}
}


import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;

public class Horse 
{
private int xTop;
private int yTop;
public static final int RING_WIDTH = 20;

public Horse(int x, int y) 
{
    xTop = x;
    yTop = y;
}

public void setXY(int dx, int dy)
{
    xTop = dx;
    yTop = dy;
}

public void draw(Graphics2D g2) 
{
    Ellipse2D.Double horse = new Ellipse2D.Double(xTop, yTop, RING_WIDTH,   RING_WIDTH);
    g2.setColor(Color.BLUE);
    g2.fill(horse);
    g2.setColor(Color.WHITE);
    g2.fill(horse);     
}

}

【问题讨论】:

    标签: java multithreading user-interface


    【解决方案1】:

    主要问题是,HorseThread 扩展自 JComponent,但您实际上从未将其添加到任何内容中,因此它永远不会被绘制。

    如果相反,您创建了一个 TrackPane 并在 paintComponent 方法中绘制了每匹马(HorseThread 无需从 JComponent 扩展),您可能会有更好的运气。

    另请注意,一旦Thread 完成,就无法重新启动...

    例如...

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.geom.Ellipse2D;
    import java.util.ArrayList;
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class HorseTester {
    
        public static void main(String[] args) {
            new HorseTester();
        }
    
        public HorseTester() {
            JFrame frame = new HorsePanel();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    
        public class HorsePanel extends JFrame {
    
            private JPanel panel;
            private JButton reset;
            private JButton quit;
            private JButton run;
            private ActionListener listener;
            public static final int FRAME_WIDTH = 400;
            public static final int FRAME_HEIGHT = 400;
    
            private TrackPane trackPane;
    
            public HorsePanel() {
    
                createPanel();
                createRunRace();
                createQuit();
                setSize(FRAME_WIDTH, FRAME_HEIGHT);
            }
    
            public void createRunRace() {
    
                class RunRace implements ActionListener {
    
                    public void actionPerformed(ActionEvent rightEvent) {
                        run.setEnabled(false);
                        trackPane.start();
                    }
                }
    
                ActionListener a = new RunRace();
                this.run.addActionListener(a);
            }
    
            public void createQuit() {
                class QuitRace implements ActionListener {
    
                    public void actionPerformed(ActionEvent rightEvent) {
                        System.exit(0);
                    }
                }
    
                ActionListener b = new QuitRace();
                this.quit.addActionListener(b);
            }
    
            public void createPanel() {
                panel = new JPanel(new BorderLayout());
                trackPane = new TrackPane();
                this.run = new JButton("Run Race");
                this.quit = new JButton("Quit");
                this.reset = new JButton("Reset");
                JPanel topPanel = new JPanel();
    
                topPanel.setLayout(new GridLayout(1, 3));
                topPanel.add(run);
                topPanel.add(reset);
                topPanel.add(quit);
                panel.add(topPanel, BorderLayout.NORTH);
                panel.add(trackPane, BorderLayout.CENTER);
    
                add(panel);
            }
        }
    
        public class TrackPane extends JPanel {
    
            private static final int NUM_OF_HORSES = 5;
    
            private ArrayList<HorseThread> horses = new ArrayList<HorseThread>();
            private ArrayList<Thread> threads = new ArrayList<Thread>(25);
    
            public TrackPane() {
                setBackground(Color.GREEN);
                reset();
            }
    
            public void reset() {
                // Should dispose of any running threads...
                horses.clear();
                //Allocating the memory for horses
                for (int i = 0; i < NUM_OF_HORSES; i++) {
                    horses.add(new HorseThread(this, i + 1));
                }
            }
    
            public void start() {
                // Should dispose of any running threads...
                threads.clear();
                for (int i = 0; i < horses.size(); i++) {
                    Thread thread = new Thread(horses.get(i));
                    thread.start();
                    threads.add(thread);
                }
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                for (HorseThread horse : horses) {
                    horse.paint(g);
                }
            }
    
        }
    
        public class HorseThread implements Runnable {
    
            public static final int X_START = 10;
            public static final int Y_START = 20;
    
            private Horse horse;
            private int xpos, ypos;
            private TrackPane track;
    
            public HorseThread(TrackPane track, int offset) {
                xpos = X_START;
                ypos = Y_START * offset;
                horse = new Horse(xpos, ypos);
                this.track = track;
            }
    
            public void paint(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
                horse.draw(g2);
            }
    
            /**
             * Run method that thread executes and makes horses go across the screen
             * racing.
             */
            public void run() {
                track.repaint();
            }
        }
    
        public class Horse {
    
            private int xTop;
            private int yTop;
            public static final int RING_WIDTH = 20;
    
            public Horse(int x, int y) {
                xTop = x;
                yTop = y;
            }
    
            public void setXY(int dx, int dy) {
                xTop = dx;
                yTop = dy;
            }
    
            public void draw(Graphics2D g2) {
                Ellipse2D.Double horse = new Ellipse2D.Double(xTop, yTop, RING_WIDTH, RING_WIDTH);
                g2.setColor(Color.BLUE);
                g2.fill(horse);
                g2.setColor(Color.WHITE);
                g2.draw(horse);
            }
        }
    }
    

    还要注意 Swing 不是线程安全的,在这种环境中使用 Threads 时要小心;)

    【讨论】:

    • TrackPane 是方法还是类?
    • @user56029283888 这将是从JPanel扩展而来的类,ti将负责管理HorseThreads和Threads,并且可能有resetstart方法
    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 2015-04-08
    • 1970-01-01
    • 2013-11-20
    相关资源
    最近更新 更多