Home > Software design >  Java Thread Swing
Java Thread Swing

Time:11-08

Application class

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;

public class Application extends JFrame {

    public Circle c1,c2,c3;  
    
    public Application() {
        c1 =new Circle(100,100,2,2,new int[] {100,100,150,150},Color.blue);  
        c2 =new Circle(150,150,-2,0,new int[] {50,150,150,150},Color.red);
        c3 =new Circle(50,150,2,-2,new int[] {100,10,150,150},Color.green);

        setSize(1000,1000); 
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void paint(Graphics g) {
        super.paint(g);
        
        g.setColor(c1.getColor());
        g.fillOval(c1.getX(), c1.getY(), 10, 10);
        g.setColor(c2.getColor());
        g.fillOval(c2.getX(), c2.getY(), 10, 10);
        g.setColor(c3.getColor());
        g.fillOval(c3.getX(), c3.getY(), 10, 10);
    }
    
    public static void main(String[] args) {
        Application a = new Application();      
        new Application();           
    }
}

Circle Class

import java.awt.Color;
    
public class Circle extends Thread {
    private int x,y;
    private int xs,ys;
        
    private Color color;
    private int[] boundries;
    
    public  Circle(int x ,int y ,int xs,int ys,int[]boundries,Color color) {
        this.x=x;
        this.y=y;
        this.xs=xs;
        this.ys=ys;
        this.boundries=boundries;  //kordinatlar ve buyukluk 
        this.color=color;
    }

    @Override
    public void run() {
        while(true) {
            move();
        }
    }

    public void move() {
        UpdateSpeedInformation();
        
        this.x  =this.xs;  //xs artış kordinat hızı
        this.y  =this.ys;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public void UpdateSpeedInformation() {
        if(x<boundries[0] && x>boundries[2]) {  //eger x 0.indexten kücük 2.indexten büyükse 
            this.xs  *= -1;
            this.ys  *= -1;
            //kontrol operatörü bu      
        }
        else if(y<boundries[1] && y>boundries[3]) {
            this.xs=xs;
            this.ys=ys; //..
        }
    }
        
    public int getX() {
        return x ;
    }
    
    public Color getColor() {
        return color;
    }

    public int getY() {
        return y;   
    }
}

These are the classes this three circle have to move but I dont know where I should place to Thread starters ask me if you need more information thanks

These are the classes this three circle have to move but I dont know where I should place to Thread starters ask me if you need more information thanks

These are the classes this three circle have to move but I dont know where I should place to Thread starters ask me if you need more information thanks

CodePudding user response:

Swing is not thread safe. This means that you should not be updating the UI or updating any state the UI relies on from outside the context of the Event Dispatching Thread.

Swing is single threaded. This means that you should not be performing any long running or blocking operations from within the context of the Event Dispatching Thread.

See Concurrency in Swing for more details and How to Use Swing Timers for a common solution.

I dont know where I should place to Thread starters

There's no reliable method for determining when a component is made visible on the screen (at least in a meaningful manner). You could look at WindowListener and ComponentListener but I've found them to overly reliable in this context.

One trick I do tend to use is overriding add/removeNotify, while this won't tell you when the component is made visible on the screen, it does give you a good indicator of when the component might come into a "usable" state.

The following makes use of a simple Swing Timer and fixes your movement logic (the circle can't be simultaneously less then and greater then the bounding box)

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private List<Circle> circles = new ArrayList<>(5);        
        private Timer timer;

        public TestPane() {
            circles.add(new Circle(100, 100, 2, 2, new int[]{100, 100, 150, 150}, Color.blue));
            circles.add(new Circle(150, 150, -2, 0, new int[]{50, 150, 150, 150}, Color.red));
            circles.add(new Circle(50, 150, 2, -2, new int[]{100, 10, 150, 150}, Color.green));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }

        @Override
        public void addNotify() {
            super.addNotify();
            if (timer != null) {
                timer.stop();
            }
            timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    for (Circle circle : circles) {
                        circle.tick();
                    }
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public void removeNotify() {
            super.removeNotify();
            if (timer != null) {
                timer.stop();
            }
            timer = null;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (Circle circle : circles) {
                g2d.setColor(circle.getColor());
                g2d.fillOval(circle.getX(), circle.getY(), 10, 10);
            }
            g2d.dispose();
        }

    }

    public class Circle {
        private int x, y;
        private int xs, ys;

        private Color color;
        private int[] boundries;

        public Circle(int x, int y, int xs, int ys, int[] boundries, Color color) {
            this.x = x;
            this.y = y;
            this.xs = xs;
            this.ys = ys;
            this.boundries = boundries;  //kordinatlar ve buyukluk 
            this.color = color;
        }

        public void tick() {
            move();
        }

        protected void move() {
            updateSpeed();

            this.x  = this.xs;  //xs artış kordinat hızı
            this.y  = this.ys;
        }

        protected void updateSpeed() {
            if (x <= boundries[0]) {
                xs *= -1;
                x = boundries[0];
            } else if (x >= boundries[2]) {
                xs *= -1;
                x = boundries[2];
            }
            if (y <= boundries[1]) {
                ys *= -1;
                y = boundries[1];
            } else if (y >= boundries[3]) {
                ys *= -1;
                y = boundries[2];
            }
        }

        public int getX() {
            return x;
        }

        public Color getColor() {
            return color;
        }

        public int getY() {
            return y;
        }
    }
}

You could then extend on this by adding start and stop methods to the TestPane and use a WindowListener to further trigger actions based on the window state.

  • Related