Moving point along lines - java

I draw a shape, which looks like letter "Y". Then I draw a small point at the bottom of it.
Let's say the shape is 3 lines, like so:
I want to move this point along line 1, then line 2, then back along line 2, then line 3, and finally back to the start at the bottom of line 1.
It moves with speed specified by slider.
Here's my code so far:
public class yyyyy extends JFrame{
private Komponent komponent;
private Timer timer;
private int tick = 0;
private int speed = 4;
private int x1 = 225, y1 = 300, y2 = 225, x3 = 150, y3 = 150, x4 = 300;
private int x = x1, y = y1;
class Komponent extends JComponent{
/**
*
*/
private static final long serialVersionUID = -4028514932033769012L;
#Override
protected void paintComponent(Graphics arg0) {
if(tick< y1-y2){
x = x1;
y = y1-tick;
}
else if(tick>y1-y2 && tick < 2*(y1-y2)){
x = x1-tick + (y1-y2);
y = y2-tick + (y1-y2);
}
else if(tick>2*(y1-y2) && tick < 3*(y1-y2)){
x = x3 + tick - 2*(y1-y2);
y = y3 + tick - 2*(y1-y2);
}
else if(tick>3*(y1-y2)&& tick < 4*(y1-y2)){
x = x1 + tick - 3*(y1-y2);
y = y2 - tick + 3*(y1-y2);
}
else if(tick>4*(y1-y2)&& tick < 5*(y1-y2)){
x = x4 - tick + 4*(y1-y2);
y = y3 + tick - 4*(y1-y2);
}
else{
x = x1;
y = y2 + tick - 5*(y1-y2);
}
arg0.setColor(Color.BLUE);
arg0.drawLine(x1, y1, x1, y2);
arg0.drawLine(x1,y2,x3,y3);
arg0.drawLine(x1, y2, x4, y3);
arg0.setColor(Color.RED);
arg0.fillOval(x-5, y-5, 10, 10);
super.paintComponent(arg0);
}
}
public yyyyy (String string){
super(string);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBounds(100,100,550,550);
add(komponent=new Komponent());
JPanel panel = new JPanel();
add(panel, BorderLayout.SOUTH);
final JCheckBox cb = new JCheckBox("Animacja");
cb.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if(cb.isSelected()){
timer.start();
}
else{
timer.stop();
}
}
});
panel.add(cb);
timer = new Timer(50, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tick+=speed;
if(tick > 6*(y1 -y2)){
tick -= 6*(y1-y2);
}
if(tick < 0){
tick = 6*(y2-y1);
}
komponent.repaint();
}
});
final JSlider speedSlider = new JSlider(-30,30,speed);
panel.add(speedSlider);
speedSlider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
speed = speedSlider.getValue();
komponent.repaint();
}
});
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new yyyyy("wat");
}
});
}
}
Now I have 2 problems:
1. Is the resetting of tick defined properly? I feel like it should go to 0 after being 2 * the sum of distances of all lines.
2. The part of the code I marked with comment. How can I check what the current x and y of the point should be? I tried doing that from line equation, but not much success (point was always just shooting outside of the window).
EDIT: Code updated.

Although the question was already answered in the comment (and although it was mainly a debugging hint, and although this is not really an answer...) I'd like to recommend you to generalize this.
You should probably to model each and every segment manually, with a fixed set of coordinates. Instead, you could create a general "path", that should be followed. The position on the path can be defined as a value between 0.0 and 1.0.
Then, the timing and interpolation are separated, and the timing itself can be handled separately. You can then even add nifty animation effects, for example, add some Math.sin somewhere and obtain interesting ease-in/ease-out effects.
However, here is an MCVE showing an example of how such a generic path follower could be implemented. It may changed from following an Y to following an X just by changing the creation of the PathFollower instance in the main method.
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class PathFollowerTest
{
public static void main(String[] args)
{
final PathFollower pathFollower = createPathFollowerY();
//final PathFollower pathFollower = createPathFollowerX();
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI(pathFollower);
}
});
}
private static PathFollower createPathFollowerY()
{
Point2D p0 = new Point2D.Double(225, 300);
Point2D p1 = new Point2D.Double(225, 225);
Point2D p2 = new Point2D.Double(150, 150);
Point2D p3 = new Point2D.Double(300, 150);
PathFollower pathFollower = new PathFollower();
pathFollower.addPoint(p0);
pathFollower.addPoint(p1);
pathFollower.addPoint(p2);
pathFollower.addPoint(p1);
pathFollower.addPoint(p3);
pathFollower.addPoint(p1);
pathFollower.addPoint(p0);
return pathFollower;
}
private static PathFollower createPathFollowerX()
{
Point2D p0 = new Point2D.Double(150, 300);
Point2D p1 = new Point2D.Double(225, 225);
Point2D p2 = new Point2D.Double(150, 150);
Point2D p3 = new Point2D.Double(300, 300);
Point2D p4 = new Point2D.Double(300, 150);
PathFollower pathFollower = new PathFollower();
pathFollower.addPoint(p0);
pathFollower.addPoint(p1);
pathFollower.addPoint(p2);
pathFollower.addPoint(p1);
pathFollower.addPoint(p4);
pathFollower.addPoint(p1);
pathFollower.addPoint(p3);
pathFollower.addPoint(p1);
pathFollower.addPoint(p0);
return pathFollower;
}
private static void createAndShowGUI(final PathFollower pathFollower)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(100, 100, 550, 550);
f.getContentPane().setLayout(new BorderLayout());
PathFollowerPanel pathFollowerPanel =
new PathFollowerPanel(pathFollower);
f.getContentPane().add(pathFollowerPanel, BorderLayout.CENTER);
final PathFollowerController pathFollowerController =
new PathFollowerController(
pathFollower, pathFollowerPanel);
JPanel panel = new JPanel();
f.getContentPane().add(panel, BorderLayout.SOUTH);
final JCheckBox cb = new JCheckBox("Animacja");
cb.addChangeListener(new ChangeListener()
{
#Override
public void stateChanged(ChangeEvent e)
{
pathFollowerController.setRunning(cb.isSelected());
}
});
panel.add(cb);
final JSlider speedSlider = new JSlider(-30, 30, 0);
panel.add(speedSlider);
speedSlider.addChangeListener(new ChangeListener()
{
#Override
public void stateChanged(ChangeEvent e)
{
pathFollowerController.setSpeed(speedSlider.getValue());
}
});
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class PathFollowerController
{
private int speed = 0;
private PathFollower pathFollower;
private PathFollowerPanel pathFollowerPanel;
private final Timer timer = new Timer(50, new ActionListener()
{
private double alpha = 0;
#Override
public void actionPerformed(ActionEvent e)
{
alpha += speed / 500.0;
alpha %= 1.0;
while (alpha < -1.0)
{
alpha += 1.0;
}
pathFollower.setAlpha(alpha < 0 ? -alpha : alpha);
pathFollowerPanel.repaint();
}
});
PathFollowerController(PathFollower pathFollower,
PathFollowerPanel pathFollowerPanel)
{
this.pathFollower = pathFollower;
this.pathFollowerPanel = pathFollowerPanel;
}
void setRunning(boolean running)
{
if (running)
{
timer.start();
}
else
{
timer.stop();
}
}
public void setSpeed(int speed)
{
this.speed = speed;
}
}
class PathFollower
{
private final List<Point2D> points;
private Shape path;
private double pathLength = -1;
private double alpha = 0;
PathFollower()
{
points = new ArrayList<Point2D>();
}
void addPoint(Point2D p)
{
points.add(new Point2D.Double(p.getX(), p.getY()));
path = null;
pathLength = -1;
}
void setAlpha(double alpha)
{
this.alpha = alpha;
}
Point2D getCurrentPoint()
{
return computePoint(alpha);
}
Shape getPath()
{
if (path == null)
{
path = createPath();
}
return path;
}
private Shape createPath()
{
Path2D path = new Path2D.Double();
for (int i = 0; i < points.size(); i++)
{
Point2D p = points.get(i);
double x = p.getX();
double y = p.getY();
if (i == 0)
{
path.moveTo(x, y);
}
else
{
path.lineTo(x, y);
}
}
return path;
}
private double computePathLength()
{
double pathLength = 0;
for (int i = 0; i < points.size() - 1; i++)
{
Point2D p0 = points.get(i);
Point2D p1 = points.get(i + 1);
pathLength += p0.distance(p1);
}
return pathLength;
}
private Point2D computePoint(double alpha)
{
if (pathLength < 0)
{
pathLength = computePathLength();
}
double alphaPosition = alpha * pathLength;
double accumulatedLength = 0;
for (int i = 0; i < points.size() - 1; i++)
{
Point2D p0 = points.get(i);
Point2D p1 = points.get(i + 1);
double distance = p0.distance(p1);
double nextLength = accumulatedLength + distance;
if (nextLength >= alphaPosition)
{
double localAlpha =
(alphaPosition - accumulatedLength) / distance;
double x = p0.getX() + localAlpha * (p1.getX() - p0.getX());
double y = p0.getY() + localAlpha * (p1.getY() - p0.getY());
return new Point2D.Double(x, y);
}
accumulatedLength = nextLength;
}
Point2D p = points.get(points.size() - 1);
return new Point2D.Double(p.getX(), p.getY());
}
}
class PathFollowerPanel extends JPanel
{
private final PathFollower pathFollower;
PathFollowerPanel(PathFollower pathFollower)
{
this.pathFollower = pathFollower;
}
#Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.BLUE);
g.setStroke(new BasicStroke(3.0f));
g.draw(pathFollower.getPath());
g.setColor(Color.RED);
Point2D p = pathFollower.getCurrentPoint();
double r = 5;
g.fill(new Ellipse2D.Double(
p.getX() - r, p.getY() - r, r + r, r + r));
}
}

Related

How to prevent flushing when draw a rectangle in Java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
class DrawningBoard extends Canvas implements MouseMotionListener{
private List<Point> points = new ArrayList<>();
private List<List<Point>> curves = new ArrayList<>();
private boolean isRectangle = false;
private int xr, yr, widthr, heightr;
public void setIsRectangle(boolean trueOrFalse){
isRectangle = trueOrFalse;
}
public boolean getIsRectangle(){
return isRectangle;
}
public DrawningBoard(){
setBackground(Color.MAGENTA);
addMouseMotionListener(this);
addMouseListener(new MouseAdapter(){
public void mouseReleased(MouseEvent e){
curves.add(points);
points = new ArrayList<>();
}
public void mousePressed(MouseEvent e){
points.add(new Point(e.getX(), e.getY()));
}
});
}
public void paint(Graphics g){
g.setColor(Color.CYAN);
if(isRectangle){
g.drawRect(xr, yr, widthr, heightr);
}
for(List<Point> curve : curves){
for(int i = 0; i < curve.size() - 1; i++){
g.drawLine((int)curve.get(i).getX(), (int)curve.get(i).getY(), (int)curve.get(i + 1).getX(), (int)curve.get(i + 1).getY());
}
}
}
public void mouseDragged(MouseEvent e){
Graphics g = getGraphics();
g.setColor(Color.CYAN);
int xx = e.getX();
int yy = e.getY();
int x = (int)points.get(points.size() - 1).getX();
int y = (int)points.get(points.size() - 1).getY();
int dx = xx-x;
int dy = yy-y;
if(isRectangle){
if(dx >= 0 && dy >= 0){
xr = x;
yr = y;
widthr = dx;
heightr = dy;
} else if(dx < 0 && dy < 0){
xr = xx;
yr = yy;
widthr = -dx;
heightr = -dy;
} else if(dx >= 0 && dy < 0){
xr = x;
yr = yy;
widthr = dx;
heightr = -dy;
} else if(dx < 0 && dy >= 0){
xr = xx;
yr = y;
widthr = -dx;
heightr = dy;
}
repaint();
}
else {
g.drawLine(xx, yy, (int)points.get(points.size() - 1).getX(), (int)points.get(points.size() - 1).getY());
points.add(new Point(xx, yy));
}
}
public void mouseMoved(MouseEvent e) { }
}
class GUI extends JFrame implements ActionListener{
private JPanel[] panel;
private JButton[] button;
private DrawningBoard board;
public GUI(String title){
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(416, 400);
board = new DrawningBoard();
board.setBounds(0,0, 400, 400);
panel = new JPanel[3];
panel[0] = new JPanel();
panel[1] = new JPanel();
panel[2] = new JPanel();
panel[0].setLayout(null);
panel[1].setLayout(null);
panel[2].setLayout(null);
panel[0].setBounds(0, 0, 400, 20);
panel[1].setBounds(0, 20, 400, 400);
panel[2].add(panel[0]);
panel[2].add(panel[1]);
panel[0].setBackground(Color.red);
button = new JButton[5];
button[0] = new JButton("Rectangle");
button[1] = new JButton("b1");
button[2] = new JButton("b2");
button[3] = new JButton("b3");
button[4] = new JButton("b4");
button[0].addActionListener(this);
button[3].addActionListener(this);
button[0].setBounds(0, 0, 100, 20);
button[1].setBounds(100, 0, 100, 20);
button[2].setBounds(200, 0, 100, 20);
button[3].setBounds(300, 0, 100, 20);
button[4].setBounds(0, 0, 100, 20);
panel[0].add(button[0]);
panel[0].add(button[1]);
panel[0].add(button[2]);
panel[0].add(button[3]);
panel[0].add(button[4]);
panel[1].add(board);
add(panel[2]);
show();
}
public void actionPerformed(ActionEvent e){
String command = e.getActionCommand();
if(command.equals("Rectangle"))
board.setIsRectangle(!board.getIsRectangle());
}
}
public class Paint{
public static void main(String []str){
new GUI("Paint");
}
}
I want to create a Paint application. If I draw multiple curves on the board and then I want to draw a rectangle (using drawRect(x, y, width, height)), those curves are repainted and results some flushing as result of use repaint() method. How can I avoid that flushing?
I tried to use update() method, but many rectangles are drawn when mouse dragging.
Swing is double buffered by default.
public void paint(Graphics g){
Don't override paint(). You have done this incorrectly and have lost the benefit of double buffering.
Instead, custom painting should be done by overriding the paintComponent(...) method. Read the section from the Swing tutorial on Custom Painting for more information and working examples.
You can also check out the DrawOnComponent example from Custom Painting Approaches for a more complete example that does what you want.

netbeans: animate circle drawn using drawline funtion

I am trying to draw a circle like this: http://35.197.37.158/Circle/
using drawline function and animate it same as the attached link.
here is what I tried but it draw a line of circle and delete the previous one
This is the class that have my code for drawing a circle and animating it using swin Timer. anyone have better idea to animate the circle ?
import java.awt.Color;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.GeneralPath;
import javax.swing.*;
public class CustomPanel extends JPanel implements ActionListener{
Point [] coordinates;
GeneralPath circle;
final int C = 10;
int j =0;
int i =j;
Point p;
Point p2 ;
Timer clock = new Timer(100, this);
public CustomPanel()
{
LinesCoordinates();
clock.setInitialDelay(50);
clock.start();
}
private void LinesCoordinates()
{
int numberOfLines = 360/C;
coordinates = new Point[numberOfLines];
double cx = 200.0;
double cy = 200.0;
double r = 75.0;
int count = 0;
for(int theta = 0; theta < 360; theta+=C)
{
int x = (int)(cx + r * Math.cos(Math.toRadians(theta)));
int y = (int)(cy + r * Math.sin(Math.toRadians(theta)));
coordinates[count++] = new Point(x, y);
}
}
#Override
public void actionPerformed(ActionEvent e) {
Redraw();
repaint();
}
public void Redraw(){
j=j+1;
p = p2;
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(Color.red);
// while (j<=coordinates.length){
while(i<=j){
j--;
p2 = coordinates[j % coordinates.length];
g2.drawLine(p.x, p.y, p2.x , p2.y);
}}}
And this is my Main
public static void main(String[] args)
{
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
JFrame frame = new JFrame("Circle ");
CustomPanel co = new CustomPanel();
frame.add(co);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
Since I was not able to get your solution draw the circle I had to rewrite your code a bit. Here is my solution preserving your JPanel listening to Timer approach. Hopefully this will work for you. I can send the complete NetBeans project if you want.
package circleanimation;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class CustomPanel extends JPanel implements ActionListener {
final int numberOfPoints = 20;
Point[] circleCoordinates = new Point[numberOfPoints];
int nextPointToAnimate = 1;
Timer clock = new Timer(100, this);
public CustomPanel() {
calculateCirclePoints();
clock.setInitialDelay(50);
clock.start();
}
private void calculateCirclePoints() {
int angle = 360 / numberOfPoints;
double cx = 150.0;
double cy = 150.0;
double r = 75.0;
int count = 0;
for (int totalAngle = 0; totalAngle < 360; totalAngle = totalAngle + angle) {
int x = (int) (cx + r * Math.cos(Math.toRadians(totalAngle)));
int y = (int) (cy + r * Math.sin(Math.toRadians(totalAngle)));
circleCoordinates[count++] = new Point(x, y);
}
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.red);
for (int i = 0; i < nextPointToAnimate; i++) {
Point firstPoint = circleCoordinates[i];
Point secondPoint;
if (i == numberOfPoints - 1) {
secondPoint = circleCoordinates[0];
} else {
secondPoint = circleCoordinates[i + 1];
}
g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);
}
}
#Override
public void actionPerformed(ActionEvent e) {
nextPointToAnimate++;
if (nextPointToAnimate == numberOfPoints) {
clock.stop();
}
repaint();
}
}

Draw with lines in Java

How can I draw in java figure like this?
Here is my code which has to draw at least half of this figure
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class Main {
public static void main(String[] a) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 300, 300);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
class MyCanvas extends JComponent {
private static final long serialVersionUID = 1L;
public void paint(Graphics g) {
int i =0;
for ( i = 0; i < 100; i++) {
int x=1+i*3;
g.drawLine(x, 200, 2+(x+(i/2)), 400-((i*i)/20));
}
}
}
And I get this one.
A little animation to show you the logic you need to be looking for in terms of line rotation. Think of the line like a hand on a clock. How would to animate a hand on a clock. It's pretty much the exact same concept. The only difference is that the x1 (the x point for the center point of the clock hand), instead of remaining still, it moves along the x axis (which is the y1 constant) while the hand is turning. So for every tick of the clock (hand rotation), the x location is also moved horizontally. That's the way I looked at it.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main {
public static void main(String[] a) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.getContentPane().add(new MyCanvas());
window.pack();
window.setVisible(true);
}
}
class MyCanvas extends JPanel {
int x1 = 0;
int rotate = 50;
List<Line> lines;
Timer timer = null;
public MyCanvas() {
lines = new ArrayList<>();
timer = new Timer(75, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (rotate < -50) {
((Timer) e.getSource()).stop();
} else {
lines.add(new Line(x1, rotate));
repaint();
x1 += 5;
rotate--;
}
}
});
JButton start = new JButton("Start the Magic");
start.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
add(start);
}
public Dimension getPreferredSize() {
return new Dimension(502, 400);
}
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
for (Line line : lines) {
line.drawLine(g);
}
}
class Line {
int x1;
int rotate;
int y1 = 200;
public Line(int x1, int rotate) {
this.x1 = x1;
this.rotate = rotate;
}
void drawLine(Graphics g) {
int Radius = (int) (Math.min(getWidth(), getHeight()) * 0.4);
int sLength = (int) (Radius * 0.9);
int xSecond = (int) (x1 + sLength * Math.sin(rotate * (2 * Math.PI / 100)));
int ySecond = (int) (y1 - sLength * Math.cos(rotate * (2 * Math.PI / 100)));
g.setColor(Color.GREEN);
g.drawLine(x1, y1, xSecond, ySecond);
}
}
}
Me so much :D
float centerY = 250;
float x1 = 0;
float x2 = 0;
float y2 = 400;
float way2 = 0;
for (int i = 0; i < 125; i++)
{
x2 += cos(way2*PI/-180)*10;
y2 += sin(way2*PI/-180)*10;
way2 += centerY/y2*0.235*10;
x1 += y2/600*10;
g.drawLine(x1,centerY,x2,y2);
}
Here's what I figured out, little different though :)
public void paint(Graphics g) {
for (int i = 0; i < 100; i++) {
int x = 1 + i * 3;
g.drawLine(x, 200, x + i, 400 - i * i / 20);
g.drawLine(600 - x, 200, 600 - (x + i), 400 - i * i / 20);
}
}
We need to rework on the function '400 - i * i / 20'.

How can I move a jlabel image around the screen?

I want to click on the screen and have the character move to that destination. Not instantly, but rather "walk" to the given coordinate. Currently I'm using JLabels and they're fine if I only use static images, but everytime I click somewhere on the screen the image shows up at that exact point. Could someone give me some tips?
edit: Should I override the paint class and draw some items that way?
Here's some code:
package mod;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.awt.KeyboardFocusManager;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Board2 extends JPanel {
private Thread animator;
int x, y;
double ix, iy;
double dx, dy;
final int frameCount = 8;
BufferedImage flower;
private int[][] fPos = {{232, 15},{400, 200},{335, 335}}; // flower coordinates
private static int bWIDTH = 800; // width of window
private static int bHEIGHT = 600;// height of window
private Font font;
private FontMetrics metrics;
ImageIcon grassI = new ImageIcon(this.getClass().getResource("grass.png"));
ImageIcon riverI = new ImageIcon(this.getClass().getResource("river.png"));
private Image grass = grassI.getImage();
private Image river = riverI.getImage();
private House house = new House();
private River river1 = new River();
//private Flower flower = new Flower();
private TitleScreenLayer ts = new TitleScreenLayer();
private Player girlP = new Player();
private static int px = 250;
private static int py = 250;
private boolean visTl = false;
private boolean plant = false;
ArrayList<Flower> flowers= new ArrayList<Flower>();
private long period;
private volatile boolean running = false;
private volatile boolean gameOver = false;
private volatile boolean isPaused = false;
// New stuff for Board2 below
private JLayeredPane lpane;
private JLabel grassLabel;
private JLabel riverLabel;
private JLabel houseLabel;
private JLabel pear1Label;
private JLabel pear2Label;
private JLabel pear3Label;
private JLabel drivewayLabel;
private JLabel girlLabel;
private JProgressBar progressBar;
private JLabel toolLabel;
private JTextArea textBubble;
ImageIcon girlImage = new ImageIcon(girlP.getImage());
int mouseClicks = 0;
CountdownTimer cTimer;
private static String message;
public static String setMessage(String newMessage){
return message = newMessage;
}
private static ImageIcon playerTool = new ImageIcon("BradfordPear.png");
public ImageIcon getPlayerTool(){
return playerTool;
}
public static void setPlayerTool(String image){
playerTool = new ImageIcon(image);
}
public JTextArea getTextBubble(){
return textBubble;
}
public Player getPlayer(){
return girlP;
}
public static int getPlayerX(){
return px;
}
public static int getPlayerY(){
return py;
}
public JLayeredPane getLayeredPane(){
return lpane;
}
public Board2(){
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
//create the layered pane
lpane = new JLayeredPane();
lpane.setPreferredSize(new Dimension(800, 600));
//create the "background" image
ImageIcon image = new ImageIcon("grass.png");
grassLabel = new JLabel(image);
grassLabel.setBounds(0, 0, image.getIconWidth(), image.getIconHeight());
//create the house image
ImageIcon houseImage = new ImageIcon("house.png");
houseLabel = new JLabel(houseImage);
houseLabel.setBounds(-330, -150, image.getIconWidth(), image.getIconHeight());
//create the driveway image
ImageIcon drivewayImage = new ImageIcon("driveway.png");
drivewayLabel = new JLabel(drivewayImage);
drivewayLabel.setBounds(-335, 105, image.getIconWidth(), image.getIconHeight());
//create the river image
ImageIcon riverImage = new ImageIcon("river.png");
riverLabel = new JLabel(riverImage);
riverLabel.setBounds(360, 0, image.getIconWidth(), image.getIconHeight());
//create pear1 image
ImageIcon pear1Image = new ImageIcon("BradfordPear.png");
pear1Label = new JLabel(pear1Image);
pear1Label.setBounds(100, 100, image.getIconWidth(), image.getIconHeight());
//create pear2 image
ImageIcon pear2Image = new ImageIcon("BradfordPear.png");
pear2Label = new JLabel(pear2Image);
pear2Label.setBounds(50, -100, image.getIconWidth(), image.getIconHeight());
//create pear3 image
ImageIcon pear3Image = new ImageIcon("BradfordPear.png");
pear3Label = new JLabel(pear3Image);
pear3Label.setBounds(-100, -50, image.getIconWidth(), image.getIconHeight());
//create initial Player(girl) image
//ImageIcon girlImage = new ImageIcon(girlP.getImage());
girlLabel = new JLabel(girlImage);
girlLabel.setBounds((int)girlP.getPositionX(), (int)girlP.getPositionY(), image.getIconWidth(), image.getIconHeight());
//create progress bar
progressBar = new JProgressBar(JProgressBar.VERTICAL, 0, 10);
progressBar.setValue(0);
progressBar.setBounds(720, 50, 100, 500);
//create timer
JTextField timerField = new JTextField();
cTimer = new CountdownTimer(timerField);
timerField.setBounds(400, 0, 50, 50);
//create toolbox
Toolbox toolbox = new Toolbox();
toolbox.setBounds(550, 0, 250, 50);
//create the text bubble
textBubble = new JTextArea("IDPC is the best coding group ever");
textBubble.setLineWrap(true);
//textBubble.setBounds(200, 200, 100, 100);
//add the background & various images
lpane.add(grassLabel, new Integer(1));
lpane.add(houseLabel, new Integer(2));
lpane.add(riverLabel, new Integer(2));
lpane.add(drivewayLabel, new Integer(2));
lpane.add(pear1Label, new Integer(2));
lpane.add(pear2Label, new Integer(2));
lpane.add(pear3Label, new Integer(2));
lpane.add(progressBar, new Integer(3));
lpane.add(girlLabel, new Integer(3));
lpane.add(timerField, new Integer(2));
lpane.add(toolbox, new Integer(3));
add(lpane);
cTimer.start();
// listen for action events
new ActionListener() {
public void actionPerformed(ActionEvent e) {
girlP.move();
//girlLabel.setLocation(px, py);
}
};
// listen for mouse presses
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
//lpane.remove(textBubble);
mouseClicks+= 1;
testPress(e.getX(), e.getY());
//textBubble.setBounds(e.getX(), e.getY(), 40, 40);
updateProgressBar();
}
});
//listen for player action
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if(e.getClickCount() == 2){
ImageIcon flowerImage = playerTool;
JLabel flowerPanel = new JLabel(flowerImage);
flowerPanel.setBounds((px -((int)girlP.getPositionX() / 2)),
(py - ((int)girlP.getPositionY() / 2)),
flowerImage.getIconWidth(),
flowerImage.getIconHeight());
lpane.add(flowerPanel, new Integer(3));
textBubble.setBounds(e.getX(), e.getY(), 200, 40);
textBubble.replaceSelection(message);
lpane.add(textBubble, new Integer(3));
//lpane.remove(textBubble);
}
}
});
x = 15;
y = 150;
ix = 0;
iy = 0;
dx = .05;
dy = .05;
girlP.setDestination(px, py);
}
public void testPress(int x, int y){
px = x;
py = y;
if (px < (ix + house.getImage().getWidth(this))
&& (py < (iy + house.getImage().getHeight(this)))) {
px = px + (house.getImage().getWidth(this)/3);
py = py + (house.getImage().getHeight(this)/3);
}
if (px > (bWIDTH - river1.getImage().getWidth(this))) {
px = px - 80 - (river1.getImage().getWidth(this)/2);
}
girlLabel.setBounds((px -((int)(girlP.getPositionX()*2.5))),
(py - ((int)(girlP.getPositionY()*2.5))),
girlImage.getIconWidth(), girlImage.getIconHeight());
girlP.setDestination((px-(girlP.getImage().getWidth(this)/2)),
(py-(girlP.getImage().getHeight(this)/2)));
girlP.pinned(x, y);
}
public void updateProgressBar(){
if(progressBar.getValue() == 3){
//progressBar.setBackground(Color.red);
//UIManager.put("progressBar.foreground", Color.RED);
UIDefaults defaults = new UIDefaults();
defaults.put("progressBar[Enabled].foregroundPainter", Color.RED);
progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
progressBar.putClientProperty("Nimbus.Overrides", defaults);
}
progressBar.setValue(mouseClicks);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new TitleScreenLayer();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Here's the player class:
package mod;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.ImageObserver;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class Player {
int tile;
double positionX;
double positionY;
int destinationX;//Used when moving from place to place
int destinationY;
Tool currentTool;
int direction; //Position the image is facing
double dx;
double dy;
int [] pin = new int[10];
private String girl = "girl.png";
ImageIcon ii = new ImageIcon(this.getClass().getResource(girl)); // load girl image
private Image image = ii.getImage();
private boolean visible = true;
public boolean plant = false;
Image playerImage;
public double getPositionX() {
return positionX;
}
public void setPositionX(double positionX) {
this.positionX = positionX;
}
public double getPositionY() {
return positionY;
}
public void setPositionY(double positionY) {
this.positionY = positionY;
}
public Player(){
positionX=30;
positionY=20;
dx = 0.2;
dy = 0.2;
destinationX=(int)positionX;
destinationY=(int)positionY;
//this.playerImage=playerImage;
}
public void doAction() {
//currentTool.getNum();
plant = true;
}
public void pinned(int x, int y) {
if (plant == true) {
pin[0] = x;
pin[1] = y;
}
//plant = false;
}
public void plant(Graphics g, ImageObserver io) {
int x = pin[0];
int y = pin[1];
if (plant == true) {
// g.drawImage(flower.getImage(), x, y, io);
}
}
public void ActionPerformed(ActionEvent e) {
positionX += dx;
positionY += dy;
}
public boolean isVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
public Image getImage() {
return image;
}
public void move(){
//MOVE LEFT AND RIGHT
if(destinationX<positionX){
positionX-=dx;
}
if(destinationX>positionX){
positionX+=dx;
}
//MOVE UP AND DOWN
if(destinationY<positionY){
positionY-=dy;
}
if(destinationY>positionY){
positionY+=dy;
}
}
public double setDx(double speed) {
dx = speed;
return dx;
}
public double setDy(double speed) {
dy = speed;
return dy;
}
public void TileIn(int px, int py)
{
px=destinationX;
py=destinationY;
int tileX=1;
int tileY = 1;
int bWIDTH=800;
int bHEIGHT=600;
if(px >= 0 && px <= 800*.1)
{
tileX=2;
}
else if(px> bWIDTH*.1 && px <= bWIDTH*.2)
{
tileX=3;
}
else if(px > bWIDTH*.2 && px <= bWIDTH*.3)
{
tileX=4;
}
else if(px > bWIDTH*.3 && px <= bWIDTH*.4)
{
tileX=5;
}
else if(px > bWIDTH*.4 && px <= bWIDTH*.5)
{
tileX=6;
}
else if(px > bWIDTH*.5 && px <= bWIDTH*.6)
{
tileX=7;
}
else if(px > bWIDTH*.6 && px <= bWIDTH*.7)
{
tileX=8;
}
else if(px > bWIDTH*.7 && px <= bWIDTH*.8)
{
tileX=9;
}
else if(px > bWIDTH*.8 && px <= bWIDTH*.9)
{
tileX=10;
}
else if(px > bWIDTH*.9 && px <= bWIDTH)
{
tileX=11;
}
if(py >= 0 && py <= bHEIGHT*.1)
{
tileY=2;
}
else if(py> bHEIGHT*.1 && py <= bHEIGHT*.2)
{
tileY=3;
}
else if(py > bHEIGHT*.2 && py <= bHEIGHT*.3)
{
tileY=4;
}
else if(py > bHEIGHT*.3 && py <= bHEIGHT*.4)
{
tileY=5;
}
else if(py > bHEIGHT*.4 && py <= bHEIGHT*.5)
{
tileY=6;
}
else if(py > bHEIGHT*.5 && py <= bHEIGHT*.6)
{
tileY=7;
}
else if(py > bHEIGHT*.6 && py <= bHEIGHT*.7)
{
tileY=8;
}
else if(py > bHEIGHT*.7 && py <= bHEIGHT*.8)
{
tileY=9;
}
else if(py > bHEIGHT*.8 && py <= bHEIGHT*.9)
{
tileY=10;
}
else if(py > bHEIGHT*.9 && py <= bHEIGHT)
{
tileY=11;
}
System.out.println("Grid X: " + tileX + " Grid Y: " + tileY);
}
public void setDestination(int x, int y){
destinationX=x;
destinationY=y;
System.out.println(x + "," + y);
TileIn(x,y);
}
// public void tileIn(int a)
// {
//
// b=destinationY;
// return TileIn(x,y)
// }
public void draw(Graphics g,ImageObserver io){
g.drawImage(image, (int)positionX,(int) positionY,io);
}
}
Here is the main class:
package mod;
import java.awt.Container;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
public class Skeleton2 extends JFrame /*implements WindowListener*/{
private static int DEFAULT_FPS = 80;
private Board2 bd;
public Skeleton2(long period) {
super("Skeleton");
makeGUI(period);
//addWindowListener(this);
pack();
setResizable(false);
setVisible(true);
}
public void makeGUI(long period) {
Container c = getContentPane();
bd = new Board2();
c.add(bd, "Center");
} // end of makeGUI()
//==================================================================================
// Window Events
//==================================================================================
/*
public void windowActivated(WindowEvent e) {
bd.resumeGame();
}
public void windowDeactivated(WindowEvent e) {
bd.pauseGame();
}
public void windowDeiconified(WindowEvent e) {
bd.resumeGame();
}
public void windowIconified(WindowEvent e) {
bd.pauseGame();
}
public void windowClosing(WindowEvent e) {
bd.stopGame();
}
*/
public void windowClosed(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
//==================================================================================
public static void main(String[] args) {
int fps = DEFAULT_FPS;
long period = (long) 1000.0/fps;
new Skeleton2(period);
System.out.println("Period: " + period);
}
}
Not instantly, but rather "walk" to the given coordinate.
Then you need to use a Swing Timer. The Timer is used to schedule the animation. So you would need to calculate a path between the two points. Every time the Timer fires you would move the label a few pixels until it reaches it's destination.
There is no need to do custom painting for this. A JLabel will work fine. The hard part is calculating the path you want the character to take. Also make sure you use a null layout on the panel you add the JLabel to, which means you will also need to set the size of the label equal to the preferred size of the label.
You should rather use g.drawImage in your component paintComponent method.

Drawing a line using a Mouse Motion Listener

I'm new at using actionListener and mouselistner. I want to track the Mouse movements and connect the dots as I go. So it will be one continuous line. I am using the MouseMotionListener every time I move the mouse across the screen and get a new set of points. I am not using mousePressed or mouseReleased.
Everytime I move the mouse, I can get every point of where my mouse's position is on my JPanel to show up on my results window, but in order to draw the line between two points, I'm not sure how to decipher between each different set of points so I can have a beginning and ending set of points to use for drawing a line? I checked through here and the API and I'm stuck.
I was asked to put more code and so I gave you my code.
I am basically creating a Jpane that tracks mouse movement when the Track Mouse button or Draw Track Radio button is pressed
These results will print out as (x,y) on the output screen
FYI: You can also draw circles once the Draw circles RadioButton is checked
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class MouseTest {
private JFrame frame;
private boolean tracking;
private boolean drawing;
private boolean connectdots;
private int xstart;
private int ystart;
private int xend;
private int y;
private int x;
private int yend;
private int borderWidth = 5;
String drawCircles = "Draw Circles";
String drawTrack = "Draw Track";
public static void main (String [] arg) {
MouseTest first = new MouseTest();
}//main
$
public MouseTest() {
tracking = false;
frame = new JFrame();
frame.setBounds(250,98,600,480);
frame.setTitle("Window number three");
Container cp = frame.getContentPane();
JButton track = new JButton("Track Mouse");
track.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
trackMouse();
}
});
JPanel top = new JPanel();
top.add(track);
cp.add(top,BorderLayout.NORTH);
MyPanel pane = new MyPanel();
cp.add(pane,BorderLayout.CENTER);
pane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
xstart = e.getX();
ystart = e.getY();
}
public void mouseReleased(MouseEvent e) {
xend = e.getX();
yend = e.getY();
if (xend < xstart) { int tmp = xstart; xstart = xend; xend = tmp; }
if (yend < ystart) { int tmp = ystart; ystart = yend; yend = tmp; }
frame.repaint();
}
});
pane.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (tracking) {
x = e.getX();
y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
});
JRadioButton circleButton = new JRadioButton(drawCircles);
circleButton.setMnemonic(KeyEvent.VK_B);
circleButton.setActionCommand(drawCircles);
circleButton.setSelected(false);
JRadioButton trackButton = new JRadioButton(drawTrack);
trackButton.setMnemonic(KeyEvent.VK_C);
ButtonGroup group = new ButtonGroup();
group.add(circleButton);
group.add(trackButton);
JPanel radioPanel = new JPanel(new GridLayout(2,0));
radioPanel.add(circleButton);
radioPanel.add(trackButton);
cp.add(radioPanel,BorderLayout.EAST);
drawing = false;
connectdots = false;
circleButton.addActionListener(new ActionListener() { //Set drawing to true when the button is clicked
public void actionPerformed(ActionEvent ae) {
tracking = !tracking;
drawCircles();
}
});
trackButton.addActionListener(new ActionListener() { //Set drawing to true when the button is clicked
public void actionPerformed(ActionEvent ae) {
drawing = false;
tracking = true;
connectDots();
}
});
frame.setVisible(true);
}//constructor
$
public void trackMouse() {
tracking = !tracking;
}//trackMouse
public void msg(String s) { //new method to simplify the system.out.print method
System.out.println(s);
}
public void drawCircles() {
drawing = true;
}//Allow Drawing of Circles
public void connectDots() {
connectdots = !connectdots;
}//Trying to use for connecting the mouse motion listener points when tracking
$
public class MyPanel extends JPanel {
ArrayList<Circle> circles = new ArrayList<Circle>();
public void paintComponent(Graphics g) {
int width = this.getWidth();
int height = this.getHeight();
msg("H = " + height + ", w = " + width);
g.setColor(Color.BLACK);
Circle c = new Circle(xstart, ystart);
circles.add(c);
if (drawing){
for(int k=0; k<circles.size(); k++){
circles.get(k).draw(g);
}
} // draw the circle
if (connectdots && tracking) { //trying to use for drawing the lines
g.drawLine(x,y,x,y);
}
for (int delta = 0; delta < borderWidth; delta++) {
g.drawRect(delta,delta,width-(2*delta),height-(2*delta));
}
if (xstart != xend || ystart != yend) {
int red = (int)(256*Math.random());
int green = (int)(256*Math.random());
int blue = (int)(256*Math.random());
g.setColor(new Color(red, green, blue));
msg("Colors are: " + red + " - " + green + " - " + blue );
msg("Drawing from: (" + xstart + ", " + ystart + ") to (" + xend + ", " + yend + ")");
msg("Width is " + (xend-xstart) + " - Height is " + (yend-ystart));
g.fillRect(xstart,ystart,xend-xstart,yend-ystart);
}
}
}
}
$
public class Circle {
// instance variables:
int radius; //random radius
int x, y; // coords of the center point
private Graphics g;
public Circle(int xIn, int yIn) {
radius = (int)(127*Math.random());
x = xIn;
y = yIn;
}
public void draw(Graphics g){
g.drawOval(x-radius, y-radius, radius, radius);
g.fillOval(x-radius, y-radius, radius, radius);
int red = (int)(256*Math.random());
int green = (int)(256*Math.random());
int blue = (int)(256*Math.random());
g.setColor(new Color(red, green, blue));
}
public int getX(int xstart) {
// TODO Auto-generated method stub
return x;
}
public int getY(int ystart) {
// TODO Auto-generated method stub
return y;
}
}
You just have to save x and y in some attribute for your class (like lastX and lastY.) When you get the event the second time, your first point coordinates are saved in your attributes and you can then draw your line. This new point has to be saved too to serve as your new lastX and lastY.
Even better: since you'll probably need to redraw your lines each frame (if you want a set of lines and not just a single line to be drawn each frame), use Point to save your coordinates and some kind of list like ArrayList. Save the full set of tracked points in an ArrayList<Point> and then draw each frame iterating over this list.
An example of an sscce:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class Foo3 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private boolean tracking = false;
private int x, y;
public Foo3() {
add(new JToggleButton(new AbstractAction("TrackMouse") {
public void actionPerformed(ActionEvent ae) {
trackMouse(ae);
}
}));
MyMouseAdapter myMA = new MyMouseAdapter();
addMouseMotionListener(myMA);
}
private void trackMouse(ActionEvent ae) {
JToggleButton toggleBtn = (JToggleButton) ae.getSource();
tracking = toggleBtn.isSelected();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void msg(String message) {
System.out.println(message);
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
if (tracking) {
x = e.getX();
y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
}
private static void createAndShowGui() {
Foo3 mainPanel = new Foo3();
JFrame frame = new JFrame("MouseMotion Eg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Edit: Example 2
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class MouseTestHovercraft extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final int MAX_CLR = 5;
private static final Color CURRENT_LIST_COLOR = new Color(190, 190, 255);
private List<Color> colors = new ArrayList<Color>();
private boolean tracking = false;
private List<Point> currentList = null;
private BufferedImage bufferedImage = new BufferedImage(PREF_W, PREF_H,
BufferedImage.TYPE_INT_ARGB);
private Random random = new Random();
public MouseTestHovercraft() {
for (int redIndex = 0; redIndex < MAX_CLR; redIndex++) {
int r = (redIndex * 256) / (MAX_CLR - 1);
r = (r == 256) ? 255 : r;
for (int greenIndex = 0; greenIndex < MAX_CLR; greenIndex++) {
int g = (greenIndex * 256) / (MAX_CLR - 1);
g = (g == 256) ? 255 : g;
for (int blueIndex = 0; blueIndex < MAX_CLR; blueIndex++) {
int b = (blueIndex * 256) / (MAX_CLR - 1);
b = (b == 256) ? 255 : b;
Color c = new Color(r, g, b);
colors.add(c);
}
}
}
add(new JToggleButton(new AbstractAction("TrackMouse") {
public void actionPerformed(ActionEvent ae) {
trackMouse(ae);
}
}));
add(new JButton(new AbstractAction("Clear Image") {
public void actionPerformed(ActionEvent e) {
bufferedImage = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_INT_ARGB);
repaint();
}
}));
MyMouseAdapter myMA = new MyMouseAdapter();
addMouseListener(myMA);
addMouseMotionListener(myMA);
}
private void trackMouse(ActionEvent ae) {
JToggleButton toggleBtn = (JToggleButton) ae.getSource();
tracking = toggleBtn.isSelected();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void msg(String message) {
System.out.println(message);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bufferedImage, 0, 0, null);
if (currentList != null) {
drawList(g, currentList, CURRENT_LIST_COLOR, 1f);
}
}
private void drawList(Graphics g, List<Point> ptList, Color color,
float strokeWidth) {
if (ptList.size() > 1) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
g2.setStroke(new BasicStroke(strokeWidth));
for (int j = 0; j < ptList.size() - 1; j++) {
int x1 = ptList.get(j).x;
int y1 = ptList.get(j).y;
int x2 = ptList.get(j + 1).x;
int y2 = ptList.get(j + 1).y;
g2.drawLine(x1, y1, x2, y2);
}
g2.dispose();
}
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
if (tracking && e.getButton() == MouseEvent.BUTTON1) {
currentList = new ArrayList<Point>();
currentList.add(e.getPoint());
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (tracking && e.getButton() == MouseEvent.BUTTON1) {
currentList.add(e.getPoint());
Graphics2D g2 = bufferedImage.createGraphics();
Color color = colors.get(random.nextInt(colors.size()));
drawList(g2, currentList, color, 3f);
currentList = null;
repaint();
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (tracking && currentList != null) {
currentList.add(e.getPoint());
repaint();
}
}
}
private static void createAndShowGui() {
MouseTestHovercraft mainPanel = new MouseTestHovercraft();
JFrame frame = new JFrame("MouseMotion Eg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Categories