Related
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);
}
}
I'm making a game and when the user is in one of the game map panels he should enter the game once the character rectangle intersects with the game button rectangle on the map. The user navigates the character using the arrow keys.
I have the following code in the keyPressed method for one of the map panels (its the same for the rest) and the button (game1) reacts to the intersection as it should but the add and remove statements aren't adding or removing the respective panels:
Rectangle rb1 = character.getBounds();
Rectangle rb2 = game1.getBounds();
if (rb1.intersects(rb2)){
game1.setText("Int");
game1.setBackground(Color.red);
remove(sp);
add(g1, "Center");
validate();
repaint();
}
Initially I thought putting that block in the keyPressed method was what's causing the issue but when i moved it, the game1 button stopped reacting entirely. Any help is welcomed and appreciated :)
Here is the code in that panel:
public class SportsPanel extends javax.swing.JPanel implements KeyListener {
JButton homeButton2;
JButton game1;
JButton game2;
JButton game3;
JButton game4;
JButton game5;
SportsPanel sp;
JLabel character;
CharacterMenu cm;
ControlPanel cp;
game1 g1;
game2 g2;
game3 g3;
game4 g4;
game5 g5;
JTextField scoreField;
int c =1;
int x = 100;
int y = 100;
public SportsPanel() {
cm = new CharacterMenu();
g1 = new game1();
g2 = new game2();
g3 = new game3();
g4 = new game4();
g5 = new game5();
setLayout(null);
setBackground(Color.white);
homeButton2 = new JButton("Back to Main Menu");
add(homeButton2);
homeButton2.setBounds(10, 629, 150, 40);
character = new JLabel("");
character.setBounds(x, y, 100, 100);
add(character);
game1 = new JButton("Game 1");
add(game1);
game1.setBounds(200,200, 100, 20);
game2 = new JButton("Game 2");
add(game2);
game2.setBounds(340, 20, 100, 20);
game3 = new JButton("Game 3");
add(game3);
game3.setBounds(120,458, 100, 20);
game4 = new JButton("Game 4");
add(game4);
game4.setBounds(458,269, 100, 20);
game5 = new JButton("Game 5");
add(game5);
game5.setBounds(2, 500, 100, 20);
setFocusable(true);
addKeyListener(this);
scoreField = new JTextField(" Time elapsed: ");
scoreField.setBounds(10, 10, 150, 50);
add(scoreField);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
requestFocusInWindow();
Image myImage = Toolkit.getDefaultToolkit().getImage("images/sports.png");
g.drawImage(myImage, 0, 0, 925, 699, this);
if(c == 1){
ImageIcon lion1 = new ImageIcon("images/lion.png");
ImageIcon newSize = new ImageIcon(((lion1).getImage()).getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH));
character.setText("");
character.setIcon(newSize);
}
if(c == 2){
ImageIcon franklin1 = new ImageIcon("images/franklin.png");
ImageIcon newSize = new ImageIcon(((franklin1).getImage()).getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH));
character.setText("");
character.setIcon(newSize);
}
if(c == 3){
ImageIcon saquon1 = new ImageIcon("images/saquon.png");
ImageIcon newSize = new ImageIcon(((saquon1).getImage()).getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH));
character.setText("");
character.setIcon(newSize);
}
}
#Override
public void keyTyped(KeyEvent evt) {
}
#Override
public void keyPressed(KeyEvent evt) {
System.out.println("Key pressed");
int kk = evt.getKeyCode();
if (kk == evt.VK_LEFT)
{
x = x - 5;;
}
if (kk == evt.VK_RIGHT)
{
x = x + 5;
}
if (kk == evt.VK_UP)
{
y = y - 5;
}
if (kk == evt.VK_DOWN)
{
y = y + 5;
}
character.setBounds(new Rectangle(x, y, 100, 100));
Rectangle rb1 = character.getBounds();
Rectangle rb2 = game1.getBounds();
if (rb1.intersects(rb2)){
game1.setText("Int");
game1.setBackground(Color.red);
remove(sp);
add(g1, "Center");
validate();
repaint();
}
}
#Override
public void keyReleased(KeyEvent evt) {
}
}
I recently made a drawing of a car and tried changing the .fillPolygon to .fillRect but it didnt work to change the car to look like a truck. How would I change my code below to make the drawing of the car into a drawing of a truck?I did this on Eclipse.
Car.java
import java.awt.*;
public class Car {
//Coordinates if car is drawn at position 0,0
private int [] x = {0, 0, 20, 25, 70, 80, 105, 110};
private int[] y = {35, 15, 15, 0, 0, 15, 15, 35};
private int [] xCurrent = new int [x.length];
private int [] yCurrent = new int [y.length];
private int xOffset = 0, yOffset =0;
private Color carColor;
//-----------------------------------------------------------------
// Sets up the graphical car with the specified offsets.
//-----------------------------------------------------------------
public Car(int xOff, int yOff, Color color)
{
xOffset = xOff;
yOffset = yOff;
carColor = color;
for (int i=0; i < x.length; i++)
{
xCurrent[i] = x[i] + xOffset;
yCurrent[i] = y[i] + yOffset;
}
}
//
public int getXOffset() {return xOffset;}
public int getYOffset() {return yOffset;}
//-----------------------------------------------------------------
// Draws the car at a particular x and y offset.
//-----------------------------------------------------------------
public void draw(Graphics page)
{
page.setColor(carColor);
page.fillPolygon(xCurrent, yCurrent, x.length);
page.setColor(Color.black);
page.fillOval(13+xOffset, 28+yOffset, 14, 14); // rear wheel
page.fillOval(83+xOffset, 28+yOffset, 14, 14); // front wheel
page.drawLine(15+xOffset, 18+yOffset, 15+xOffset, 3+yOffset);
}
}
CarPanel.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CarPanel extends JPanel {
private Car car1, car2, car3;
private final int DELAY =20;
private int x, y;
private final int SPEED =2;
public CarPanel ()
{
car1 =new Car(200, 150, Color.BLUE);
car2 = new Car(50, 50, Color.RED);
car3 = new Car(0, 220, Color.GREEN);
x =0;
y= 220;
setPreferredSize(new Dimension(450,300));
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
x = car3.getXOffset() + SPEED;
y = car3.getYOffset();
if (x > getWidth()) x = 0;
car3 = new Car(x, y, Color.GREEN);
x = car2.getXOffset() + SPEED + 5;
if (x > getWidth()) x = 0;
y = car2.getYOffset();
car2 = new Car(x, y, Color.RED);
repaint();
}
};
new Timer(DELAY, taskPerformer).start();
}
//-----------------------------------------------------------------
// Draws the car.
//-----------------------------------------------------------------
public void paint(Graphics page)
{
super.paint(page);
car1.draw(page);
car2.draw(page);
car3.draw(page);
}
}
GUITester.java
import javax.swing.JFrame;
public class GUITester {
//-----------------------------------------------------------------
// Sets up a frame containing a tabbed pane. The panel on each
// tab demonstrates a different layout manager.
//-----------------------------------------------------------------
public static void main(String[] args)
{
JFrame frame = new JFrame("GUI Tester");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// add any panel into here
//ArrayReviews panel = new ArrayReviews();
//ArrayBetter panel = new ArrayBetter();
CarPanel panel = new CarPanel();
//NumericKeypadPanel panel = new NumericKeypadPanel();
//StarPanel panel = new StarPanel();
//SnowPanel panel = new SnowPanel();
//Draw1StarPanel panel = new Draw1StarPanel();
//Rain panel = new Rain();
//Cards panel = new Cards();
//SelectionSortPanel panel = new SelectionSortPanel();
//PersonPanel panel = new PersonPanel();
//SinPanel panel = new SinPanel();
//KochSnowFlake panel = new KochSnowFlake();
//CalculatorPanelSimple panel = new CalculatorPanelSimple();
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
Yuk! You are declaring x[] y[] arrays, and then constructing xOffset[] yOffset[] arrays to translate you car/truck to different positions. You can let the GPU do the work for you:
void draw(Graphics g) {
Graphics2D g2d = (Graphics2D) g; // Every Graphics is actually a Graphics2D.
translate(xOffset, yOffset); // Move the graphic origin
g2d.fillPolygon(x, y, x.length); // Draw with original coordinates
translate(-xOffset, yOffset); // Restore graphic origin, for other drawing
}
It doesn't turn your car into a truck, but your code doesn't show your attempt, so it is hard to say where you went wrong.
But, if this simplifies your code, perhaps that will help.
As #MadProgrammer points out, the Shape API might also be useful.
static Shape CAR_SHAPE;
static {
// Initialize CAR_SHAPE
}
void draw(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
translate(xOffset, yOffset);
g2d.draw(CAR_SHAPE);
translate(-xOffset, yOffset);
}
See Trail: 2D Graphics
In my code i generate randoms integer between 0 and 60 and i draw lines based on these.
I just want my lines fit the ordinate vertical line without touching my randoms integer... I guess it's kind of a mathematics problem but i'm really stuck here!
Here's my code first:
Windows.java:
public class Window extends JFrame{
Panel pan = new Panel();
JPanel container, north,south, west;
public JButton ip,print,cancel,start,ok;
JTextArea timeStep;
JLabel legend;
double time=0;
double temperature=0.0;
Timer chrono;
public static void main(String[] args) {
new Window();
}
public Window()
{
System.out.println("je suis là");
this.setSize(1000,400);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setTitle("Assignment2 - CPU temperature");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container = new JPanel(new BorderLayout());
north = new JPanel();
north.setLayout(new BorderLayout());
ip = new JButton ("New");
north.add(ip, BorderLayout.WEST);
print = new JButton ("Print");
north.add(print,BorderLayout.EAST);
JPanel centerPanel = new JPanel();
centerPanel.add(new JLabel("Time Step (in s): "));
timeStep = new JTextArea("0.1",1,5);
centerPanel.add(timeStep);
start = new JButton("OK");
ListenForButton lForButton = new ListenForButton();
start.addActionListener(lForButton);
ip.addActionListener(lForButton);
print.addActionListener(lForButton);
centerPanel.add(start);
north.add(centerPanel, BorderLayout.CENTER);
west = new JPanel();
JLabel temp = new JLabel("°C");
west.add(temp);
container.add(north, BorderLayout.NORTH);
container.add(west,BorderLayout.WEST);
container.add(pan, BorderLayout.CENTER);
this.setContentPane(container);
this.setVisible(true);
}
private class ListenForButton implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==start)
{
time=Double.parseDouble(timeStep.getText());
System.out.println(time);
chrono = new Timer((int)(1000*time),pan);
chrono.start();
}
if(e.getSource()==ip)
{
JPanel options = new JPanel();
JLabel address = new JLabel("IP Address:");
JTextField address_t = new JTextField(15);
JLabel port = new JLabel("Port:");
JTextField port_t = new JTextField(5);
options.add(address);
options.add(address_t);
options.add(port);
options.add(port_t);
int result = JOptionPane.showConfirmDialog(null, options, "Please Enter an IP Address and the port wanted", JOptionPane.OK_CANCEL_OPTION);
if(result==JOptionPane.OK_OPTION)
{
System.out.println(address_t.getText());
System.out.println(port_t.getText());
}
}
if(e.getSource()==print)
{
chrono.stop();
}
}
}
}
Panel.java:
public class Panel extends JPanel implements ActionListener {
int rand;
int lastrand=0;
ArrayList<Integer> randL = new ArrayList<>();
ArrayList<Integer> tL = new ArrayList<>();
int lastT = 0;
Color red = new Color(255,0,0);
Color green = new Color(0,200,0);
Color blue = new Color (0,0,200);
Color yellow = new Color (200,200,0);
int max=0;
int min=0;
int i,k,inc = 0,j;
int total,degr,moyenne;
public Panel()
{
super();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(1.8f));
g2.drawLine(20, 20, 20, this.getHeight()-50);
g2.drawLine(20, this.getHeight()-50, this.getWidth()-50, this.getHeight()-50);
g2.drawLine(20, 20, 15, 35);
g2.drawLine(20, 20, 25, 35);
g2.drawLine(this.getWidth()-50, this.getHeight()-50, this.getWidth()-65, this.getHeight()-45);
g2.drawLine(this.getWidth()-50, this.getHeight()-50, this.getWidth()-65, this.getHeight()-55);
g.drawString("10", 0, this.getHeight()-85);
g.drawString("20", 0, this.getHeight()-125);
g.drawString("30", 0, this.getHeight()-165);
g.drawString("40", 0, this.getHeight()-205);
g.drawString("50", 0, this.getHeight()-245);
g2.drawString("Maximum: ", 20, this.getHeight()-20);
g2.drawString(Integer.toString(max), 80, this.getHeight()-20);
g2.drawString("Minimum: ", 140, this.getHeight()-20);
g2.drawString(Integer.toString(min), 200, this.getHeight()-20);
g2.drawString("Average: ", 260, this.getHeight()-20);
g2.drawString(Integer.toString(moyenne), 320, this.getHeight()-20);
g2.setColor(red);
g2.drawLine(500, this.getHeight()-25, 540, this.getHeight()-25);
g2.setColor(new Color(0,0,0));
g2.drawString(": Maximum", 560, this.getHeight()-20);
g2.setColor(blue);
g2.drawLine(640, this.getHeight()-25, 680, this.getHeight()-25);
g2.setColor(new Color(0,0,0));
g2.drawString(": Minimum", 700, this.getHeight()-20);
g2.setColor(green);
g2.drawLine(780, this.getHeight()-25, 820, this.getHeight()-25);
g2.setColor(new Color(0,0,0));
g2.drawString(": Average", 840, this.getHeight()-20);
if(!randL.isEmpty()){
g2.setColor(red);
g2.drawLine(15, this.getHeight()-50-max, this.getWidth()-50,this.getHeight()-50-max);
g2.setColor(blue);
g2.drawLine(15, this.getHeight()-50-min, this.getWidth()-50,this.getHeight()-50-min);
g2.setColor(green);
g2.drawLine(15, this.getHeight()-50-moyenne, this.getWidth()-50,this.getHeight()-50-moyenne);
}
for(i = 0; i<tL.size(); i++){
int temp = randL.get(i);
int t = tL.get(i);
g2.setColor(new Color(0,0,0));
g2.drawLine(20+t, this.getHeight()-50-temp, 20+t, this.getHeight()-50);
// Ellipse2D circle = new Ellipse2D.Double();
//circle.setFrameFromCenter(20+t, this.getHeight()-50, 20+t+2, this.getHeight()-52);
}
for(j=0;j<5;j++)
{
inc=inc+40;
g2.setColor(new Color(0,0,0));
g2.drawLine(18, this.getHeight()-50-inc, 22, this.getHeight()-50-inc);
}
inc=0;
}
#Override
public void actionPerformed(ActionEvent e) {
rand = (int)(Math.random() * (60));
lastT += 80;
randL.add(rand);
tL.add(lastT);
Object obj = Collections.max(randL);
max = (int) obj;
Object obj2 = Collections.min(randL);
min = (int) obj2;
if(!randL.isEmpty()) {
degr = randL.get(k);
total += degr;
moyenne=total/randL.size();
}
k++;
if(randL.size()>=12)
{
randL.removeAll(randL);
tL.removeAll(tL);
lastT = 0;
k=0;
degr=0;
total=0;
moyenne=0;
}
repaint();
}
}
And here it what i gives me :
Sorry it's a real mess!
Any thoughts ?
Thanks.
You need to stop working with absolute/magical values, and start using the actual values of the component (width/height).
The basic problem is a simple calculation which takes the current value divides it by the maximum value and multiples it by the available width of the allowable area
int length = (value / max) * width;
value / max generates a percentage value of 0-1, which you then use to calculate the percentage of the available width of the area it will want to use.
The following example places a constraint (or margin) on the available viewable area, meaning all the lines need to be painted within that area and not use the entire viewable area of the component
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DrawLine {
public static void main(String[] args) {
new DrawLine();
}
public DrawLine() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int margin = 20;
int width = getWidth() - (margin * 2);
int height = getHeight() - (margin * 2);
int x = margin;
for (int index = 0; index < 4; index++) {
int y = margin + (int)(((index / 3d) * height));
int length = (int)(((index + 1) / 4d) * width);
g2d.drawLine(x, y, x + length, y);
}
g2d.dispose();
}
}
}
This one's a tough one - I have a JFrame that generates JTextFields. When I go from generating 2 JTextFields to 12 JTextfields (for example), I see some error where there is an extra differently-sized JTextField at the end. It seems to be a repaint error.
Main.java code:
import java.awt.*;
import javax.swing.*;
public class Main {
public static Display display = new Display();
public static void main(String[] args) {
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
display.setVisible(true);
}
}
Display.java code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Display extends JFrame {
final int FRAME_WIDTH = 820;
final int FRAME_HEIGHT = 700;
final int X_OFFSET = 40;
final int Y_OFFSET = 40;
final int GRAPH_OFFSETX = 35;
final int GRAPH_OFFSETY = 60;
final int GRAPH_WIDTH = 500;
final int GRAPH_HEIGHT = 500;
final int GRAPH_INTERVAL = 20;
JButton submit;
JTextField top;
JTextField bottom;
JTextField numPoint;
JPanel bpanel;
JPanel points;
int maxPoints;
public Display() {
init();
}
public void init() {
setBackground(Color.WHITE);
setLocation(X_OFFSET, Y_OFFSET);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setTitle("Geometric Transformations");
getContentPane().setLayout(null);
setDefaultLookAndFeelDecorated(true);
top = new JTextField(); // parameter is size of input characters
top.setText("1 2 3");
top.setBounds(590, 150, 120, 25);
bottom = new JTextField(); // parameter is size of input characters
bottom.setText("5 6 7");
bottom.setBounds(590, 200, 120, 25);
numPoint = new JTextField();
numPoint.setText("Number of Points?");
numPoint.setBounds(550,200,200,25);
this.add(numPoint);
SubmitButton submit = new SubmitButton("Submit");
submit.setBounds(570, 250, 170, 25);
bpanel = new JPanel(new GridLayout(2,3));
bpanel.add(top);
bpanel.add(bottom);
bpanel.add(submit);
points = new JPanel(new GridLayout(2,2));
points.setBounds(540,250,265,60);
this.add(points);
bpanel.setBounds(550,100,200,70);
this.add(bpanel, BorderLayout.LINE_START);
Component[] a = points.getComponents();
System.out.println(a.length);
repaint();
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.fillRect(100, 100, 20, 30);
g.setColor(Color.BLACK);
genGraph(g, GRAPH_OFFSETX, GRAPH_OFFSETY, GRAPH_WIDTH, GRAPH_HEIGHT, GRAPH_INTERVAL);
}
public void genGraph (Graphics g, int x, int y, int width, int height, int interval) {
// draw background
int border = 5;
g.setColor(Color.BLACK);
width = width - (width % interval);
height = height - (height % interval);
for (int col=x; col <= x+width; col+=interval) {
g.drawLine(col, y, col, y+height);
}
for (int row=y; row <= y+height; row+=interval) {
g.drawLine(x, row, x+width, row);
}
}
class SubmitButton extends JButton implements ActionListener {
public SubmitButton(String title){
super(title);
addActionListener(this);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
maxPoints = Integer.parseInt(numPoint.getText()) * 2;
points.removeAll();
for (int i=0; i<maxPoints; i++) {
JTextField textField = new JTextField();
points.add(textField);
}
points.validate(); // necessary when adding components to a JPanel
// http://stackoverflow.com/questions/369823/java-gui-repaint-problem-solved
// What to Check:
// Things between commas are either spaces (which will be stripped later)
// or numbers!
// Pairs must match up!
}
}
}
The new components are redrawn over the previous ones.
I added points.repaint(); after points.validate(); and the problem was gone.
Note: I was annoyed with the issue of repainting of the grid too (put the window in front then back, you will see).
From a quick search, it seems better to avoid painting directly on the JFrame, but instead delegate that to a sub-component. If I am wrong, somebody tell me.
Here is my solution (imperfect, I leave to you the task to improve it... :-P
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SODisplay extends JFrame {
final int FRAME_WIDTH = 820;
final int FRAME_HEIGHT = 700;
final int X_OFFSET = 40;
final int Y_OFFSET = 40;
JButton submit;
JTextField top;
JTextField bottom;
JTextField numPoint;
JPanel bpanel;
JPanel points;
GridPanel grid;
int maxPoints;
public SODisplay() {
init();
}
public void init() {
setBackground(Color.WHITE);
setLocation(X_OFFSET, Y_OFFSET);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setTitle("Geometric Transformations");
getContentPane().setLayout(null);
setDefaultLookAndFeelDecorated(true);
grid = new GridPanel();
grid.setBounds(0,0,530,FRAME_HEIGHT);
this.add(grid);
top = new JTextField(); // parameter is size of input characters
top.setText("1 2 3");
top.setBounds(590, 150, 120, 25);
bottom = new JTextField(); // parameter is size of input characters
bottom.setText("5 6 7");
bottom.setBounds(590, 200, 120, 25);
numPoint = new JTextField();
numPoint.setText("Number of Points?");
numPoint.setBounds(550,200,200,25);
this.add(numPoint);
SubmitButton submit = new SubmitButton("Submit");
submit.setBounds(570, 250, 170, 25);
bpanel = new JPanel(new GridLayout(2,3));
bpanel.add(top);
bpanel.add(bottom);
bpanel.add(submit);
points = new JPanel(new GridLayout(2,2));
points.setBounds(540,250,265,60);
this.add(points);
bpanel.setBounds(550,100,200,70);
this.add(bpanel, BorderLayout.LINE_START);
Component[] a = points.getComponents();
System.out.println(a.length);
repaint();
}
class SubmitButton extends JButton implements ActionListener {
public SubmitButton(String title){
super(title);
addActionListener(this);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
maxPoints = Integer.parseInt(numPoint.getText()) * 2;
points.removeAll();
for (int i=0; i<maxPoints; i++) {
JTextField textField = new JTextField();
points.add(textField);
}
points.validate(); // necessary when adding components to a JPanel
points.repaint();
// http://stackoverflow.com/questions/369823/java-gui-repaint-problem-solved
// What to Check:
// Things between commas are either spaces (which will be stripped later)
// or numbers!
// Pairs must match up!
}
}
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
SODisplay display = new SODisplay();
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
display.setVisible(true);
}
});
}
class GridPanel extends JPanel {
// Or drop the offset and adjust the placement of the component
final int GRAPH_OFFSETX = 35;
final int GRAPH_OFFSETY = 60;
final int GRAPH_WIDTH = 500;
final int GRAPH_HEIGHT = 500;
final int GRAPH_INTERVAL = 20;
public GridPanel() {
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.fillRect(100, 100, 20, 30);
g.setColor(Color.BLACK);
genGraph(g, GRAPH_OFFSETX, GRAPH_OFFSETY, GRAPH_WIDTH, GRAPH_HEIGHT, GRAPH_INTERVAL);
}
public void genGraph (Graphics g, int x, int y, int width, int height, int interval) {
// draw background
int border = 5;
g.setColor(Color.BLACK);
width = width - (width % interval);
height = height - (height % interval);
for (int col=x; col <= x+width; col+=interval) {
g.drawLine(col, y, col, y+height);
}
for (int row=y; row <= y+height; row+=interval) {
g.drawLine(x, row, x+width, row);
}
}
}
}
That's just my test code in one file for simplicity, you might want to dissect it differently, of course.