Results 1 to 4 of 4
  1. #1
    Bronsonboy is offline Member
    Join Date
    Jun 2012
    Location
    Illinois
    Posts
    4
    Rep Power
    0

    Default Multithreaded Screensaver Project not Building Properly

    I have written a couple of classes designed to produce a "screensaver" of bouncing boxes. Unfortunately, it is hitting multiple runtime exceptions that seem to be related to threading (something I am not very experienced with resolving), and I would greatly appreciate some assistance from a more experienced programmer. I have included the full text of my files here for copy-pasting (I created the "smallest working sample" when looking to debug myself).

    TestScreenSaver.java (runnable test class):
    Java Code:
    package screensaver;
    
    import javax.swing.JFrame;
    
    class TestScreenSaver extends JFrame {
        ScreenSaver screensaver;
        Bouncer[] bouncers = new Bouncer[6];
        
        public TestScreenSaver() {
            super("ScreenSaver");
            setSize(800,600);
            screensaver = new ScreenSaver(bouncers);
            add(screensaver);
            setVisible(true);
            screensaver.run();
        }
        
        public static void main(String[] args) {
            TestScreenSaver tss = new TestScreenSaver();
        }
    }
    ScreenSaver.java (the canvas the screensaver will exist upon):
    Java Code:
    package screensaver;
    
    import java.awt.Canvas;
    import java.awt.Graphics;
    
    public class ScreenSaver extends Canvas implements Runnable {
    
        private static long defaultRefreshRate = 100;
        private long lastRefresh;
        private Bouncer mainbox;
        private Thread mainThread;
        private long refreshRate;
    
        public ScreenSaver(Bouncer[] bouncers) {
            refreshRate = defaultRefreshRate;
            mainbox = new Bouncer(bouncers);
            mainThread = new Thread(mainbox);
        }
    
        @Override
        public void run() {
            mainbox.setRect(0, 0, this.getWidth(), this.getHeight());
            mainThread.start();
            while (true) {
                lastRefresh = System.currentTimeMillis();
                repaint();
                try {
                    Thread.sleep(refreshRate
                            - (System.currentTimeMillis() - lastRefresh));
                } catch (InterruptedException ex) {
                    System.out.println("Could not sleep.");
                }
            }
        }
    
        @Override
        public void paint(Graphics g) {
            paint(g, mainbox);
        }
    
        private void paint(Graphics g, Bouncer bouncer) {
            g.setColor(bouncer.getColor());
            g.fillRect((int) bouncer.getX(), (int) bouncer.getY(),
                    (int) bouncer.getWidth(), (int) bouncer.getHeight());
            if (bouncer.getBouncers() != null) {
                for (Bouncer b : bouncer.getBouncers()) {
                    paint(g, b);
                }
            }
        }
    }
    Bouncer.java (the individual bouncing boxes, which can stack inside each other – at least in theory, but it hasn't yet been tested):
    Java Code:
    package screensaver;
    
    import java.awt.Color;
    import java.awt.Rectangle;
    import myMods.Random2;
    
    class Bouncer extends Rectangle implements Runnable {
    
        private Bouncer container = null;
        private Bouncer[] bouncers = null;
        private Color color;
        private static Color[] colors = {Color.BLUE, Color.CYAN, Color.GREEN,
            Color.MAGENTA, Color.PINK, Color.RED, Color.YELLOW};
        private Thread[] bouncerThreads = null;
        private int defaultHeight = 50;
        private int defaultWidth = 100;
        private int defaultXSpeed = 1;
        private int defaultYSpeed = 1;
        private long lastMoveTime;
        private int xSpeed;
        private int ySpeed;
    
        public Bouncer() {
            this.xSpeed = defaultXSpeed;
            this.ySpeed = defaultYSpeed;
            this.height = defaultHeight;
            this.width = defaultWidth;
            if (container != null) {
                randomize();
            }
        }
    
        public Bouncer(Bouncer[] bouncers) {
            this();
            this.bouncers = bouncers;
            this.bouncerThreads = new Thread[bouncers.length];
            for (int i = 0; i < bouncers.length; i++) {
                bouncerThreads[i] = new Thread(this.bouncers[i]);
            }
            for (Bouncer bouncer : this.bouncers) {
                bouncer = new Bouncer();
                bouncer.setContainer(this);
            }
        }
    
        public boolean detectOverlap(Bouncer bouncer) {
            for (Bouncer b1 : bouncer.getContainer().getBouncers()) {
                if (bouncer.intersects(b1)) {
                    return true;
                }
            }
            return false;
        }
    
        public Bouncer[] getBouncers() {
            return bouncers;
        }
    
        public Color getColor() {
            return color;
        }
    
        public Bouncer getContainer() {
            return container;
        }
    
        public long getLastMoveTime() {
            return lastMoveTime;
        }
    
        public int getXSpeed() {
            return xSpeed;
        }
    
        public int getYSpeed() {
            return ySpeed;
        }
    
        public void randomize() {
            System.out.println(container);
            this.x = Random2.randInt(
                    (int) container.getWidth() - this.width + 1) - 1;
            this.y = Random2.randInt(
                    (int) container.getHeight() - this.height + 1) - 1;
            this.color = this.colors[Random2.randInt(colors.length) - 1];
        }
    
        @Override
        public void run() {
            if (this.bouncers != null) {
                for (Bouncer bouncer : bouncers) {
                    while (detectOverlap(bouncer)) {
                        bouncer.randomize();
                    }
                }
                for (Thread bouncerThread : bouncerThreads) {
                    bouncerThread.start();
                }
            }
            if (this.container != null) {
                this.setLastMoveTime(System.currentTimeMillis());
                while (true) {
                    this.translate(xSpeed, ySpeed);
                    try {
                        Thread.sleep(1000
                                - (System.currentTimeMillis() - this.lastMoveTime));
                    } catch (InterruptedException ex) {
                        System.out.println("Could not sleep.");
                    }
                }
            }
        }
    
        public void setBouncers(Bouncer[] bouncers) {
            this.bouncers = bouncers;
        }
    
        public void setColor(Color color) {
            this.color = color;
        }
    
        public void setContainer(Bouncer container) {
            this.container = container;
        }
    
        public void setLastMoveTime(long time) {
            lastMoveTime = time;
        }
    
        public void setXSpeed(int xSpeed) {
            this.xSpeed = xSpeed;
        }
    
        public void setYSpeed(int ySpeed) {
            this.ySpeed = ySpeed;
        }
    
        public void slowDownX() {
            this.xSpeed -= this.xSpeed / Math.abs(this.xSpeed);
        }
    
        public void slowDownY() {
            this.ySpeed -= this.ySpeed / Math.abs(this.ySpeed);
        }
    
        public void speedUpX() {
            this.xSpeed += this.xSpeed / Math.abs(this.xSpeed);
        }
    
        public void speedUpY() {
            this.ySpeed += this.ySpeed / Math.abs(this.ySpeed);
        }
    
        @Override
        public void translate(int dx, int dy) {
            int i = 0;
            int j = 0;
            while (i < Math.abs(dx) || j < dy) {
                if (i < Math.abs(dx)) {
                    super.translate(dx / Math.abs(dx), 0);
                    for (Bouncer b : container.getBouncers()) {
                        if (this.intersects(b)) {
                            b.translate(dx / Math.abs(dx), 0);
                            this.slowDownX();
                            b.speedUpX();
                        }
                    }
                    if (container != null) {
                        if (!this.intersection(container).equals(this)) {
                            System.out.println("Hit wall");
                            this.translate(-(dx / Math.abs(dx)), 0);
                        }
                    }
                }
                if (j < Math.abs(dy)) {
                    super.translate(0, dy / Math.abs(dy));
                    for (Bouncer b : container.getBouncers()) {
                        if (this.intersects(b)) {
                            b.translate(0, dy / Math.abs(dy));
                            this.slowDownY();
                            b.speedUpY();
                        }
                    }
                    if (container != null) {
                        if (!this.intersection(container).equals(this)) {
                            System.out.println("Hit wall");
                            this.translate(0, -(dy / Math.abs(dy)));
                        }
                    }
                }
            }
            this.setLastMoveTime(System.currentTimeMillis());
        }
    }
    Random2.java (a class I created to keep random generation neat):
    Java Code:
    package myMods;
    
    import java.util.Random;
    
    public abstract class Random2 {
        private static Random generator = new Random();
        
        public static int randInt(int max) {
            int randInt = generator.nextInt(max);
            return randInt;
        }
        
        public static boolean randBool() {
            int randInt = generator.nextInt(2);
            boolean randBool;
            if (randInt == 1) {
                randBool = false;
            } else {
                randBool = true;
            }
            return randBool;
        }
    }

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,188
    Rep Power
    19

    Default Re: Multithreaded Screensaver Project not Building Properly

    Ever heard of Swing's single threaded rule? If not, then google it.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  3. #3
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,188
    Rep Power
    19

    Default Re: Multithreaded Screensaver Project not Building Properly

    Also, don't mix AWT and Swing components. Don't use Thread.sleep(...) for timing -- use a javax.swing.Timer. And assigning a new object to the local reference inside an enhanced-for loop while iterating over an array doesn't assign anything to the array element.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  4. #4
    Bronsonboy is offline Member
    Join Date
    Jun 2012
    Location
    Illinois
    Posts
    4
    Rep Power
    0

    Default Re: Multithreaded Screensaver Project not Building Properly

    Thanks for the pointers. A little frustrating, but it is better for me to make these mistakes now, rather than when I'm working on something bigger later down the road.

    Does AWT suffer from the same inability to be multi-threaded?
    Last edited by Bronsonboy; 07-30-2012 at 08:44 PM.

Similar Threads

  1. Building JOGL 2.0 lib properly
    By JavaNoob84 in forum New To Java
    Replies: 11
    Last Post: 12-21-2012, 09:26 AM
  2. How to building a project with a phone MIDP?
    By HoangNgoc in forum CLDC and MIDP
    Replies: 0
    Last Post: 12-22-2010, 04:32 AM
  3. Building EJB project with dependency
    By caseta in forum Eclipse
    Replies: 0
    Last Post: 08-09-2010, 05:38 PM
  4. assignement change the java screensaver
    By anotsu in forum New To Java
    Replies: 2
    Last Post: 03-07-2008, 12:28 AM
  5. Building A Java Project In Eclipse
    By JavaForums in forum Eclipse
    Replies: 0
    Last Post: 05-22-2007, 09:34 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •