Note that there are some explanatory texts on larger screens.

plurals
  1. POJava Multithread
    text
    copied!<p>After making changes based on user suggestions I have taken the following code a few steps further by introducing single/double click recognition. Why are the balls being created in the top left corner and not where the mouse is clicked?</p> <h3>BouncingBalls.java</h3> <pre class="lang-java prettyprint-override"><code>import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class BouncingBalls extends JPanel implements MouseListener { protected List&lt;RandomBall&gt; randomBalls = new ArrayList&lt;RandomBall&gt;(20); protected List&lt;VerticalBall&gt; verticalBalls = new ArrayList&lt;VerticalBall&gt;(20); private Container container; private DrawCanvas canvas; private Boolean doubleClick = false; private final Integer waitTime = (Integer) Toolkit.getDefaultToolkit() .getDesktopProperty("awt.multiClickInterval"); private static int canvasWidth = 500; private static int canvasHeight = 500; public static final int UPDATE_RATE = 30; int count = 0; public static int random(int maxRange) { return (int) Math.round((Math.random() * maxRange)); } public BouncingBalls(int width, int height) { canvasWidth = width; canvasHeight = height; container = new Container(); canvas = new DrawCanvas(); this.setLayout(new BorderLayout()); this.add(canvas, BorderLayout.CENTER); this.addMouseListener(this); start(); } public void start() { Thread t = new Thread() { public void run() { while (true) { update(); repaint(); try { Thread.sleep(1000 / UPDATE_RATE); } catch (InterruptedException e) { } } } }; t.start(); } public void update() { for (RandomBall ball : randomBalls) { ball.ballBounce(container); } for (VerticalBall ball : verticalBalls) { ball.verticalBounce(container); } } class DrawCanvas extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); container.draw(g); for (RandomBall ball : randomBalls) { ball.draw(g); } for (VerticalBall ball : verticalBalls) { ball.draw(g); } } public Dimension getPreferredSize() { return (new Dimension(canvasWidth, canvasHeight)); } } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame f = new JFrame("Stack Answer 2"); f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); f.setContentPane(new BouncingBalls(canvasHeight, canvasWidth)); f.pack(); f.setVisible(true); } }); } @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { if (e.getClickCount() &gt;= 2) { doubleClick = true; verticalBalls.add(new VerticalBall(getX(), getY(), canvasWidth, canvasHeight)); System.out.println("double click"); } else { Timer timer = new Timer(waitTime, new ActionListener() { public void actionPerformed(ActionEvent e) { if (doubleClick) { /* we are the first click of a double click */ doubleClick = false; } else { count++; randomBalls.add(new RandomBall(getX(), getY(), canvasWidth, canvasHeight)); /* the second click never happened */ System.out.println("single click"); } } }); timer.setRepeats(false); timer.start(); } } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } } </code></pre> <h3>RandomBall.java</h3> <pre class="lang-java prettyprint-override"><code>import java.awt.Color; import java.awt.Graphics; public class RandomBall { public static int random(int maxRange) { return (int) Math.round((Math.random() * maxRange)); } private int x; private int y; private int canvasWidth = 500; private int canvasHeight = 500; private boolean leftRight; private boolean upDown; private int deltaX; private int deltaY; private int radius = 20; private int red = random(255); private int green = random(255); private int blue = random(255); RandomBall(int x, int y, int width, int height) { this(x, y, width, height, false, false); } RandomBall(int x, int y, int width, int height, boolean leftRight, boolean upDown) { this.x = x; this.y = y; this.canvasWidth = width; this.canvasHeight = height; this.leftRight = leftRight; this.upDown = upDown; updateDelta(); } public void draw(Graphics g) { g.setColor(new Color(red, green, blue)); g.fillOval((int) (x - radius), (int) (y - radius), (int) (2 * radius), (int) (2 * radius)); } private void updateDelta() { final int minimumMovement = 5; final int maxExtra = 10; deltaY = minimumMovement + (int) (Math.random() * maxExtra); deltaX = minimumMovement + (int) (Math.random() * maxExtra); } public void ballBounce(Container container) { // controls horizontal ball motion if (leftRight) { x += deltaX; if (x &gt;= getWidth()) { leftRight = false; updateDelta(); } } else { x += -deltaX; if (x &lt;= 0) { leftRight = true; updateDelta(); } } // controls vertical ball motion if (upDown) { y += deltaY; if (y &gt;= getHeight()) { upDown = false; updateDelta(); } } else { y += -deltaY; if (y &lt;= 0) { upDown = true; updateDelta(); } } } public void verticalBounce(Container container) { // controls vertical ball motion if (upDown) { y += deltaY; if (y &gt;= getHeight()) { upDown = false; updateDelta(); } } else { y += -deltaY; if (y &lt;= 0) { upDown = true; updateDelta(); } } } public int getX() { return x; } public int getY() { return y; } public int getWidth() { return canvasWidth; } public int getHeight() { return canvasHeight; } } </code></pre> <h3>VerticalBall.java</h3> <pre class="lang-java prettyprint-override"><code>import java.awt.Color; import java.awt.Graphics; public class VerticalBall { public static int random(int maxRange) { return (int) Math.round((Math.random() * maxRange)); } private int x; private int y; private int canvasWidth = 500; private int canvasHeight = 500; private boolean upDown; private int deltaY; private int radius = 20; private int red = random(255); private int green = random(255); private int blue = random(255); VerticalBall(int x, int y, int width, int height) { this(x, y, width, height, false); } VerticalBall(int x, int y, int width, int height, boolean upDown) { this.x = x; this.y = y; this.canvasWidth = width; this.canvasHeight = height; this.upDown = upDown; updateDelta(); } public void draw(Graphics g) { g.setColor(new Color(red, green, blue)); g.fillOval((int) (x - radius), (int) (y - radius), (int) (2 * radius), (int) (2 * radius)); } private void updateDelta() { final int minimumMovement = 5; final int maxExtra = 10; deltaY = minimumMovement + (int) (Math.random() * maxExtra); } public void verticalBounce(Container container) { // controls vertical ball motion if (upDown) { y += deltaY; if (y &gt;= getHeight()) { upDown = false; updateDelta(); } } else { y += -deltaY; if (y &lt;= 0) { upDown = true; updateDelta(); } } } public int getX() { return x; } public int getY() { return y; } public int getWidth() { return canvasWidth; } public int getHeight() { return canvasHeight; } } </code></pre> <h3>Container.java</h3> <pre class="lang-java prettyprint-override"><code>import java.awt.Color; import java.awt.Graphics; public class Container { private static final int HEIGHT = 500; private static final int WIDTH = 500; private static final Color COLOR = Color.WHITE; public void draw(Graphics g) { g.setColor(COLOR); g.fillRect(0, 0, WIDTH, HEIGHT); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload