0

I want to realize a simple Java painting example to simulate a car/tractor driving path. For this I want to add only a simple line in the middle of a JPanel (which is my car/tractor :-)). When I use the up,down,left,right key of the keyboard the driving path should be painted on the panel.

I was able to realize this but only if I move the line on the panel (means I move the car/tractor on the panel). But what I want to do is not move the line (car/tractor). The car/tractor should always be in the middle of the panel but the path should be painted behind the car. It should look like the background is moving? Similar to car navigation systems.

I'm not sure how can I realize this.

I added the following picture to explain in detail what I want to realize:

enter image description here

The blue arrow in the middle of the picture is the car/tractor. Behind this a black line is painted on the screen. The moving path of the car/tractor is painted in blue behind the black line. Within my application I have GPS corrdinates which I can use to calculate points with x and y coordinates. With this calculated points I want to draw the path of the moving car/tractor. But the car/tractor should always be in the middle of the JPanel. Only the path should move and rotate.

Example:

enter image description here

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;

public class Start {

    public static void main(String[] args)
    {

        JFrame frame = new JFrame("AutoPilot");
        frame.setSize(800,600);

        Stage e1 = new Stage();
        frame.getContentPane().add(e1);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.addKeyListener(new KeyListener() {

            @Override
            public void keyPressed(KeyEvent e)
            {
                switch(e.getKeyCode())

                {
                case KeyEvent.VK_LEFT:
                    e1.moveLine(e);
                    break;

                case KeyEvent.VK_RIGHT:
                    e1.moveLine(e);
                    break;

                case KeyEvent.VK_UP:
                    e1.moveLine(e);
                    break;

                case KeyEvent.VK_DOWN:
                    e1.moveLine(e);
                    break;

                case KeyEvent.VK_PLUS:
                    e1.moveLine(e);
                    break;

                case KeyEvent.VK_MINUS:
                    e1.moveLine(e);
                    break;

                case KeyEvent.VK_Z:
                    e1.moveLine(e);
                    break;
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
                // TODO Auto-generated method stub
            }

            @Override
            public void keyTyped(KeyEvent e) {
                // TODO Auto-generated method stub
            }
        });

        frame.setVisible(true);
    }
}


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class Stage extends JPanel
{

    int pW = 800;
    int pH = 600;

    double centerX, centerY;
    double x,y,angle, angleLine, xpic,ypic;
    double w = 15;
    double x1,y1,x2,y2,x3,y3;

    BufferedImage bi;

    private boolean gf_rotate;
    private boolean gf_bgSet;
    private boolean gf_rotated;

    public Stage()
    {
        setLayout(null);
        setBounds(0,0,pW,pH);
        setBackground(Color.WHITE);
        centerX = this.getWidth()/2;
        centerY = this.getHeight()/2;

        x = centerX;
        y = centerY;

        xpic = centerX;
        ypic = centerY;

        bi = new BufferedImage(pW, pH, BufferedImage.TYPE_INT_RGB);

        addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent arg0) {
                System.out.println(arg0.getX() +","+ arg0.getY());  // TODO Auto-generated method stub
            }
            @Override
            public void mouseEntered(MouseEvent arg0) {
                // TODO Auto-generated method stub
            }
            @Override
            public void mouseExited(MouseEvent arg0) {
                // TODO Auto-generated method stub
            }
            @Override
            public void mousePressed(MouseEvent arg0) {
                // TODO Auto-generated method stub
            }
            @Override
            public void mouseReleased(MouseEvent arg0) {
                // TODO Auto-generated method stub
            }
        });
    }

    public void moveLine(KeyEvent e)
    {
        switch(e.getKeyCode())
        {
        case KeyEvent.VK_PLUS:
            angle--;
            angleLine--;

            gf_rotate = true;
            repaint();

            break;

        case KeyEvent.VK_MINUS:
            angle++;
            angleLine++;

            gf_rotate = true;
            repaint();

            break;

        case KeyEvent.VK_LEFT:
            break;

        case KeyEvent.VK_RIGHT:
            break;

        case KeyEvent.VK_UP:
            y--;
            ypic++;

            if (gf_rotate == true)
            {

                gf_rotated = true;
            }

            gf_rotate = false;
            repaint();
            break;

        case KeyEvent.VK_DOWN:
            y++;
            ypic--;

            if (gf_rotate == true)
            {
                gf_rotated = true;
            }
            gf_rotate = false;
            repaint();
            break;

        case KeyEvent.VK_Z:
            repaint();
            break;
        }
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) bi.createGraphics();
        Graphics2D g2dMain = (Graphics2D) g;

        double _x,_y;

        //Hintergrundfarbe (Bild) setzen
        if (gf_bgSet==false)
        {
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, pW, pH);

            g2d.setColor(Color.BLUE);

            Line2D line = new Line2D.Double(x, y, x+100,y);
            g2d.draw(line);

            gf_bgSet=true;
        }

        float[] fa = {1};

        BasicStroke s = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND,15,fa,15);

        g2d.setStroke(s);

        _x  =x;
        _y = y;

        if (gf_rotated==true)
        {
            _x=400;
            _y=300;
        }

        Point2D p1 = new Point2D.Double(_x,_y);
        Point2D p2 = new Point2D.Double(p1.getX()+100,p1.getY());
        Line2D line = null;

        if (gf_rotate==true)
        {
            line = new Line2D.Double(p1.getX(), p1.getY(), p2.getX(),p2.getY());
        }
        else
        {
            Point2D p3 =  rotateLine(p1,p2,angleLine);

            line = new Line2D.Double(p1.getX(), p1.getY(), p3.getX(),p3.getY());
        }
        g2d.setColor(new Color(255,80,90,100));


        AffineTransform atLine = null;

        if (gf_rotated == true)
        {

            atLine = new AffineTransform();
            atLine = g2d.getTransform();
            g2d.setColor(Color.GREEN);

            Point2D newP2 = rotateLine(p1,p2,angleLine);

            line = new Line2D.Double(p1.getX()-(centerX-x), p1.getY()-(centerY-y), newP2.getX()-(centerX-x),newP2.getY()-(centerY-y));

        }
        else
        {
            //Rotate line
            atLine = new AffineTransform();
            atLine.translate(x,y);
            if (gf_rotate==true)
            {
                atLine.rotate(Math.toRadians(angle));
            }
            atLine.translate(-x,-y);
        }

        g2d.draw(atLine.createTransformedShape(line));

        g2d.dispose();

        AffineTransform at = new AffineTransform();

        AffineTransform old = g2d.getTransform();

        at.translate(xpic,ypic);

        at.rotate(Math.toRadians(-angle),centerX-xpic,centerY-ypic);

        at.translate(-centerX,-centerY);

        g2dMain.drawImage(bi, at , null);

        g2d.setTransform(old);

        g2dMain.dispose();
    }

    private Point2D rotateLine(Point2D center, Point2D edge, double angle2) {

        double xRot = (int) center.getX() + Math.cos(Math.toRadians(angle2)) * (edge.getX() - center.getX()) - Math.sin(Math.toRadians(angle2)) * (edge.getY() - center.getY());
        double yRot = (int) center.getY() + Math.sin(Math.toRadians(angle2)) * (edge.getX() - center.getX()) + Math.cos(Math.toRadians(angle2)) * (edge.getY() - center.getY());
        return new Point2D.Double(xRot, yRot);
    }
}
c0der
  • 18,467
  • 6
  • 33
  • 65
Hans
  • 107
  • 1
  • 4
  • *"I'm not sure how can I realize this."* I'm sure that's not a question *"It should look like the background is moving?"* and neither is that, despite the `?`. **What is the question?** – Andrew Thompson Oct 24 '19 at 02:57
  • 1
    "I was able to realize this but only if I move the line on the panel " please share [mre] of what you tried. – c0der Oct 24 '19 at 14:49
  • I have changed the question and added a picture to show in detail what I want to realize. – Hans Oct 25 '19 at 10:10
  • Tips: 1) Tip: Add @c0der (or whoever, the `@` is important) to *notify* the person of a new comment. 2) You were advised to post an MRE & a question. A picture is neither of those. Minus one. – Andrew Thompson Oct 25 '19 at 13:53
  • @c0der: I added an example code to my question. The following was implemented: With the keyboard keys up and down the car can be moved up and down (the path is drawn always from the middle behind the car). With key "+" and "-" a curve can be drawn. The main issue is that when I first draw a path with the key "UP" , than I draw a curve (e.g. hit "+" 20 times) and than use the "UP" key again to drive a straight path then the path was not drawn correct (see picture). – Hans Oct 30 '19 at 19:26
  • Some general comments and suggestions: 1. You have a `switch` statement where all cases do the same, so the `switch` is not needed. 2. Prefer [key binding over key listeners](https://stackoverflow.com/questions/20873255/keylistener-vs-key-bindings#targetText=Key%20bindings%20were%20introduced%20later,preferable%20to%20use%20key%20bindings.) 3. The "main issue" in your last comment is different from the issue detailed in the post. Decide on one issue and focus the post on it. – c0der Oct 31 '19 at 15:53
  • @c0der: At the moment I have the issue described with the last picture. I want to draw the path 90 degrees down when I use the up button. Not draw the path rotate angle to the side. Thanks. – Hans Oct 31 '19 at 17:37

0 Answers0