Hi, I need your help with my project. I'm doing traffic simulator, but I don't want it to be static map with moving cars, I want it to have methods to generate the roads with intersection (for now I have few simplifications like the roads are straight vertical or horizontal lanes, for now there is also no roundabouts and priority on road - on each intersection are the traffic lights). I started to code it, but quickly I noticed, that easier way will be first do the graphic (I need just an easy one) and then deal with things like counting cars on intersection, more sophisticated collision system or lane change, and here I have a few questions, and I will be glad for any answer:

  • I found the Model–view–controller pattern and as I understand, I should make separated class for graphics, to not have everything in one place, but how the graphic class and the controlling class shoiuld comunicate? For example I have class Car with position (x,y) and all staff to respectively change it. I have also class CarGraphics with paint methot, so would it work if the paint method would be static and get car as argument?

  • I have also problem with understanding all graphics methods. As I think for now, the app window will be generated with JFrame class, but I don't want the road to take whole window. What type should have the road, so I could for example set background as green rectangle, draw lines as lanes, and draw small rectangles as cars in it? I would very much like to place all things with reference to corner of the background, not to the corner of whole window. I basicly need a hint on type of components which could work as like I have class RoadGraphics wchich includes window 900x600 on witch I draw background, lanes, traffic lightts and cars and then place this whole thing in main frame.

For now I deal with the backend (I just did a few simple things, I must also admit I'm quite new in Java and it is my first serious project) and I think it will be easier if I will be able to see moving and responsive objects than just catch exeptions and do a lot of if statements, so I will be really glad for any sugestions and answers.

Good project!

Yes, MVC is a good way to go, although it may be overkill for a simple app. The important thing to have a clean separation between model and view.
You can use the Observer pattern to link a CarGraphics object to a Car object (just like any Swing event listener). The CarGraphics object adds itself as a listener to the Car object. Whenever the Car changes its state it notifies the listener(s). The CarGraphics object gets the car's latest state and calls repaint(). Swing then calls its paint method, which does the actual painting.
Alternatively, if you have the kind of model that updates the whole thing every n millisecs then you can just have the graphics as a listener to the model itself. Or maybe just have the timer call the model's update method then call the view's repaint. (There are many variants on this, just chose one that makes sense to you for this application.)
Don't use a JFrame for the painting, use a JPanel that you can place within the JFrame alongside other components. You subclass JPanel and override paintComponent. You could paint everything in one paint method, but you may find it easier in the long run to have a JPanel with the fixed stuff (roads etc) and the cars as separate components (eg JLabels) that you can move around in the JPanel. Or at least separate the method that paints a car from the method that paints the background.

commented: Thanks for an answer, you helped a lot, I think that secound option is closer to me, I would have just two more questions. +0

I have two questions:
1 I wrote the simple code moving rectangles along the screen (like u said in secound option - JPanel inside JFrame), but there is one think I don't understand - in lines
11) setSize(new Dimension(60, 60));
35) cars.setLocation(100,100);
I thought I set size and location of JPanel inside JFrame. Why then when I create rectangles in (0,0) position they start to move from left up corner of program, not from (100,100) point?
And I set size as 60,60, why then rectangles moves from left up corner to right down, and not disappear moving outside of JPanel?

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.Random;

class CarAnimation extends JPanel implements ActionListener {

    CarAnimation() {
        setSize(new Dimension(60, 60));
        new Timer(50, this).start();
    }

    public void actionPerformed(ActionEvent arg0) {
        for (Car c : Car.cars)
            c.update();

        repaint();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        for (Car c : Car.cars)
            c.draw(g2d);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1200,900);

        CarAnimation cars = new CarAnimation();
        cars.setLocation(100,100);
        frame.add(cars);

        frame.setVisible(true);
        new Car(0,0,1.2);
        new Car(0,0,1);
        new Car(0,0,1.5);
        new Car(0,0,1.6);
        new Car(0,0,1);
        new Car(0,0,1.1);
    }
}

class Car {
    public static final LinkedList<Car> cars = new LinkedList<>();
    double  x, y, speed;

    public Car(double x, double y, double s) {
        this.x = x;
        this.y = y;
        this.speed = s;
        cars.add(this);
    }
    public void update() {
        Random rand = new Random();
        x += (rand.nextInt(10) - 3) * speed;
        y += (rand.nextInt(10) - 3) * speed;
    }
    public void draw(Graphics2D g2d) {
        g2d.setColor(Color.red);
        g2d.fillRect((int) x, (int) y, 10,10);
    }

}

2 I will have the methods to create map, like setIntersection(x,y) setRoad(start,end) etc. but would it be a lot of trouble to do allow user move things like on this video: https://youtu.be/6xTLd47SmIs ? What liblaries could help me with this?

  1. Without all the code I can't reproduce that problem, but here's my best guess:
    You create the JPanel wih an initial size and location.
    You add that panel to a JFrame with the default BorderLayout layout, so the panel goes in the center. As there are no other components in the JFrame the layout manager sizes and positions the panel to fill the frame.
    You can check this by printing the size and position of the JPanel AFTER the JFame has been made visible.

In general you can't mix absolute sizing and positioning with a layout manager - the layout manager wil do its job and size/position components according to its own rules. You can try setMinimum/Maximum/Preferred sizes and the layout manager will respect some or all of those - each layout manager will have its own way of reconciling those constraints with its own rules.

Don't be tempted to use a null layout manager and position everything yourself - all that gives you is an application that messes up on any other machine with a different pixel size or system font size, and which fails to handle window re-sizing etc.

  1. The standard Swing API has all you need to track mouse press/relese, click, movements and drags. In the mouse listeners you simply get the mouse position and use that to call your setRoad etc methods. See https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html You don't need any other libraries, and it's easier than you may think!

(this is an answer to Q2, but the dumb editor thinks it knows best and keeps replacing my 2 with a 1)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.