I have Jbutton (represented by the envelope) and an ArrayList of lines which the Envelope will go along. Can anyone help me? any ideas or tutorial will be much appreciated.
-
1Is `JButton` necessary, what if you can use a simple `JLabel/JPanel`, if you not performed any action with this envelope entity. Anyways, you can take some idea from [this](http://stackoverflow.com/a/13795187/1057230), though you can improve on the logic thingy. – nIcE cOw Aug 10 '13 at 07:11
-
I do need JButton as a popup menu appears when i click on it. – ht.luvit Aug 10 '13 at 07:22
-
1Any component can have a MouseListerner attached to it, just saying – MadProgrammer Aug 10 '13 at 07:31
3 Answers
I assume that your goal is to animate the envelope along the line to provide an animation of data being transferred.
For every line you need first to find the line equation. A line equation is in the form y = a * x + b
. If you already have that in the List
you mention then that's fine. If on the other hand you have two points instead (start and end positions), use those with the above equation to find a
, b
for each line.
After you have the equations for your lines then you can use an animation (probably with a SwingWorker
or a SwingTimer
) that would increase the x
coordinate of your envelope at regular intervals and then use the line equation to calculate the new y
coordinate.
I hope that helps
Update: Added code snippet for a moving box using a SwingTimer
for demonstration
package keymovement;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
public class TestMovingObject {
static class Envelope {
double x;
double y;
void setPosition(double x, double y) {
this.x = x;
this.y = y;
}
}
static class DrawArea extends JPanel {
Envelope envelope = new Envelope();
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
int x = (int) Math.round(envelope.x);
int y = (int) Math.round(envelope.y);
g.drawRect(x, y, 20, 20);
}
public Envelope getEnvelope() {
return envelope;
}
}
/**
* @param args
*/
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
throw new RuntimeException(e);
}
JFrame window = new JFrame("Moving box");
window.setPreferredSize(new Dimension(500, 400));
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final DrawArea mainArea = new DrawArea();
window.add(mainArea);
window.pack();
window.setLocationRelativeTo(null);
window.setVisible(true);
int delay = 20; // execute every 20 milliseconds i.e. 50 times per second
Timer timer = new Timer(delay, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Envelope envelope = mainArea.getEnvelope();
double x = envelope.x + 1; // use smaller increments depending on the desired speed
double y = 0.5 * x + 2; // moving along the line y = 0.5 * x + 2
envelope.setPosition(x, y);
mainArea.repaint();
}
});
timer.setRepeats(true);
timer.start();
}
});
}
}

- 4,786
- 18
- 32
-
Thanks for your helpful answers! I partly know how should I do, regarding the Swingworker and SwingTimer, can you tell me a very simple example? as this is my first time encounter with runnable stuff. – ht.luvit Aug 10 '13 at 07:31
-
@ht.luvit see my updated answer. A rather crude example of moving a box along a line using a `SwingTimer` – c.s. Aug 10 '13 at 08:04
Can you tell me a very simple example?
In this game, enemies advance toward the player one row or column at time, without calculating any intermediate points. When the destination is stationary, the path is a straight line. The animation is paced by a javax.swing.Timer
. See RCModel#move()
and RCView#timer
for the implementation.

- 203,806
- 29
- 246
- 1,045
There are some mathematic things to do for you. Check out this article: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
This simple algorithm will tell you each X,Y coordinate on a line between two points. You could use this algorithm to compute all of the positions it needs to visit, store the coordinates in an array, and iterate over the array as you update the position.
There is an alternative helper class:
package snippet;
import java.awt.geom.Point2D;
public class MyVelocityCalculator {
public static void main(String[] args) {
Point2D.Double currentPosition = new Point2D.Double();
Point2D.Double destinationPosition = new Point2D.Double();
currentPosition.setLocation(100, 100);
destinationPosition.setLocation(50, 50);
Double speed = 0.5;
System.out.println("player was initially at: " + currentPosition);
while (currentPosition.getX() > destinationPosition.getX()
&& currentPosition.getY() > destinationPosition.getY()) {
Point2D.Double nextPosition = MyVelocityCalculator.getVelocity(currentPosition, destinationPosition, speed);
System.out.println("half seconds later player should be at: " + nextPosition);
currentPosition = nextPosition;
}
System.out.println("player destination is at: " + destinationPosition);
}
public static final Point2D.Double getVelocity(Point2D.Double currentPosition, Point2D.Double destinationPosition,
double speed) {
Point2D.Double nextPosition = new Point2D.Double();
double angle = calcAngleBetweenPoints(currentPosition, destinationPosition);
double distance = speed;
Point2D.Double velocityPoint = getVelocity(angle, distance);
nextPosition.x = currentPosition.x + velocityPoint.x;
nextPosition.y = currentPosition.y + velocityPoint.y;
return nextPosition;
}
public static final double calcAngleBetweenPoints(Point2D.Double p1, Point2D.Double p2) {
return Math.toDegrees(Math.atan2(p2.getY() - p1.getY(), p2.getX() - p1.getX()));
}
public static final Point2D.Double getVelocity(double angle, double speed) {
double x = Math.cos(Math.toRadians(angle)) * speed;
double y = Math.sin(Math.toRadians(angle)) * speed;
return (new Point2D.Double(x, y));
}
}
Instead of print out the position on console you need to draw the control at this position to you graphics element.

- 3,719
- 14
- 40
- 62