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:
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:
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);
}
}