JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

What would this method be used for?

It tests for two Shapes overlapping. They can be rectanges, circles, polygons or completely arbitrary Shapes. If you have a Circle then that's the shape you should be using, not its bounding rectangle.

in the program I took that code from the moving objects ("Sprites") are actually transparent GIF Images. The Shape is a compound thing I hand-craft to fit reasonably round the visible part of the image so I can detect collisions between the visible parts of two Images.

I agree with AN's advice to get something simple working first before moving on to harder stuff. BUT you should accept that the simple stuff is just a learning exercise and not the base for a final implementation. Before you ge too far you have to take what you have learned, set aside the learning code, and think through a proper design for the real thing. Just adding complexity to an arbitrary simple case is a formula for chaos!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Is it all good? in terms of coding practice? not sure

One thing to watch out for is the date when the video was made. I still see a lot of web sites showing code from before Java 1.5, and even more that have not been updated for the huge changes in Java 8. Oracle's tutorials are the best for being up to date.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Have a look at java.awt.geom.Area - it implements Shape but represents a closed shape at a particular position. It has all kinds of useful methods that Shape doesn't have, including area.intersects(other area)
Here's code I used a while back to do an exact check on collision between two arbitrary Shapes. It gets the Area from each shape, translates them to the correct x.y position, and intersects them. If the intersection is empty then they do not overlap.

    private boolean exactCollision(Sprite s1, Sprite s2) {
        Area a1 = new Area(s1.getShape());
        a1.transform(AffineTransform.getTranslateInstance(s1.getX(), s1.getY()));

        Area a2 = new Area(s2.getShape());
        a2.transform(AffineTransform.getTranslateInstance(s2.getX(), s2.getY()));

        a1.intersect(a2);
        return !a1.isEmpty();
    }
AssertNull commented: Good link +8
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, don’t reinvent the wheel.
Re bouncing off sides:
In practice you do need to consider the direction of motion (a) because that's simpler and (b) otherwize you get artifacts from the non-continuous simulation (ball overlaps rect at tick n, you reverse direction, but at tick n+1 it may not yet have cleared the rect but you don't want to treat that as another bounce).

Re bouncing off a corner - the imaginary wall needs to be normal to the line joining the corner to the circle's center I believe.

If you already have working code for 2 balls bouncing off each other then you can replace the corner by a very small very heavy ball and use the existing code.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You can check for the two Shapes (ellipse and rectangle) intersecting. Which side is then just a tedious testing of the x and y coordinates.
Bouncing off a side of a rectangle (assuming it;s horiontal/vertical) is trivial (1), but bouncing off a corner is a different question. If you get a decent solution then please share it.

(1) if circle.centre.y < top of rectangle && > bottom of rectangle and dx > 0 then it was the left side. Etc

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

It looks like you have been experimenting with a variety of layout mangers!
Firstly - have you seen the Oracle tutorials - they are excellent. They start here: https://docs.oracle.com/javase/tutorial/uiswing/layout/using.html

In my experience they are all too simpistic for anything but the simplest of requirements except GridBagLayout and SpringLayout. SpringLayout was designed specifically to support drag'n'drop GUI builders and is a pain to work with at the code level.
GridBagLayout is the one I always go to when I have an interesting design, especially if I want it to behave in a particular way when porting across OSs or when the window is resized.

Of course you can nest JPanels with a box layout here and a flow or grid layout there, but controlling that on a resize is a nightmare. I suggest you jump straight to GridBag. Yes, there's a bit of a learning curve, but learn it once and you're set up for life!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, in my code dx and dy are the speed in the x and y directions.
If things stop moving that may be a result of using int calculations rather than doubles? (see previous posts)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

he nice thing about circles is that it's extremely easy to determine if/when they collide with each other ... Collisions at an angle are much more involved.

Not too bad - the first 7 lines of the code I posted, or lines 30-32 of OP's, do exactly that for the general case.
I agree about the importance of separating the code and the relevance of OO as a way to do it. I tried to steer OP in that direction in an earlier thread.

A couple of years ago I did a demo verion of bouncing balls (etc etc) for a tutorial series, using a lot of subclassing for different kinds of sprites and collisions. More recently I did a new version using pluggable behaviours and a single Sprite class, and I think that scales with complexity a lot better. I'm happy to share if anyone is interested.

even in a 2D world with a few balls and a few walls, it can potentially get quite computationally intensive

I was surprised at how well this stuff can run, even on an unexceptional machine. I was bouncing >50 balls off the sides and each other at 120 updates per sec for the model and 60 fps for the repaints and it ran perfectly with <30% CPU on a 2009 iMac.

ps: I forgot to credit the source for the bounce algorithm. I found it here

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

No time for a proper answer now, but here's some code I use that I modified from something on the web that bounces balls a and b that have position x,y and velocity dx,dy. I gives bounces that look very realistic to me. It's very similar to your code,

        double ra = a.width / 2; // radius
        double rb = b.width / 2; // radius
        double radiiSquared = (ra + rb) * (ra + rb);  // square sum of radii
        double xDist = (a.x + ra) - (b.x + rb);
        double yDist = (a.y + ra) - (b.y + rb);
        double distSquared = xDist * xDist + yDist * yDist;
        if (distSquared > radiiSquared) return false; // balls don't touch

        // circles touch (or overlap) so they bounce off each other...
        double xVelocity = b.dx - a.dx;
        double yVelocity = b.dy - a.dy;
        double dotProduct = xDist * xVelocity + yDist * yVelocity;
        if (dotProduct > 0) { // moving towards each other
            double collisionScale = dotProduct / distSquared;
            double xCollision = xDist * collisionScale;
            double yCollision = yDist * collisionScale;
            //The Collision vector is the speed difference projected on the Dist vector,
            //thus it is the component of the speed difference needed for the collision.
            double combinedMass = a.width * a.width + b.width * b.width; // mass porp. to area
            double collisionWeightA = 2* b.width * b.width / combinedMass;
            double collisionWeightB = 2* a.width * a.width / combinedMass;
            a.dx += collisionWeightA * xCollision;
            a.dy += collisionWeightA * yCollision; …
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The "first version" is from your "I've changed this..." post - where you have one class for the game JPanel and another class (extends JFrame) for the main window, For me that's good design when each class represents one thing fully.

super. in constructors:
Netbeans is designed to support huge mission-critical projects and so warns of all kinds of code that, in theory, could cause bugs. Calling a method in a constructor, when the method could have been overridden and the override method assumed construction is complete can cause bugs. Will this happen in a one-person small project? Highly unlikely.
For now you can safely ignore that message - just keep your constructors small and simple, and be aware of what order things are being done in.

As for your other 3 issues - without seeiing the code there's nothing I can do.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Leaking in constructor...

The language spec only guarantees that the new object will be in a complete and consistent state after the constructor has finished.
When you add the key listener you pass a reference to you current object, so it's immediately possible for another class to call methods in your object, even though its constructor has not finished.
It's one of those theoretical warnings that rarely cause problems in practice, but the simplest way to keep safe in a case like this one is to finish creating the window and make it visible before adding any listeners.

ps I greatly preferred the first version. It shouldn't be the responsibility of a JPanel to create its own parent frame like in v2.
pps you don’t need all those supers when calling methods inherited from a superclass

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

first time the renderer gets called i get a null

You create a BallGame before you create a GameThread, but BallGame creates the window and makes it visible, which causes a call to Renderer's paintComponent, which tries to call the GameThread, which doesn't exist yet.
Don't try to fix this before you fix the structure, it;s just an artifact of the two JPanels mistake.

You may find this code useful - it's taken from a sample program I wrote to help teach sprite-based animation - but the following excerpt shows one way for the model view and controller to fit together and split up the responsibilities between them (ignore the Sprite references for the moment).

public class Animation2 {
    // Outline class structure demo for multi-sprite animation

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Animation2::new);
    }

    // shared constants
    final AnimationModel model;
    final AnimationView view;
    final int TIMER_MSEC = 16; // mSec per clock tick

    Animation2() {
        model = new AnimationModel(600, 400);

        view = new AnimationView(model);
        view.setPreferredSize(new Dimension(model.width, model.height));

        new MainWindow(this);

        new ScheduledThreadPoolExecutor(1).
                scheduleAtFixedRate(this::updateAnimation, 0, TIMER_MSEC, MILLISECONDS);
    }

    void updateAnimation() {
        model.updateSimulation();
        view.repaint();
    }

    void close() { // tidies up and quits application
        // do any cleanup etc here
        System.exit(0);
    }

}

class AnimationModel {

    final List<Sprite> sprites = new ArrayList<>();
    final int width, height;

    AnimationModel(int width, int height) {
        this.width = width;
        this.height = height;
        sprites.add(new Sprite(this).velocity(2, 1));
        sprites.add(new BouncingSprite(this).
                color(green).size(80, 80).at(0, 250).velocity(7, -10));
        sprites.add(new BouncingHeavySprite(this).
                color(RED).size(60, 60).at(0, 0).velocity(4, 0));
    }

    void updateSimulation() {
        for (Sprite …
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I'm not sure, but my best guess is...
you add gamePainter to the JFrame after makingthe JFrame visible and don't pack() or invalidate() or anything else, so gamePainter may well be invisible, or maybe 0 pixels by 0 pixels. So when you call repaint for gamePainter Swing decides there is nothing visible to repaint, so it never calls its paintComponent.

number 2: you have two JPanels, only one of which is added to the JFrame, both of which contain Swing paint code. They are also tighly coupled so it's anybody's guess as to what is really going on and what will or won't be painted where.

My advice would be to fix that structural problem, and waste no time trying to debug or fix the current code. You need exactly one JPanel to display your game, and that should contain all the graphics drawing code. (Except later, when you have a Ball class, then maybe the JPanel will delegate drawing Balls to the Balls class.) And add it to the JFrame before pack() and setVisible

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

ps: I don't think ypur class structure is helping here... your GameThread class
1) Isn't a thread
2) Extends JPanel, but is never visible
3) Has lots of painting code that belongs in Renderer

It looks like maybe you have created classes to answer "where can I put this code?" rather than "what are the objects and their responsibilities needed for this application?"

For a Java Swing game the answer is almost always some kind of MVC as in (just an example):

class Model - represents the state of the game, update method moves it on one time unit.
class Renderer - extends JPanel, paintComponent displays the current state of the Model
class WIndow - extends JFrame, contains a Renderer plus buttons & controls as required, responds to keyboard.
class Controller - ties it all together, creates Window, Model and Renderer, starts a timer to update Model and repaint Renderer.

If you do that kind of design first then the resulting code will be much cleaner.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Like he said... plus specifically: do you get "in here" printed 30 times per sec?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Interesting link - one man's opinion even if it's not so mainstream.
What he says about java,util.Timer and javax.swing.Timer is basically right, which is why the ScheduledThreadPoolExecutor is the recomended timing mechanism. It's just as easy as the others to use but gives you as much control over the threading as you want.

eg to run a method updateSimulation() immediately then every 30 mSec on a single thread:

new ScheduledThreadPoolExecutor(1).
                scheduleAtFixedRate(this::updateSimulation, 
                0, 30, MILLISECONDS);

If you really try with your own loop and thread management then maybe eventually you could make it as solid, safe, hardware/OS independent, and resiliant, but why bother?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

No, you call run directly in the constructor and that calls repaint, which results in a call to paintComponent - which may be before the constructor is finished, depending on how the threads are scheduled. If you want run to execute only after it then you need to call it from somewhere else or do some thread scheduling of your own.

I'm going to try this just one more time.
You should not use a loop with "something added" to get a steady fps in a Swing application. Use a java.util.Timer or ThreadPoolScheduler that will call your model update at a regular intervals (regardless of hardware) and do so without creating thread blocking problems. This is one of those absolutely basic concepts about Swing animation. Why are you opposed to it?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Looks l;ike a very interesting bug starting with ballGame = new BallGame(); in main.

First, new BallGame() is called. That constructor calls Renderer.repaint() which executes BallGame.ballGame.Repaint(g); then, and only then, after the constructor has returned, the variable ballGame is set to refer to the new BallGame.

So when you execute BallGame.ballGame.Repaint(g);, ballGameis still null and you get an NPE

ps You still need a Timer, not a loop!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

We don't know which line is the 16th in your editor! Please be more explicit.

comment out the while (running) { and }
...Thats exaccly what i dont want to do though

If you are referring to the run loop (line 44 above) then, no, that's exactly what you do want to do. Posting repaint requests as fast as the CPU will, at best, just slow your machine to a crawl.

To display an animation (game or whatever) in Swing you need a Timer to trigger an update to the game state at regular intervals, eg 60 times per second, then call repaint to update the screen to match the latest game state. I can give you a lot more info and some sample code if you are interested.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster
public Renderer Renderer;

You have a variable with exactly the same name as a class. Surprisingly this is valid Java, but it's making your code imcomprehensible.
It would be much easier to read if you follow Java conventions and start class names with a capital, variable and method names with a lower case.

But anyway...
I can't see where you call Dimensions(), so Paddle is probably uninitialised, ie its value is null

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I think the obfuscation/hacking issue is much over-rated. Although decompiling and modifying a jar is possible, few people have the necessary skills and even fewer can be bothered unless it’s a really desirable program with too high a cost. If you set a sensible price then it will be less painful to pay than to hack every new version as you keep releasing updates.
Ok, so maybe there will also be the1% who will hack it just because they can, so ignore them.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Well.... yes.

It was inspired by the Ruby each_slice(5) thing that pty posted. It looked like a neat and useful thing that Java doesn't have. So I started out trying to do a Java version. The print-oriented version was a step on the road, but since then I have got it a lot more generic and closer to the original.
Now I have a "slicer" Collector that breaks a Stream<T> into substreams of a given size ie a Stream<Stream<T>>
You can do lots of things with that, including printing stuff in comma-delimited blocks of 5, ie

(some stream)
.collect(new SlicerBuilder(5).build())
.map(s -> s.collect(Collectors.joining(", "))) 
.forEach(System.out::println);

.collect(new SlicerBuilder(5).build()) 
// break into substreams of length 5

.map(s -> s.collect(Collectors.joining(", "))) 
// convert each substream to a comma-delimited list

.forEach(System.out::println);
// print each comma-delimited list on a new line

The code for the builder is a bit longer :), but it's just a utility thing that can be re-used endlessly. It would also be pretty trivial to adapt or extend it to split a stream on any other criteria

    class SlicerBuilder {

         private final int itemsPerGroup; 

        public SlicerBuilder(int itemsPerGroup) {
            this.itemsPerGroup = itemsPerGroup;
        }

        public <T> Collector<T, ?, Stream<Stream<T>>> build() {
            ArrayList<T> temp = new ArrayList<>();
            return Collector.of(
                    () -> new ArrayList<Stream<T>>(),
                    (list, i) -> {
                        temp.add(i);
                        if (temp.size() >= itemsPerGroup) {
                            list.add(new ArrayList(temp).stream());
                            temp.clear();
                        }
                    },
                    (list1, list2) -> {
                        list1.addAll(list2);
                        return list1;
                    },
                    list -> {
                        if (!temp.isEmpty()) list.add(temp.stream());
                        return list.stream();
                    }
            );
        }

    }
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I haven't been able to come up with a really elegant way to print 5 values per line...

OK, a bit off-topic, but I wanted to share this with anyone who may have been interested...
The problem is to print a Stream of numbers formatted at 5 per line.
I tackled this by creating a Collector that takes a Stream of Objects and returns a Stream of Strings in groups with different separators within groups and between groups, and threw in a formatting option for the Objects themselves.
In good Java 8 style I wrote a fluent builder to create Collectors with any or all of those options.
In use it looks like this

// adds a new line before each new group of 5

  (some arbitrary Stream)
. collect(new GrouperBuilder(5).groupPrefix("\n").build())
. forEach(System.out::print);

// build example with all the options
new GrouperBuilder(3) // 3 items per group
.prefix(", ")         // commas between them
.groupPrefix("\n")    // new lines between groups
.format("%4d")        // format items as 4 col ints
.build()              // create the Collector

// creates output like
//  24,   36,   48
//  60,   72,   84
//  96

and here (if anyone cares) is the builder code. Please comment and suggest improvements...

  class GrouperBuilder {

        // converts stream of Objects to stream of fornated Strings in groups

        private final int itemsPerGroup; // number of items in each group. Mandatory

        // optional formatting values...
        private String prefix = "";      // text to put between items within …
Reverend Jim commented: Kewl +15
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

No worries - "praise where praise is due"
If I were to write that the only changes I would make would be:
1) Some kind of very simple validation on the user input so it crashes out of bad input with a friendly error message
and
2) instead of i < secondNumber + 1 I would write i <= secondNumber

(or, for fun, I would write it using Streams range and filter as in my earlier post)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Conmments are attached to up and down votes, so unless yiu want to up/down vote, a simple reply is fine.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, I'd say beautiful.
The equivalent in Java is quite pretty too...

int lower = 16, upper = 99;

IntStream.rangeClosed(lower,upper)
   .filter(i -> i%3 == 0 && i%4 == 0)
   .forEach(System.out::print);

,,, but I haven't been able to come up with a really elegant way to print 5 values per line - any ideas anyone?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK folks, getting a bit off-topic here?... it's Java.

John: I don't see how you got from the problem definition to that code. It looks like you have tried to adapt a different program, with arrays of numbers and primes somehow.
Hacking a different program is almost always a bad idea.
The best thing to do is to go back to the start and sketch out your logic on a scrap of paper in pseudo-code, then write the Java to implement that. You could copy/paste the first 3 lines of the old code if you want, but no more than that.
If you get stuck come back here and someone will help.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Actually, looking at it now, it doesn't look un-matched to me anyway. "senior moment"?
Which < is it complaining about - line 1 or 6?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You have an unmatched ) on line 5

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I don't mean to be picky, but a loop that needs to be executed at least once should be a do/while not a while, which would obviate the need for that faffing around with a quit boolean.
As in

do {
   (whatever)
} while (user wants another game);
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Maybe you could use a try/catch for any Exception at the highest level in your code and see if you can output the message from there?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Sorry, I’m all OSX, IOS, Win10, don’t know android at all.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Just a random thought...
Are the array sizes ok? Visually it looks like pcX is bigger than pcY, so there’s a possible array index out of range???

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

“Crashes” doesn’t tell us much. How about an error message and a stack dump?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hey, no need to apologise - I know how frustrating it can be when you look at code and you just can't see what you're looking for.
I too started on traditional procedural programming (IBM 360 PL/!) and I still remember how hard it was to switch to event-driven GUI logic on the first Macintoshes. Once you've got it it perfectly simple, but until then...

I didn't comment on or change any other aspects of your code, but if you want to discuss them further I'd be glad to help. I see you are still using anonymous inner classes for your listeners... are you limited to pre-version-8 Java?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

.. still don't believe me? Ok then, here it is structured as above and working...

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static java.lang.Math.random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.Timer;

public class RunPhysics extends JFrame {

    private final int waits = 200; // 30 is smoother
    private JLabel blackBoard = new JLabel();
    private JLabel label = new JLabel("F=m*a -> O");
    private JButton roll = new JButton("Roll");
    private int labelX = 10;
    private int labelY = 60;
    private int die;
    // private Timer timer;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new RunPhysics();
            }
        });
    }

    public RunPhysics() {
        setSize(1000, 200);
        setTitle("Running Physics");
        setLayout(null);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setVisible(true);
        getContentPane().add(blackBoard);
        blackBoard.setBounds(10, 10, 980, 280);
        blackBoard.add(label);
        blackBoard.add(roll);
        label.setBounds(30, 50, 100, 20);
        roll.setBounds(10, 10, 60, 30);
        roll.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent roller) {
                roll.setEnabled(false);
                timer.start();
            }
        });
    }

    private Timer timer = new Timer(waits, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent mover) {

            labelX += 36; // += 4 is smoother
            label.setLocation(labelX, labelY);

            if (labelX < 900) {
                return;
            }

            die = (int) (random() * 6 + 1);
            System.out.println(die + " was rolled.");
            labelX = 10;

            if (die == 6) {
                // let the label continue moving
            } else {
                timer.stop();
                roll.setEnabled(true);
            }
        }
    });

}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

... and just to be absolutely certain I have edited your code into the structure described above and tested it. It executes exactly as you described. It took a few minutes, so it's not a big job.
Please try it. If your version does not execute as you want then post your edited code here and I'll tell you where it's going wrong.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

No, that's not right. It does exactly what you asked. Maybe you're not reading the pseudo code correctly?

On the first move (timer event) the label will not be at the end, so you return from the actonPerformed immediatley. You don't go on to roll unless the label is at the end. (see lines 15,16 above).

Don't get frustrated or give up on this now. I've been writing code for animations like this in Java since the 1990's, and I promise you that the pseudo code above does do what you asked.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That has absolutely no resemblance to the pseudo-code I posted earlier (did you read it?), and definitely will not work. Maybe I confused things by talking about "ticks". In animation like this a "tick" is the same as one timer event being fired. Ie if the timer delay is 40 mSec you will get 25 ticks (timer events) per second.

Here's the pseudo code again, this time formatted more like Java to make it absolutely clear.

// this is the action listener for the button...
// it's executed once each time the (enabled) button is pressed 

       disable the button;
       start the timer;
      // that's all

// end of action listener for the button

// this is the action listener for the timer events...
// the timer will executed it once every 200 mSec

       move the label one step (36 pixels)

       if (label has not reached the end) 
           return;
           // that's all that we do for this timer event
           // nothing else happens until the next timer event
       }

       // if we get here the label has reached the end

       roll the die;
       reset the label's position;

       if (roll == 6) {
             // we go round again
             // (the label will continue moving again on the next timer event)
       } else {
            // we have finished, so...
           stop the timer;
           re-enable the button;
       }

// end of action listener for the timer events

That's the whole structure. Nothing is repeated. and there are no loops. It's really very simple, but …

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The timer is a repeating timer that fires every 200ms
Every time it fires you move the label 36 pixels right
So it moves at a speed of 180 pixels every second (5 steps/sec)
No loop

When it reaches the end that's when you roll the die and reset the label- still part of the same timer firing.

(Line 4 is a comment - because of the if test on line 3 you will only get to line 4 if the label has reached the end of its journey)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You are right about EDT choking. That's why all your "looping" has to be done by a repeating Timer, not a for/while/do loop. I'll say it again. You cannot use a loop for this exercise - it won't work. No loops, OK?

"Timer inside Timer" can be made to work, but i's messy. One timer is enough...

Just play this through in your head (yes, really, do it)...

The use has clicked to button, and you've disabled it temporarily so he can't click it again too soon.

Now you timer is going tick - tick - tick (play each tick in your head) and at each tick you:

... move the label one step (eg 36 pixels)
... if it's not at the end yet then there's nothing else to do on this tick, so return
... (the label has moved all the way across, so..)
... roll the dice to see if it's a six
... if it's not a six you have finished, so stop the timer, re-enable the button, and return
... (the dice roll was a six, so...)
... move the label back to the beginning and return
... NB: There are no loops in this code !

The pseudo-code I posted illustrates a detailed structure you could be using.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The reason this is confusing is that the code lines 52-57 are coded inside the loop 40-61 but they are not executed in that loop. They are executed only after the Timer has expired. It runs like:

     do {labelX = 10;
         die = (int)(random()*6+1);
         roll.setEnabled(false);
         timer = new Timer( waits, etc).start();
     } while (die == 6); 
     roll.setEnabled(true);

     ... later...

     do a few times after a time delay {
            Toolkit.getDefaultToolkit().beep();
            label.setLocation(labelX, labelY);    
            if (labelX >= 900) {((Timer)mover.getSource()).stop();}
                    else { labelX+=36; }
     }

You can see there that you are executing code immediately upon button press that should really be executed after the Timer fires. Some thing like:

button pressed:
    disable button
    start timer 

timer fired
    update label position
    if label reached limit {
          reset label position
          if a new random roll is not 6 {
              stop timer
              re-enable button
          }
     }

In other words it's your outer loop that is causing your problems. Insead of starting a loop, start a repeating timer to keep rolling and updating the label; instead of exiting the loop stop the timer.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

It opens a new tab instead of a new window

That's a setting that is in the user preferences for Safari, and probably for other browsers as well.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Great!
In that case please mark this "solved". If you have any new questions you can start another topic.
JC

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You can't do it with one array.
You will need two arrays, one for the current state and one for the new state - so you check the number of adjacent cells in the current state array, then set the new values in the new state array.
After that you can copy the new state back into the current state, or keep the same arrays but simply swap over the references for which is current and which is next.

rproffitt commented: "Always two there are; no more, no less." +0
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

For the game of life you have to check the number of adjacent cells etc over the whole board, and then update the cells as appropriate.

What you are doing is to check each cell and immediatley update it, so that changes the result for all the cells adjacent to it.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

print throws an exception because there is no print method

???

PrintWriter has 9 overloaded print methods- one for each of the primitives plus ones for Object and String - just look at the API doc
https://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.html

however, they all require a parameter of some sort, so what tinstaafl should have said is

print() throws an exception because there is no print() method

and so the requirement statement is reasonable, but badly phrased, in that you should use a print method (eg print(char c)), but not print()

(see the difference between line 18 and line 31)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

If quantity is not 1 the you don't set rows properly and it's left at 0 (only done on line 9).
If you are trying to update the last row of 'n' rows then the row number is n-1.
I don't know which row you are trying to update but just remember first row is row 0 and the second row is row 1(etc)

I don't know how to make that any clearer

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

If quantity is 1 then you add a new row, and do not execute line 12. For other quantity values you execute line 12 with the second parameter invalid (see above)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I don't know your design, so I don't know wha the "specific row" is.
What I can say is that if rows is (eg) 2, then the valid values for the second parameter are 0 and 1, but not 2. ie, the first row is row 0 and the second row is row 1, there is no row 2.