I'm Making a program that displays a building, some clouds, and trees with Java Graphics. I would like to use a Timer to scroll the clouds across the screen. I'm not sure how to use the timer to continually loop the clouds after it reaches the end of the JFrame
timer is on 126-147
cloud method is on 184 - 239
I have tried to put all the Timer code within the Cloud drawing method but I can't figure out how to use the variable that is tied to the timer to make the clouds move inside the method for the clouds. Currently, I just have most of the timer stuff outside of the method, and then using 3 different cloud methods, which is redundant.
I'm very new to java so sorry if I have basic mistakes.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Elevator extends JFrame implements ActionListener {
private final int DISPLAY_WIDTH = 800;
private final int DISPLAY_HEIGHT = 600;
private JPanel guiPanel, buttonPanel;
private DisplayPanel display;
private JLabel Title;
private JButton Floor;
private JComboBox Select;
int locX, locY;
final int LIMIT = 10;
final int NUM_ROWS = 10;
final int WINDOWWIDTH = 12;
final int WINDOWHEIGHT = 25;
final int WINDOWSPACING = 10;
final int FLOORSPACING = 30;
final int FLOOROFFSET = -10;
final int ELEVATOR_COLUMN = 5;
private static final int NUM_ITERATIONS = 10; //number of floors for combo box selection
private int lvlChoice; //variable holding elevator level choice for item event
private int buildX, buildY, buildW, buildH; //building height dem
Color drkGrn = new Color ( 49, 216, 91); //building ground color
Color flWind = new Color (163, 156, 77); //default floor window color
Color bldCol = new Color (176, 201, 212); // building color
Color crntFl = new Color (255, 247, 0); //current floor color for elevator
Color blu1 = new Color ( 157, 215, 255 ); //cloud colors
Color blu2 = new Color (93, 172, 227);
Color blu3 = new Color ( 62, 167, 240);
Color blu4 = new Color (136, 156, 169);
Color blu5 = new Color (209, 230, 245);
Color plmLeaf = new Color ( 6, 145, 84);
Color trunk =new Color ( 170, 85, 0);
//graphics variables
final int tWidth = 10;
final int tHeiht =120;
public static void main(String[] args) {
Elevator frame = new Elevator();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.initializeVariables();
frame.setUpGUI();
frame.pack();
frame.setVisible(true);
}
public void initializeVariables() {
locX = 300;
locY = 150;
buildX = locX-20;
buildY = locY-10;
buildH =375;
buildW =250;
lvlChoice = 1;
}
public void setUpGUI() {
Container window = getContentPane(); //you attach Jcomponents to this pannel
display = new DisplayPanel();
guiPanel = new JPanel(new FlowLayout());
buttonPanel = new JPanel(new FlowLayout());
//TODO add title panel
/* Title = new JLabel("Elevator");
Title.setFont(new Font(" San Serif", Font.PLAIN, 20));
titlePanel.add(Title);*/
Floor =new JButton("Floor");
Floor.addActionListener(this);
Select = new JComboBox();
for (int i = 0; i < NUM_ITERATIONS; i++) {
Select.addItem(String.valueOf(i + 1)); //this takes the int value and the parses it to a string
}
buttonPanel.add(Select);
buttonPanel.add(Floor);
window.add(buttonPanel, BorderLayout.NORTH);
window.add(guiPanel, BorderLayout.SOUTH);
window.add(display, BorderLayout.CENTER);
}
//cloude1 timer, moviment
Timer tm1 = new Timer(60, this);
int x1 = 800, velX1 = 3; //position of x on cloud and velociity of cloudes
//cloude1 timer, moviment
Timer tm2 = new Timer(50, this);
int x2 = 700, velX2 = 2; //position of x on cloud and velociity of cloudes
//cloude1 timer, moviment
Timer tm3 = new Timer(75, this);
int x3 = 777, velX3 = 2; //position of x on cloud and velociity of cloudes
@Override
public void actionPerformed(ActionEvent e) {
lvlChoice = Integer.parseInt((String) Select.getSelectedItem());
display.repaint();
//make only one of these simplfiy the "x1" to x
x1 = x1 - velX1; //every 2 milliseconds and 2 to the position of x whitch starts at 0
x2 = x2 - velX2; //every 2 milliseconds and 2 to the position of x whitch starts at 0
x3 = x3 - velX3; //every 2 milliseconds and 2 to the position of x whitch starts at 0
}
class DisplayPanel extends JPanel {
DisplayPanel() {
setPreferredSize(new Dimension(DISPLAY_WIDTH, DISPLAY_HEIGHT));
this.setBackground(Color.WHITE);
}
//executes all paint methods
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
backDrop(g2d);
cloud1(g2d, 100, 45);
cloud3(g2d, 50, 30);
buildingLoop(g2d);
cloud2(g2d, 240, 40);
tree(g2d, 140, 400);
tree(g2d, 500, 400);
tree(g2d, 650, 470);
tree(g2d, 600, 420);
tree(g2d, 190, 390);
tree(g2d, 45, 425);
tree(g2d, 75, 450);
}
//static background objects (ground, trees, ect..)
public void backDrop(Graphics2D g2d) {
g2d.setColor(drkGrn);
g2d.fillRect(0,500,getWidth(), getHeight());
}
//new method custom for cloudes
public void cloud1(Graphics2D g2d, int y, int CLDSIZE) {
//cloud 1
//y starts at 100 to be put in method argument
g2d.setColor(blu4);
g2d.fillOval(x1, y, CLDSIZE, CLDSIZE);
g2d.setColor(blu1);
g2d.fillOval(x1 + 15, y-10, CLDSIZE, CLDSIZE);
g2d.setColor(blu3);
g2d.fillOval(x1 + 30, y+10, CLDSIZE, CLDSIZE);
g2d.setColor(blu2);
g2d.fillOval(x1 + 45, y-10, CLDSIZE, CLDSIZE);
g2d.setColor(blu5);
g2d.fillOval(x1 + 57, y, CLDSIZE, CLDSIZE);
tm1.start(); //start the timer
}
public void cloud2(Graphics2D g2d, int y, int CLDSIZE) {
//cloud 2
g2d.setColor(blu5);
g2d.fillOval(x2, y, CLDSIZE,CLDSIZE);
g2d.setColor(blu4);
g2d.fillOval(x2+15, y-20, CLDSIZE,CLDSIZE);
g2d.setColor(blu2);
g2d.fillOval(x2+30, y+10, CLDSIZE,CLDSIZE);
g2d.setColor(blu3);
g2d.fillOval(x2+45, y-20, CLDSIZE,CLDSIZE);
g2d.setColor(blu1);
g2d.fillOval(x2+57, y, CLDSIZE,CLDSIZE);
tm2.start(); //start the timer
}
public void cloud3(Graphics2D g2d, int y, int CLDSIZE) {
//cloud 3
//y starts at 30
g2d.setColor(blu3);
g2d.fillOval(x3, y, CLDSIZE,CLDSIZE);
g2d.setColor(blu2);
g2d.fillOval(x3+15, y-10, CLDSIZE,CLDSIZE);
g2d.setColor(blu4);
g2d.fillOval(x3+30, y+10, CLDSIZE,CLDSIZE);
g2d.setColor(blu5);
g2d.fillOval(x3+45, y-10, CLDSIZE,CLDSIZE);
g2d.setColor(blu1);
g2d.fillOval(x3+57, y, CLDSIZE,CLDSIZE);
tm3.start(); //start the timer
}
public void tree(Graphics2D g2d, int xPoint, int yPoint){
int leafSize =25;
g2d.setColor(trunk);
g2d.fillRect(xPoint+25,yPoint,tWidth, tHeiht);
g2d.setColor(plmLeaf);
g2d.fillOval(xPoint,yPoint, leafSize, leafSize);
g2d.fillOval(xPoint+5,yPoint-10, leafSize, leafSize);
g2d.fillOval(xPoint+5,yPoint+10, leafSize, leafSize);
g2d.fillOval(xPoint+10,yPoint, leafSize, leafSize);
g2d.fillOval(xPoint+10,yPoint+10, leafSize, leafSize);
g2d.fillOval(xPoint+30,yPoint-10, leafSize, leafSize);
g2d.fillOval(xPoint+30,yPoint+10, leafSize, leafSize);
g2d.fillOval(xPoint+35,yPoint, leafSize, leafSize);
g2d.fillOval(xPoint+35,yPoint+10, leafSize, leafSize);
}
//building the building and windows for the building
public void buildingLoop(Graphics2D g2d) {
g2d.setColor(bldCol);
g2d.fillRect(buildX, buildY, buildW, buildH);
g2d.setColor(flWind);
for (int j = 1; j <=NUM_ROWS; j++) { //draws row
for (int i = 0; i <= LIMIT; i++) { //draws window's
if (i == ELEVATOR_COLUMN && j == NUM_ROWS - lvlChoice + 1) {
g2d.setColor(crntFl);
}
g2d.fillRect (i* (WINDOWWIDTH + WINDOWSPACING) + buildX + WINDOWSPACING, buildY + j * FLOORSPACING - FLOOROFFSET, WINDOWWIDTH , WINDOWHEIGHT);
g2d.setColor(flWind);
}
}
}
}
}
I have tried to put all the Timer code within the Cloud drawing method but I can't figure out how to use the variable that is tied to the timer and get that value passed from the actual parameter that is entered from the method.
Currently, I just have most of the timer stuff outside of the method, and then using 3 different cloud methods, which is redundant.
Here is how I'd write it: If you have any questions you're welcome to ask :)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Elevator extends JFrame implements ActionListener
{
private final int DISPLAY_WIDTH = 800;
private final int DISPLAY_HEIGHT = 600;
private JPanel guiPanel, buttonPanel;
private DisplayPanel display;
private JLabel Title;
private JButton Floor;
private JComboBox Select;
int locX, locY;
final int LIMIT = 10;
final int NUM_ROWS = 10;
final int WINDOWWIDTH = 12;
final int WINDOWHEIGHT = 25;
final int WINDOWSPACING = 10;
final int FLOORSPACING = 30;
final int FLOOROFFSET = -10;
final int ELEVATOR_COLUMN = 5;
private static final int NUM_ITERATIONS = 10; // number of floors for combo box selection
private int lvlChoice; // variable holding elevator level choice for item event
private int buildX, buildY, buildW, buildH; // building height dem
Color drkGrn = new Color(49, 216, 91); // building ground color
Color flWind = new Color(163, 156, 77); // default floor window color
Color bldCol = new Color(176, 201, 212); // building color
Color crntFl = new Color(255, 247, 0); // current floor color for elevator
// an array with all your clouds
private Cloud[] clouds;
private Tree[] trees;
public static void main(String[] args)
{
Elevator frame = new Elevator();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
// added the cloud initialization in there
frame.initializeVariables();
frame.setUpGUI();
frame.pack();
frame.setVisible(true);
// starts ticking each 30 ms
frame.tick();
}
private void tick()
{
// while loop for ever and ever
while (true)
{
// ticks all the clouds
for (int i = 0; i < clouds.length; i++)
{
clouds[i].tick();
}
// updates the JFrame graphics
display.repaint();
// pauses the ticking for 30 ms
try
{
Thread.sleep(30);
} catch (InterruptedException e)
{
}
}
}
public void initializeVariables()
{
locX = 300;
locY = 150;
buildX = locX - 20;
buildY = locY - 10;
buildH = 375;
buildW = 250;
lvlChoice = 1;
// puts 3 clouds in our array
clouds = new Cloud[] { new Cloud(800, 100, 45, 3, true), new Cloud(700, 50, 30, 2, false),
new Cloud(777, 240, 40, 2, false), };
trees = new Tree[] { new Tree(140, 400), new Tree(500, 400), new Tree(650, 470), new Tree(600, 420),
new Tree(190, 390), new Tree(45, 425), new Tree(75, 450) };
}
public void setUpGUI()
{
Container window = getContentPane(); // you attach Jcomponents to this pannel
display = new DisplayPanel();
guiPanel = new JPanel(new FlowLayout());
buttonPanel = new JPanel(new FlowLayout());
// TODO add title panel
/* Title = new JLabel("Elevator");
Title.setFont(new Font(" San Serif", Font.PLAIN, 20));
titlePanel.add(Title);*/
Floor = new JButton("Floor");
Floor.addActionListener(this);
Select = new JComboBox<>();
for (int i = 0; i < NUM_ITERATIONS; i++)
{
Select.addItem(String.valueOf(i + 1)); // this takes the int value and the parses it to a string
}
buttonPanel.add(Select);
buttonPanel.add(Floor);
window.add(buttonPanel, BorderLayout.NORTH);
window.add(guiPanel, BorderLayout.SOUTH);
window.add(display, BorderLayout.CENTER);
}
@Override
public void actionPerformed(ActionEvent e)
{
lvlChoice = Integer.parseInt((String) Select.getSelectedItem());
display.repaint();
// moves each cloud by the respective velocity
for (int i = 0; i < clouds.length; i++)
clouds[i].x -= clouds[i].velX;
}
class DisplayPanel extends JPanel
{
private static final long serialVersionUID = 1L;
DisplayPanel()
{
setPreferredSize(new Dimension(DISPLAY_WIDTH, DISPLAY_HEIGHT));
this.setBackground(Color.WHITE);
}
// executes all paint methods
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
backDrop(g2d);
for (Cloud c : clouds)
{
if (!c.Foreground) c.draw(g2d);
}
buildingLoop(g2d);
for (Cloud c : clouds)
{
if (c.Foreground) c.draw(g2d);
}
for (Tree t : trees)
{
t.draw(g2d);
}
}
// static background objects (ground, trees, ect..)
public void backDrop(Graphics2D g2d)
{
g2d.setColor(drkGrn);
g2d.fillRect(0, 500, getWidth(), getHeight());
}
// building the building and windows for the building
public void buildingLoop(Graphics2D g2d)
{
g2d.setColor(bldCol);
g2d.fillRect(buildX, buildY, buildW, buildH);
g2d.setColor(flWind);
for (int j = 1; j <= NUM_ROWS; j++)
{ // draws row
for (int i = 0; i <= LIMIT; i++)
{ // draws window's
if (i == ELEVATOR_COLUMN && j == NUM_ROWS - lvlChoice + 1)
{
g2d.setColor(crntFl);
}
g2d.fillRect(i * (WINDOWWIDTH + WINDOWSPACING) + buildX + WINDOWSPACING,
buildY + j * FLOORSPACING - FLOOROFFSET, WINDOWWIDTH, WINDOWHEIGHT);
g2d.setColor(flWind);
}
}
}
}
}
class Cloud
{
int x = 800, y, velX = 3; // position of x on cloud and velociity of cloudes
final Color blu1 = new Color(157, 215, 255); // cloud colors
final Color blu2 = new Color(93, 172, 227);
final Color blu3 = new Color(62, 167, 240);
final Color blu4 = new Color(136, 156, 169);
final Color blu5 = new Color(209, 230, 245);
int Size;
boolean Foreground;
public Cloud(int x, int y, int Size, int velX, boolean Foreground)
{
this.x = x;
this.y = y;
this.Size = Size;
this.velX = velX;
this.Foreground = Foreground;
}
public void tick()
{
x -= velX;
if (x < -100) x = 1000;
}
public void draw(Graphics2D g2d)
{
// cloud 1
// y starts at 100 to be put in method argument
g2d.setColor(blu4);
g2d.fillOval(x, y, Size, Size);
g2d.setColor(blu1);
g2d.fillOval(x + 15, y - 10, Size, Size);
g2d.setColor(blu3);
g2d.fillOval(x + 30, y + 10, Size, Size);
g2d.setColor(blu2);
g2d.fillOval(x + 45, y - 10, Size, Size);
g2d.setColor(blu5);
g2d.fillOval(x + 57, y, Size, Size);
}
}
class Tree
{
int xPoint, yPoint;
public Tree(int xPoint, int yPoint)
{
this.xPoint = xPoint;
this.yPoint = yPoint;
}
public void draw(Graphics2D g2d)
{
int leafSize = 25;
// graphics variables
final int tWidth = 10;
final int tHeiht = 120;
final Color plmLeaf = new Color(6, 145, 84);
final Color trunk = new Color(170, 85, 0);
g2d.setColor(trunk);
g2d.fillRect(xPoint + 25, yPoint, tWidth, tHeiht);
g2d.setColor(plmLeaf);
g2d.fillOval(xPoint, yPoint, leafSize, leafSize);
g2d.fillOval(xPoint + 5, yPoint - 10, leafSize, leafSize);
g2d.fillOval(xPoint + 5, yPoint + 10, leafSize, leafSize);
g2d.fillOval(xPoint + 10, yPoint, leafSize, leafSize);
g2d.fillOval(xPoint + 10, yPoint + 10, leafSize, leafSize);
g2d.fillOval(xPoint + 30, yPoint - 10, leafSize, leafSize);
g2d.fillOval(xPoint + 30, yPoint + 10, leafSize, leafSize);
g2d.fillOval(xPoint + 35, yPoint, leafSize, leafSize);
g2d.fillOval(xPoint + 35, yPoint + 10, leafSize, leafSize);
}
}