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.