有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用SwingWorker创建多线程?

我在这里看到了一个关于多线程的主题:Multi-threading with Swing

所以我做了答案https://stackoverflow.com/a/33908340/11445086

我执行下面的代码,但这里没有任何移动。我知道问题在于我的背景和流程实现,但我不知道该怎么做。我是Swing Builder的新手,如果这个问题很愚蠢,我很抱歉。该程序只是使许多圆圈在面板中移动。每个圆都是一根线,由摇摆工人制作

这是我的课程:

机器人等级:

package com.mycompany.test;

import java.awt.Color;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingWorker;

public class Robot extends SwingWorker< Void ,Integer> {
    public int x;
    public int y;
    public Color color;
    public final int speed = 10;
    Robot(int x , int y , Color color)
    {
        this.x = x;
        this.y = y;
        this.color = color;
    }
    public void move_90()
    {
        this.y += speed;
    }

    public void move_270()
    {
        this.y -= speed;
    }

    public void move_180()
    {
        this.x += speed;
    }

    public void move_0()
    {
        this.x += speed;
    }

    public void move_45()
    {
        this.x += speed;
        this.y += speed;
    }

    public void move_135()
    {
        this.x -= speed;
        this.y += speed;
    }

    public void move_225()
    {
        this.x -= speed;
        this.y -= speed;
    }

    public void move_315()
    {
        this.x += speed;
        this.y -= speed;
    }

    public void move()
    {
        Random temp = new Random();
        int rand = temp.nextInt(8);
        switch(rand)
        {
            case 1: move_0();
            break;
            case 2: move_135();
            break;
            case 3: move_180();
            break;
            case 4: move_225();
            break;
            case 5: move_270();
            break;
            case 6: move_315();
            break;
            case 7: move_45();
            break;
            case 8: move_90();
            break;
        }
    }
    @Override
    protected void process(List<Integer> chunks) {
         while(true)
        {
            move();
            if(x < 40) x = 40;
            if(x > PlayField.width - 40) x = (PlayField.width - 40);
            if(y < 40) y = 40;
            if(y > PlayField.height - 40) y = (PlayField.height - 40);
             try {
                 Thread.sleep(20);
             } catch (InterruptedException ex) {
                 Logger.getLogger(Robot.class.getName()).log(Level.SEVERE, null, ex);
             }
        }
    }

    @Override
    protected Void doInBackground() throws Exception {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

机器人模型类:

package com.mycompany.test;

import java.awt.Color;
import java.util.LinkedList;

public class RobotModel {
    public static final int MAX = 8;
    public LinkedList<Robot> model = new LinkedList<Robot>();
    public void add_New_Robot()
    {
        Robot temp = new Robot( 40 , 40 , Color.BLUE);
        model.addFirst(temp);
    }
}

操场班:

package com.mycompany.test;

import java.awt.Color;

public class PlayField {
    public static int width;
    public static int height;
    public static Color fill_Color;
    PlayField(int width , int height , Color fill_Color)
    {
        this.width = width;
        this.height = height;
        this.fill_Color = fill_Color;
    }
}

机器人世界级:

package com.mycompany.test;

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

public class RobotWorld extends JPanel {
    public RobotModel robot_Model;

    public RobotWorld(RobotModel robot_Model) {
        super();
        this.robot_Model = robot_Model;
        this.setSize(PlayField.width , PlayField.height);
        this.setVisible(true);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D graphic = (Graphics2D)g;
        graphic.setBackground(PlayField.fill_Color);
        for(Robot x : robot_Model.model )
        {
            graphic.setColor(x.color);
            graphic.drawOval(x.x, x.y, 40, 40);
        }
    }

}

最后,GameMain类:

package com.mycompany.test;

import java.awt.Color;
import javax.swing.JFrame;

public class GameMain extends JFrame {
    RobotModel a;
    PlayField field;
    public void Game_Start()
    {
        Robot robot = new Robot(100, 100, Color.RED);
        a = new RobotModel();
        RobotWorld world = new RobotWorld(a);
        world.robot_Model.add_New_Robot();
        this.setSize(field.width , field.height);
        this.add(world);
        this.setVisible(true);
        world.repaint();
    }

//    public void gameUpdate(Robot a , PlayField field)
//    {
//        a.move();
//        if(a.x < 40) a.x = 40;
//        if(a.x > field.width - 40) a.x = (field.width - 40);
//        if(a.y < 40) a.y = 40;
//        if(a.y > field.height - 40) a.y = (field.height - 40);
//    }


    public void gameUpdate(){
    Thread gameThread = new Thread(){
        public void run(){
            while(true){
                //execute one time step for the game
//                gameUpdate(a , field);

                //refresh screen
                repaint();

                //give other threads time
                try{
                    Thread.sleep(5);
                }catch(InterruptedException e){
//                    e.printStackTrace();
                }
            }
        }
    };

    gameThread.start();
}



    public static void main(String args[])
    {
        GameMain main = new GameMain();
        main.Game_Start();
        main.gameUpdate();
    }
}

共 (1) 个答案

  1. # 1 楼答案

    问题是多方面的,主要是因为对SwingWorker的实际工作方式缺乏了解

    记住,更多的线程并不意味着更多的工作。线程越多,系统就越难工作。有时候,少就是多;)

    SwingWorker不适合此任务。对于整个应用程序,它最多只允许10名工作人员执行,并且,除非您正确地将更新与事件调度线程同步,否则您将不会从中获得任何好处

    通常更简单的解决方案是使用Swing Timer。这将确保您的更新在EDT内执行,而不会有脏读/写或阻塞EDT的风险

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.LinkedList;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
    
                    PlayField playField = new PlayField(200, 200, Color.DARK_GRAY);
                    RobotModel model = new RobotModel();
                    model.createNewRobot();
    
                    RobotWorld world = new RobotWorld(playField, model);
                    world.start();
    
                    frame.add(world);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class RobotModel {
    
            public static final int MAX = 8;
            public LinkedList<Robot> bots = new LinkedList<Robot>();
    
            public void createNewRobot() {
                Robot temp = new Robot(40, 40, Color.BLUE);
                bots.addFirst(temp);
            }
        }
    
        public class PlayField {
    
            public int width;
            public int height;
            public Color fill_Color;
    
            PlayField(int width, int height, Color fill_Color) {
                this.width = width;
                this.height = height;
                this.fill_Color = fill_Color;
            }
        }
    
        public class RobotWorld extends JPanel {
    
            public RobotModel model;
            private PlayField playField;
    
            private Timer timer;
    
            public RobotWorld(PlayField playField, RobotModel robot_Model) {
                super();
                this.model = robot_Model;
                this.playField = playField;
    
                setBackground(playField.fill_Color);
    
                timer = new Timer(5, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent evt) {
                        Rectangle bounds = new Rectangle(new Point(0, 0), getSize());
                        for (Robot bot : model.bots) {
                            bot.move(bounds);
                        }
                        repaint();
                    }
                });
            }
    
            public void start() {
                timer.start();
            }
    
            public void stop() {
                timer.stop();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return playField == null ? super.getPreferredSize() : new Dimension(playField.width, playField.height);
            }
    
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                for (Robot bot : model.bots) {
                    Graphics2D graphic = (Graphics2D) g.create();
                    bot.paint(graphic);
                    graphic.dispose();
                }
            }
        }
    
        public class Robot {
    
            public int x;
            public int y;
            public Color color;
            public final int speed = 10;
            public int size = 40;
    
            Robot(int x, int y, Color color) {
                this.x = x;
                this.y = y;
                this.color = color;
            }
    
            public void paint(Graphics2D g2d) {
                g2d.setColor(color);
                g2d.fillRect(x, y, size, size);
            }
    
            public void move_90() {
                this.y += speed;
            }
    
            public void move_270() {
                this.y -= speed;
            }
    
            public void move_180() {
                this.x += speed;
            }
    
            public void move_0() {
                this.x += speed;
            }
    
            public void move_45() {
                this.x += speed;
                this.y += speed;
            }
    
            public void move_135() {
                this.x -= speed;
                this.y += speed;
            }
    
            public void move_225() {
                this.x -= speed;
                this.y -= speed;
            }
    
            public void move_315() {
                this.x += speed;
                this.y -= speed;
            }
    
            public void move(Rectangle bounds) {
                Random temp = new Random();
                int rand = temp.nextInt(8);
                switch (rand) {
                    case 1:
                        move_0();
                        break;
                    case 2:
                        move_135();
                        break;
                    case 3:
                        move_180();
                        break;
                    case 4:
                        move_225();
                        break;
                    case 5:
                        move_270();
                        break;
                    case 6:
                        move_315();
                        break;
                    case 7:
                        move_45();
                        break;
                    case 8:
                        move_90();
                        break;
                }
    
                if (x < bounds.x) {
                    x = bounds.x;
                } else if (x + size > bounds.x + bounds.width) {
                    x = bounds.x + bounds.width - size;
                }
                if (y < bounds.y) {
                    y = bounds.y;
                } else if (y + size > bounds.y + bounds.height) {
                    y = bounds.y + bounds.height - size;
                }
            }
    
        }
    }
    

    有关详细信息,请参见How to Use Swing Timers

    如果您下定决心要使用SwingWorker,那么您应该花时间通读Worker Threads and SwingWorker