java - 在 Java 中使用线程绘制面板

标签 java multithreading user-interface

不知道为什么在我的运行方法中没有进行打印。我在 horsethread 类中调用 repaint 并覆盖它。这是我的代码。当我运行程序并点击 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);     
}

}

最佳答案

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

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

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

例如...

Horsing around

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 不是线程安全的,在此环境中使用 Thread 时要小心;)

关于java - 在 Java 中使用线程绘制面板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22852377/

相关文章:

multithreading - 如何在分区数组上运行并行计算线程?

user-interface - 你从哪里得到你的声音样本?

python - Tkinter:当 OptionMenu 选择更改时更改标签

android - 如何去除 Android 中按下的 slider 的光晕?

java - 读取文本文件: Error - Variable out of type FileWriter

java - 从同一后端支持移动应用程序和网站的最佳技术堆栈是什么?

Java:异常本身为空

java - java中的executor service不是并行提交任务吗?

java - 困惑,像python,ruby这样的语言是单线程的吗?不像说java? (对于网络应用程序)

java - Ping Sweep,能够进入某个范围