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

As far as I can see that program has nothing specially "Java" about. It's a long time since I've seen a whole Java program entirely in static methods; it's even got statement labels! In particular it makes zero use of O.O.,
So translating into almost any other procedural language is just a matter of working through it one line at a time transliterating each in turn. Tedious, yes. Difficult, no.

rproffitt commented: Nice to read about literation rather than littering. +12
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

In OO each object has a public interface and a private implementation. No object has access to any other object's private implementation. This massively simplifies the overall architecture by restricting the number of ways that objects can interact. What you are doing here violates that; the bank object is trying to fiddle with part of the GUI's implementation.

The standard architectural solution to this is called MVC. There's loads of stuff on the web about it, but here's a good starting explanation. Google for more.

When you've read that, note that in JavaFX the model and the controller are very often combined in one class, but the model is always separate and independent.

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

19: The Track class does not have a constructor with no args.
58: you are trying to assign an int to a Track object - obviously not possible
66,77: you are referring to variables that do not exist in that class

what kind of help are you asking for?

rproffitt commented: No argument here. Assertions indeed fail. +12
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

^ That's right.

Also, mixing layout managers with setBounds is a recipe for chaos.

And you haven't needed to use frame.getContentPane().add(stuff);for about 10 years. You can just use frame.add(stuff);, or if your class extends JFrame, just add(stuff);

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That's good advice. I was ignoring your syntax errors because (a) the question was about how to test and (b) you would discover them yourself as soon as you tried to compile.

But do what AssertNull says and compile as you go.

Real programmers compile their modules early and compile them often. That way you discover your mistakes one a time rather all in one horrendous car crash at the end. That makes it a lot easier to diagnose and fix them one at a time.

diafol commented: Great advice! +15
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

90% probability that it's just looking in the wrong place.
You can try
System.out.println(new File("file.txt").getAbsolutePath());
to see exactly where Java is expecting to find it.

ps this is a good place to use a try-with-resources, which will handle disposing of the reader regardless of errors, thus allowing you to omit the whole finally block (lines 39-50)

       try(BufferedReader br = new BufferedReader(new FileReader("file.txt"));) 
       {
           String line;
           while((line = br.readLine()) != null){
                if(sb.length() > 0){
                    sb.append("\n");
                }
                sb.append(line);
           }
       }
       catch(IOException e){
           e.printStackTrace();
       }

see https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Your code is almost almost there...
Here's a simple way to structure it (pseudo code)

ask for number of students
for n = 1 to number of students {
   ask for student n's score
   calculate/display grade
} 

so all you need to do is fix your for statement and move entering the score to inside the loop. Fixing your indentation will be an enormous help in seeing what's happening!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I had a quick look at this and it's pretty simplistic (and out of date) stuff. Why would anyone think it's a good idea to waste time writing tutorials when Oracle have the definitive up-to-date tutorials (not to mention many others from established credible sources)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I've found the current problem to be with the second run

That's a very common problem. Trying to re-use existing objects and data structures for new run ... it's easy to miss re-initialising or clearing one variable that screws up the second run. (Even easier to miss when you add something to the code later!)

Simple answer is don't do it. package your code with a class whose constructor takes a data file and instantiates/executes whatever is needed. For the next data file simply create a new instance with all new variables and data structures, and allow the old stuff to be garbage collected.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

rproffitt: Sorry, but it does look to me like you have missed Gorge's point. He has got a working algorithm, but has a specific problem with intersections that have 4 (or more?) exits. Sorry if I have misunderstood your replies.

To me it looks like an artifact of the details of the implementation code, but without seeing the code and spending a lot of time I can't suggest anything specific. This Java exercise is typically most easily solved with a simple recursive exhaustive search, which would not have Gorge's problem (as I understand it).

rproffitt commented: I read it and would need to see code to see why it hit the wall. Since no code I took another path. +12
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK. I removed the Java tag as well.
JC

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Where's the Java?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

First, selecting a shape by clicking inside it...
the contains method comes from Shape, so assuming you have some kind of list of the existing shapes you can iterate through that to see which Shape contains the mouse pressed point (if you allow overlapping shapes then there may be more than 1 such shapes)

for a dragged rectangle selection...
create the selection Rectangle defined by the mouse drag start and latest points. The Rectangle class has acontains(Rectange other) method, so you can iterate through your Shapes, for each Shape get its bounding rectangle (getBounds()), then see if the selection rectangle contains that bounding rectangle.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Seen that message many times, never seen a solution.

cereal commented: sorry, I was tempted by the dark side of recursion :D +0
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi Darren

Please start your own new thread for your question - do not hijack other people's old threads. Don't forget to ask clearly what help you need, and show what you have done so far. Someone will help you.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

rproffitt: Would be a nice feature (an ignore list.)
gentlemedia: Yes, a block member would be a great addition
happygeek: Agree. Shame there isn't an equivalent to Block on FB
ddanbe: As I already mentioned(in Latin) ignoramus! ignore!

Strangely I don't agree. I think it's better to penalise behaviour than to penalise a person. Some of UI's ealier posts were perfectly reasonable newbie tech questions which deserved our usual courteous and helpful response. Then there were posts that degenerated into trollisms that deserved to be totally ignored. I'd like to think that if he were to start a new thread on a tech question, and conduct himself in an appropriate manner, then we would respond appropriately.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I would not put the code lines 4-8 in paintComponent. They don't belong there, and don't forget that paintComponent may be called by Swing at any time.
I would just have paintComponent do the painting, nothing else.

In the listener for the undo button I would simply delete the latest entry from the shapes list and call repaint()

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Who's UI?

Don't worry - it's a bit of an ongoing in-joke here at the moment.
I've sent Dani a PM on your behalf to let her know you want to get in touch.
JC

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Normally for an undo you would get rid of the last thing you added - ie remove the last Triangle, Rectangle, or Circle from its corresponding list, then redraw.
Your code deletes all the Rectangles in the list - regardless of how many there are, and regardless of whether the last thing you added was a Triangle, Rectangle, or Circle.

Hint:
You can make this a whole lot simpler by recognising that triangle, rectangle, and circle are all kinds of shapes. You could create a DrawShape class, with an abstract draw(Graphics2D g) method. Let your three Draw... classes extend it, and each implement its own version of draw(Graphics2D g).
Now you only need one List<DrawShape> that you can add all three shapes to. You can draw them all with a single loop - Java will call the correct draw method for each type of shape.
And (here's the punch line) the last thing you created will always be the last DrawShape in the list, so to undo you just delete that one.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, come on guys, I've never seen such an orgy of troll-feeding in my life.
We can't take administractive action against trolls, but we can do the next best thing which is to totally ignore any troll posts. Trolls get bored and go away when they get zero response.
STOP FEEDING THE TROLLS!

ddanbe commented: As I already mentioned(in Latin) ignoramus! ignore! +0
happygeek commented: Agree. Shame there isn't an equivalent to Block on FB +0
gentlemedia commented: Yes, a block member would be a great addition +0
rproffitt commented: Would be a nice feature (an ignore list.) +0
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster
rproffitt commented: Norway put in the effort and will reap the benefits. +0
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

if you are on the grid, you are not entirely clean even on the EVcar

Depends where you are!

The electricity sector here in France is mainly nuclear power, which accounted for 72.3% of total production in 2016, while renewables and fossil fuels accounted for 17.8% and 8.6%, respectively

That's 91.4% non-fossil

rproffitt commented: Correct. This is also a good example of how an EVcar can get cleaner over time. +0
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Sorry, but that's now we work here. We will help you to learn and help you to write your own code, butif we do your homework for you then nobody benefits.

Try to get the logic straight in your head, or on a piece of paper, before trying to write any code.

Usually people want to show the shape being drawn as the mouse moves, so they write the code in a pattern like this:

create the list of shapes
declare a temporary shape, initially null

mousepressed:  create new shape in the temporary variable
mouse dragged: update the temporary shape, call repaint
mouse released: add the temporary shape to the list, set the temporary variable to null, call repaint.

paintComponent: 
    draw all the shapes in the List
   if the temporary shape variable is not null draw the temporary shape.

That pattern means there's a temporary shape that keeps being updated and re-drawn as long as the mouse is moving. When the mouse is released the final shape is added to the list and the temporary shape is nulled.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

the cost is nearly identical to the Prius today

That's surprising. We run a Zoe EV and have a Citroen C4 Picasso that can do about 50 mpg.
Here's how the costs compare in France:

Zoe: 16.6 kWh/100km. Using standard domestic off-peak elecrticity at €0.127/kWh
= 2.11 Euros per 100 km

Citroen: 4.5 litres/100km at €1.23 per litre
= 5.71 Euros per 100km

So the EV is less than half the fuel cost of an ICE. (Not to mention the maintenance costs that are approx 0% of the maintenance costs for an ICE or hybrid)

@assertNull

  1. We have a simple socket in our garage - Renault paid for it as part of the deal for buying a Zoe. We use the car's charge timer to charge using off-peak electricity at 0.127 Euros/kWh (15 US cents)
  2. kilowatt hours per 100 km. Over the last 8 months we have averaged 16.6 kWh/100km
  3. It's massively heavy (300 kg = .33 US tons) and buried under floor under the rear seats. Carrying a spare is not feasible. We fit in the "95% trips < 100miles" category, so a 200 mile battery wouldn't affect us. A 500 mile battery would take us up to 98%. Maybe next year?
  4. Yes, of course. A heavy right foot does use more energy. Hills are less of an issue because the batteries recharge when you go downhill. Slowing by "engine braking" to recharge the batteries does make a big difference compared to slowing …
AssertNull commented: Good feedback from an actual owner +0
cereal commented: Nice info, thanks for sharing. Here in Italy electricity costs €0.28/kWh, while fuel is almost the same. +0
rproffitt commented: Nice to read about Zoe. +0
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You need to create your triangle on mousePressed, and keep updating it as the mouse is moved.

ps: down voter: did I get something wrong?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That's because you don't add the new triangle to triangles until the mouse is released.

Upside down may be because y coordinates start at 0 at the top and increase downwards.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You do realise that your code is not Java, do you?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

println works by calling toString() on each of its arguments in order to get something printable. All classes inherit a toString() from Object, but all that does is to return the class and hash of the object. Thats what line 21 above will do.
You should always override toString in any class you define. It should return a String that is a useful representation of the instance's values. println will then use that when you ask it to print a Products.

ps Minor point: class names should be singular - each instance represents one Product.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

In Internet slang, a troll (/ˈtroʊl/, /ˈtrɒl/) is a person who sows discord on the Internet by starting quarrels or upsetting people, by posting inflammatory,[1] extraneous, or off-topic messages in an online community (such as a newsgroup, forum, chat room, or blog) with the intent of provoking readers into an emotional response[2] or of otherwise disrupting normal, on-topic discussion,[3] often for the troll's amusement.

https://en.wikipedia.org/wiki/Internet_troll

Such a waste of your talents.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

If you fix your indentation it will become clear why that code will not compile...

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi Sibuns

Youhave moved on from the ER Diagram question to a discussion of usbwebserver. That's perfectly OK, but it would be better if you start a new topic, with a suitable title, to discuss that. There may be all kinds of people interested in usbwebserver who won't know this discussion is happening at the moment.

thanks
JC

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Do you really think that if people can't even be bothered to post in the Programming section that they'd bother to post in a specific language forum?

My point was that in the absence of any visible interest or activity in Java people are (a) unlikely to find us via a Java keyword search and (b) unlikely to start a Java-related topic.

I do remember that when we had a Java forum people posted in it. Lots of them.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I too believe it was a catastrophic mistake to trash the language-specific forums. Anyone looking at the remaining programming forum will quickly see that we don't do Java, just PHP, SQL, Python, C*. I don't believe tha the complete collapse of Java activity is entirely due to Google's malevolance, or the low qualiy of what we did. It's also because we longer promote ourselves as having any interest in or comittment to Java. (Substitute your own preferred technology here)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Where you have multiple forms ("views") that need to share data (a "model") you can use Model-View-Controller (MVC) architecture. In simple cases you can ignore the controller and just have a model class or classes that have the data and application logic and view classes that display or input data from/to the model.
Google MVC for more detail, but recognise that most write-ups will cover cases far more complex than yours. One model and three views is all you need. Create the model first, and pass it to form 1. Form 1 can update the model with whatever data it gets. Then pass the same model to form 2, which can query the model for whatever data it needs (etc).

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Apart from the IT justification and design, I'm curious about the business itself. Your figures imply that changing/storing 7 sets of tyres is enough to pay for an employee... unless there's more to the business than that.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Sorry if that seemed like an attack - it wasn't personal. I just didn't (still don't) understand why you would need so much Information Technology Engineering for something where a Rolodex would be perfectly OK. (and yes, I did look at the ERD... your strings seem generally too small, using integer fields for phone numbers is only OK if you are certain that every phone number will always be formatted exectly the same way, and speed ratings can be alphabetic. Do you really need separate fields for all the tyre's attributes separately - why not just "205/65R15 95H")

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Looking at your code again it seems you are setting the font on line 17.
SANS_SERIF is a porportional font where blanks and letters have different widths, so columns will not align.
Try MONOSPACED instead.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

TL;DR:

rproffitt commented: Yes. +1. +12
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Try posting it as code - that will preserve spaces

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

HappyGeek is an admin - ranks above mod and below Dani.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I have given a space of %30s between every field

That's not how it works. The width spec is the minimum width to use for the field, not the space between fields.

Your format is "%s %30s %30s %30s" That means the first item is printed a String with no padding, and the rest are printed as Strings padded to 30 chars wide.
If you want the first field printed at a fixed width then you need somethig like "%30s %30s %30s %30s"