I have a problem. I have to make an app, which would contain n
number of Threads which would move the balls around the circle (with different velocities). Now I've got my Thread extending JComponent
and implementing Runnable
. Everything works just fine, except the run()
method doesn't seem to call paintComponent. How can I fix that? The code:
Thread (Kulka.java):
package internet;
import internet.RotateWheel.TestPane;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import static java.lang.Thread.sleep;
import javax.swing.JComponent;
import javax.swing.JPanel;
public class Kulka extends JComponent implements Runnable{
int x, y;
float predkosc;
float obecna_predkosc = 0f;
TestPane parent;
public Kulka(TestPane parent, int x, int y, float v){
this.predkosc = v;
this.x = x;
this.y = y;
this.parent = parent;
}
public Point getPointOnCircle(float degress, float radius) {
int x = Math.round(getWidth() / 2);
int y = Math.round(getHeight() / 2);
double rads = Math.toRadians(degress - 90);
int xPosy = Math.round((float) (x + Math.cos(rads) * radius));
int yPosy = Math.round((float) (y + Math.sin(rads) * radius));
return new Point(xPosy, yPosy);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
int diameter = Math.min(getWidth(), getHeight());
int x = (getWidth() - diameter) / 2;
int y = (getHeight() - diameter) / 2;
g2.setColor(Color.RED);
float innerDiameter = 20;
System.out.println("Diameter: " + diameter);
Point p = getPointOnCircle(obecna_predkosc, (diameter / 2f) - (innerDiameter / 2));
g2.fillOval(x + p.x - (int) (innerDiameter / 2), y + p.y - (int) (innerDiameter / 2), (int) innerDiameter, (int) innerDiameter);
}
public synchronized void run(){
while (true){
//System.out.println(obecna_predkosc);
try {
System.out.println(predkosc);
this.repaint();
sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
This is what happens:
Class with Frame and Panel:
package internet;
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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class RotateWheel {
public static void main(String[] args) {
new RotateWheel();
}
public RotateWheel() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
LinkedList<Thread> kulki = new LinkedList<Thread>();
int n = 5;
private float degrees = 0;
Random random = new Random();
public TestPane() {
/*Timer timer = new Timer(60, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
degrees += 1f;
repaint();
}
});
timer.start();*/
}
public Point getPointOnCircle(float degress, float radius) {
int x = Math.round(getWidth() / 2);
int y = Math.round(getHeight() / 2);
double rads = Math.toRadians(degress - 90);
int xPosy = Math.round((float) (x + Math.cos(rads) * radius));
int yPosy = Math.round((float) (y + Math.sin(rads) * radius));
return new Point(xPosy, yPosy);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int diameter = Math.min(getWidth(), getHeight());
int x = (getWidth() - diameter) / 2;
int y = (getHeight() - diameter) / 2;
g2d.setColor(Color.GREEN);
g2d.drawOval(x, y, diameter, diameter);
g2d.setColor(Color.RED);
float innerDiameter = 20;
if (kulki.isEmpty()){
for (int i=0; i<n; i++){
Point p = getPointOnCircle(degrees, (diameter / 2f) - (innerDiameter / 2));
Kulka kulka = new Kulka(this, p.x, p.y, random.nextFloat() * (5f - 2f) + 1f);
Thread watek = new Thread(kulka);
kulki.add(watek);
}
for (Thread t: kulki){
t.start();
}
}
System.out.println("No elo XD");
g2d.dispose();
}
}
}