16. januar 2011 - 01:43Der er
5 kommentarer og 1 løsning
Synkronisering af hoppende bolde
Hej. Jeg er i gang med at lære java og i den forbindelse har jeg et par spørgsmål. Hvorfor virker følgende kode ikke som synchronized? boldene bliver ikke malet over hver gang...
// klasse der laver en bold import java.awt.*;
public class Bold implements Runnable { double x, y, fartx, farty; Graphics g;
public Bold(Graphics g1, int x1, int y1) { g = g1; x = x1; y = y1;
fartx = Math.random(); farty = Math.random(); Thread t = new Thread(this); t.start(); }
public void run() { for (int tid=0; tid<5000; tid++) { synchronized (this) { // Tegn bolden over med hvid på den gamle position g.setColor(Color.WHITE); g.drawOval((int) x, (int) y, 50, 50);
// Opdater positionen med farten x = x + fartx; y = y + farty;
// Tegn bolden med sort på den nye position g.setColor(Color.BLACK); g.drawOval((int) x, (int) y, 50, 50);
// Hvis bolden er uden for det tilladte område skal den // rettes hen mod området if (x < 0) fartx = Math.abs(fartx); if (x > 400) fartx = -Math.abs(fartx); if (y < 0) farty = Math.abs(farty); if (y > 100) farty = -Math.abs(farty);
Andet spørgsmål. Jeg blev desuden nødt til at lave en helt anden klasse der extends JPanel for at kunne male baggrunden på min JFrame hvid hvordan kan det være? De efterfølgende klasser kommer også lige med for en sikkerheds skyld:
import javax.swing.*; import java.awt.*;
public class PanelIndeholdBolde extends JPanel { public void paint(Graphics g){ } }
og
import java.awt.*; import javax.swing.*;
public class FlertraadetGrafik { public static void main(String[] arg) { SwingUtilities.invokeLater(new Runnable(){ public void run(){ FlertraadetGrafik start = new FlertraadetGrafik(); start.åbnPanelOgVin(); } }); }
public void åbnPanelOgVin(){ JFrame f = new JFrame(); f.setSize(400,150); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setBackground(Color.WHITE); f.setVisible(true); f.add(new PanelIndeholdBolde()); Graphics g = f.getGraphics();
new Bold(g, 0, 0); new Bold(g, 50,10); new Bold(g,100,50); new Bold(g,150,90); } }
Håber der er en der har tid til at hjælpe mig lidt .. :)
public class MovingBalls extends JFrame { public MovingBalls() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Moving balls"); getContentPane().setLayout(new BorderLayout()); Ball red = new Ball(200,200,50,Color.RED); Ball green = new Ball(400,200,50,Color.GREEN); Ball blue = new Ball(400,400,50,Color.BLUE); Ball yellow = new Ball(200,400,50,Color.YELLOW); MultiBalls mb = new MultiBalls(600, 600); mb.addBall(red); mb.addBall(green); mb.addBall(blue); mb.addBall(yellow); getContentPane().add(mb); (new BallMover(red, mb)).start(); (new BallMover(green, mb)).start(); (new BallMover(blue, mb)).start(); (new BallMover(yellow, mb)).start(); pack();
} public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame f = new MovingBalls(); f.setVisible(true); } }); } }
class MultiBalls extends JPanel { private List<Ball> balls; public MultiBalls(int w, int h) { setPreferredSize(new Dimension(w, h)); balls = new ArrayList<Ball>(); } public void addBall(Ball b) { balls.add(b); } @Override public void paint(Graphics g) { g.setColor(Color.WHITE); g.fillRect(0, 0,getWidth(), getHeight()); for(Ball b : balls) { g.setColor(b.getC()); g.fillOval(b.getX() - b.getR(), b.getY() - b.getR(), 2*b.getR(), 2*b.getR()); } } }
class Ball { private volatile int x; private volatile int y; private int r; private Color c; public Ball(int x, int y, int r, Color c) { this.x = x; this.y = y; this.r = r; this.c = c; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getR() { return r; } public void setR(int r) { this.r = r; } public Color getC() { return c; } public void setC(Color c) { this.c = c; } }
class BallMover extends Thread { private Random rng = new Random(getId() + System.currentTimeMillis()); private Ball b; private JPanel p; public BallMover(Ball b, JPanel p) { this.b = b; this.p = p; } @Override public void run() { for(;;) { try { Thread.sleep(250); } catch (InterruptedException e) { e.printStackTrace(); } int x = b.getX() + rng.nextInt(21) - 10; int y = b.getY() + rng.nextInt(21) - 10; x = Math.max(x, b.getR()); x = Math.min(x, p.getWidth() - b.getR()); y = Math.max(y, b.getR()); y = Math.min(y, p.getHeight() - b.getR()); b.setX(x); b.setY(y); EventQueue.invokeLater(new Runnable() { public void run() { p.repaint(); } }); } } }
Jeg kalder getContentPane() af gammel vane, fordi man ikke kunne sætte de ting direkte på JFrame i gamle dage. Det blev tilføjet i Java 1.5 i 2004 og jeg er et vane dyr.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.