java


Java (Swing) - How to rotate a bunch of lines?


I've been looking for this online, but I can't seem to find how to rotate a bunch of lines. I made a "plane" with the Graphics.drawLine() function, but I want to know how to rotate the whole thing 90 degrees to the right when it hits a wall. Here is my current code:
/* MovePlane
* Moves plane to the right, down, left, up, and repeats using Timer object
*/
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class MovePlane extends JPanel implements ActionListener {
private int delay = 5;
private Timer timer;
private int x = 10; // x position
private int y = 10; // y position
private boolean right = true;
private boolean up = true;
public MovePlane() {
timer = new Timer(delay, this);
timer.start(); // start the timer - infinite
}
public void actionPerformed(ActionEvent e) {
// will run when the timer fires
repaint();
}
public void paintComponent(Graphics g) {
// both paint and paintComponent work - difference?
super.paintComponent(g); // call superclass's paintComponent
g.drawLine(x,y,x+20,y); // body - drawn in terms of x
g.drawLine(x+15,y-5,x+15,y+5); // wing
g.drawLine(x,y-2,x,y+2);
if (right && up) {
x++;
if (x == getWidth()-25) {
right = false;
up = false;
}
} else if (!right && !up) {
y++;
if (y == getHeight()-10) {
up = true;
}
} else {
if (x <= getWidth()-15 && x > 0) {
x--;
}
if (x == 0) {
y--;
}
if (y == 10) {
right = true;
}
}
}
public static void main(String args[]) {
JFrame frame = new JFrame("Move Plane");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MovePlane bp = new MovePlane();
frame.add(bp);
frame.setSize(300, 300); // set frame size
frame.setVisible(true); // display frame
}
}
You need to change it everytime you change the direction, so, you need to move your g.drawLine(...) calls inside each if conditions...
But while rotating the plane, you also need to take care of the "bounds" or the limits of the screen, so, I modified if (x == 0) and ... && x > 0 conditions to have a gap of 20 instead...
Let's start for the plane going from left to right:
g.drawLine(x, y, x + 20, y); // body - drawn in terms of x
g.drawLine(x + 15, y - 5, x + 15, y + 5); // wing
g.drawLine(x, y - 2, x, y + 2);
This is telling us that:
Your plane's body length is 20
Your wings are 15 units from the back
Your tail is right on the back
So, to change it to move from left to right, we need to invert the wings and tail positions...
Plane lenght is still the same
Wings are now 5 units from the back
Tail is now on the front
Then, we have this code:
g.drawLine(x, y, x + 20, y); // Body length 20
g.drawLine(x + 5, y - 5, x + 5, y + 5); // Wing's are 5 units from the front
g.drawLine(x + 20, y - 2, x + 20, y + 2); // Tail is on the front (at body's length)
And for when going down:
Body's length is now on Y axis
Wings should be at 15 units from the back
Tail is at the back
So we have:
g.drawLine(x, y, x, y + 20); // Body is now on Y axis
g.drawLine(x - 5, y + 15, x + 5, y + 15); // Wings are 15 units from the back
g.drawLine(x - 2, y, x + 2, y); // Tail is on the back
And applying same logic as when going from right to left:
g.drawLine(x, y + 20, x, y);
g.drawLine(x - 5, y + 5, x + 5, y + 5);
g.drawLine(x - 2, y + 20, x + 2, y + 20);
Then your paintComponent(...) method looks like this:
public void paintComponent(Graphics g) {
// both paint and paintComponent work - difference?
super.paintComponent(g); // call superclass's paintComponent
if (right && up) {
g.drawLine(x, y, x + 20, y); // body - drawn in terms of x
g.drawLine(x + 15, y - 5, x + 15, y + 5); // wing
g.drawLine(x, y - 2, x, y + 2);
x++;
if (x == getWidth() - 25) {
right = false;
up = false;
}
} else if (!right && !up) {
g.drawLine(x, y, x, y + 20); // body - drawn in terms of x
g.drawLine(x - 5, y + 15, x + 5, y + 15); // wing
g.drawLine(x - 2, y, x + 2, y);
y++;
if (y == getHeight() - 25) {
up = true;
}
} else {
if (x <= getWidth() - 15 && x > 20) {
g.drawLine(x, y, x + 20, y); // body - drawn in terms of x
g.drawLine(x + 5, y - 5, x + 5, y + 5); // wing
g.drawLine(x + 20, y - 2, x + 20, y + 2);
x--;
}
if (x == 20) {
g.drawLine(x, y, x, y + 20); // body - drawn in terms of x
g.drawLine(x - 5, y + 5, x + 5, y + 5); // wing
g.drawLine(x - 2, y + 20, x + 2, y + 20);
y--;
}
if (y == 10) {
right = true;
}
}
}
And that's it! Here's an image showing how it looks like:
Additional tips:
Don't call frame.setSize() but override MovePlane's JPanel getPreferredSize() to return a fixed size of 300, 300.
Always place your GUI in the Event Dispatch Thread (EDT) by wrapping your main method like this:
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//Your code here
}
});
}
Related to tip #1, call frame.pack(); instead of frame.setSize() after overriding JPanel's getPreferredSize() :)

Related Links

How to configure a Yarn application that interacts with HDFS and Hbase in a secure mode?
Sort arrays by elements
Spring Boot JPA Hibernate JVM heap is not released
Spring service method and a complex validation logic/rules
I need a better way to reduce the line of codes which has a lot of if statements with method calls in conditions
How to apply AspectJ in GWT application for logging?
Appending to a Textfile while keeping the stored data in the TextFile
Android SOAP response error '400 Bad Request'
The second query is efficient and does not require a table join
Show formatted number and save double value
Android ImageView shows as the correct size for an image, but doesn't display the image
Using JGit to create a tool that clones repositories out of properties
In Spring data elasticsearch is there any clear syntax to query which mapping value is HashMap
Need to drag imageview to its boundaries
How to do Post for https using Apache client
Android Studio get location from Google Maps api

Categories

HOME
multithreading
clips
webpack
urbancode
sqlite3
ebean
ojdbc
pivotal-cloud-foundry
synchronization
slick-slider
session-variables
nano-server
apache-cayenne
fallback
decimal
seaborn
finite-automata
reactive-cocoa
flux
django-cms
riot.js
clickonce
mmap
tibco-mdm
format-specifiers
hammerspoon
android-widget
facebook-access-token
url-scheme
bootstrap-material-design
fgetcsv
strncpy
publish
jaxb2
windows-server-2000
fabric8
contact-form
normal-distribution
catalog
file-format
main
streamsets
starteam
c11
az-application-insights
uft-api
reportbuilder
ws-security
sql-server-agent
reportingservices-2005
nxlog
arena-simulation
turbogears
flashair
s
apple-news
qwt
parentheses
ionicons
csound
nodebb
sqlbulkcopy
imanage
jspdf-autotable
spring-mongodb
time-and-attendance
passport-google-oauth
url-masking
py2app
multiple-regression
master-slave
whois
pickadate
php-internals
historian
cyclomatic-complexity
event-bubbling
createprocessasuser
processmodel
fluid-dynamics
census
proj4js
kineticjs
csquery
dia
android-nested-fragment
nsbutton
wordpress-theme-customize
zend-route
article
funcunit
hippomocks
comexception
dealloc
srs
viadeo
gnu-smalltalk
runtime.exec
spring-io
blending
chronoforms
jquery-mobile-dialog
seed
interface-orientation
enterprisedb
jelly
free-variable
jquery-knob
rdoc
getmessage
parametric-equations
ticoredatasync
coredump
xmemcached
propagation
xfbml
html-input
dmx512
thunderbird-lightning
memory-size
phonon
premature-optimization

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App