Tuesday 27 March 2018

java - Transferring JFrame to JPanel




I created a simple "elevator" program (it's still in the beginning stages) that goes up 1 floor when I click UP and vice versa.



I messed up pretty badly when I drew all my components into JFrame, and as expected, it flickers every time I click the button (repaints). I know the solution to be draw in the JPanel and put the said panel in the JFrame, but I have a problem translating my JFrame components into JPanel. I've tried extending JPanel, creating a JFrame object and then overriding the paintComponent() method and doing my drawing there, but when I compile it does not draw it at all. It only creates the frame.



Can anyone help me or give me tips on how to proceed "transferring" my programming from JFrame based to JPanel based? Thank you in advance!



My code is below:



import java.awt.*;

import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.Timer;
import java.math.*;



public class MyCanvas extends JFrame {


private int up = 0;
private int down = 0;
private int movefloorup = 0;
private int buildingType;//type of building (1 = Residential, 2 = Commercial)
private int totnumoffloors; //for the total number of floors
private int numofelevators; //for the number of elevators to be generated
private int floorlimit = 0; //to determine up until where the elevator will be moving
private int currenttime; //determine the time of the day the elevator is operating (1 = Morning, 2 = Lunch, 3 = Afternooon)

//For elevator resetting to bottom

private int rectX = 190;
private int switchmarker = 0;

//Lines and stuff
private int horizborder = 0;
private int bordercount = 0;

private class UpAction implements ActionListener //move the elevator up
{
public void actionPerformed(ActionEvent e)

{
if(movefloorup<780){
repaint();
up++;
movefloorup = movefloorup + 130;
//repaint();

}
else
{

switchmarker = 1;
movefloorup = 0;
repaint();

}
}
}

private class DownAction implements ActionListener //move the elevator down
{

public void actionPerformed(ActionEvent e)
{

if(movefloorup>0){
repaint();
down++;
movefloorup = movefloorup - 130;
//repaint();
}


else
{
switchmarker = 0;
movefloorup = 780;
repaint();
}
}
}



public MyCanvas(int buildingType, int totnumoffloors, int numofelevators, int currenttime){


this.buildingType = buildingType;
this.totnumoffloors = totnumoffloors;
this.numofelevators = numofelevators;
this.currenttime = currenttime;
String title;

if(this.buildingType == 1)

{
title = "Residential Building";
}
else
{
title = "Commercial Building";
}

setLayout(null);


horizborder = 500*((int)Math.ceil((double)totnumoffloors/7)); //calculating how wide the window should be
bordercount = ((int)Math.ceil((double)totnumoffloors/7)); //counts how many borders there will be

//NOTES
//A floor is 130 units in the Y-Direction


//Drawing the bulding layout
if(totnumoffloors>7)
{

setSize(horizborder, 1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(title);
setLayout(new BorderLayout());
getContentPane().setBackground(Color.WHITE);
}

else{
setSize(500, 1000); //suitable for 7 floors
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setTitle(title);
setLayout(new BorderLayout());
getContentPane().setBackground(Color.WHITE);
}

JButton upButton = new JButton("UP");
upButton.addActionListener(new UpAction());
add(upButton, BorderLayout.NORTH);

JButton downButton = new JButton("DOWN");

//downButton.setBounds(0, 0, 220, 30);
//downButton.setLocation(100, 100);
downButton.addActionListener(new DownAction());
add(downButton, BorderLayout.SOUTH);


}


public void paint(Graphics graphics){ //this is where you draw shit


super.paint(graphics);

//Floors
graphics.setColor(Color.RED);

int numoffloorsY = 830;
int numoffloorsX = 830;
int floorbeginning = 0;
int floorcounter = 1;

int floorflag = 0;
int rightedge = 500;

if(this.totnumoffloors>7) //drawing the floors
{

//Default number of floors -> 7
for(int i = 0;i {
graphics.setColor(Color.RED);

graphics.drawLine(floorbeginning,numoffloorsX,rightedge,numoffloorsY); //FLOORS
graphics.setColor(Color.DARK_GRAY);
graphics.setFont(new Font("TimesRoman", Font.PLAIN, 15));
graphics.drawString(" "+floorcounter, floorbeginning+10, numoffloorsY+20); //SAVE THIS FOR DRAWING FLOORS
numoffloorsY = numoffloorsY - 130;
numoffloorsX = numoffloorsX - 130;
floorcounter++;
floorflag++;

if(floorflag==7)

{
floorbeginning = floorbeginning + 500;
rightedge = rightedge+500;
numoffloorsY = 830;
numoffloorsX = 830;
floorflag = 0;
}


}




//Every other floor past 7 will be added here.
/*for(int i = 0;i {
//System.out.println("LOLOOLO");
graphics.setColor(Color.RED);
graphics.drawLine(floorbeginning,numoffloorsX,horizborder,numoffloorsY);
graphics.setColor(Color.DARK_GRAY);

graphics.setFont(new Font("TimesRoman", Font.PLAIN, 15));
graphics.drawString(" "+floorcounter, floorbeginning, numoffloorsY+20);
//graphics.setColor(Color.DARK_GRAY);
//graphics.drawLine(500,0,500,1000);

floorcounter++;

numoffloorsY = numoffloorsY - 130;
numoffloorsX = numoffloorsX - 130;
}*/


//DIVIDING LINE -> to determine the first 7 floors from the ones higher up.
for(int i=0;i {
graphics.setColor(Color.DARK_GRAY);
graphics.drawLine(500*i,0,500*i,1000);

}

}


else{

for(int i = 0;i {
graphics.setColor(Color.RED);
graphics.drawLine(0,numoffloorsX,500,numoffloorsY);
graphics.setColor(Color.DARK_GRAY);
graphics.setFont(new Font("TimesRoman", Font.PLAIN, 15));
graphics.drawString(" "+floorcounter, floorbeginning+10, numoffloorsY+20); //SAVE THIS FOR DRAWING FLOOR

numoffloorsY = numoffloorsY - 130;
numoffloorsX = numoffloorsX - 130;
floorcounter++;
}
}

//Drawing the elevators
if(up>0 && movefloorup<1000){

graphics.setColor(Color.GRAY);

if(switchmarker==1)
{
System.out.println("ELSA");
rectX = 690;
//rectX = rectX + 190;

}
else
{
rectX = 190;

}

System.out.println(rectX);
graphics.fillRect(rectX, 850-movefloorup, 100, 100); //this needs to match the stats of the rectangle to fill it properly
graphics.drawRect(rectX, 850-movefloorup, 100, 100);

//Line for the door
graphics.setColor(Color.BLACK);
graphics.drawLine(rectX+50, 850-movefloorup, rectX+50, 950-movefloorup); //match the y-coordinate for the rectangle, add 100 for the y-coordinate of the other end


System.out.println(movefloorup);
System.out.println(switchmarker);

//drawLine(x1, y1, x2, y2); --From (x1,y1) to (x2,y2)
}

else if(down>0 && movefloorup>0)
{
graphics.setColor(Color.GRAY);


if(switchmarker==1) //This determines when the elevator should move to the next column of higher floors.
{
System.out.println("ELSA");
rectX = 500;
}
System.out.println(rectX);
graphics.fillRect(rectX, 850-movefloorup, 100, 100); //this needs to match the stats of the rectangle to fill it properly
//graphics.drawRect(190, 850 + movefloorup, 100, 100); //FIRST FLOOR
graphics.drawRect(rectX, 850-movefloorup, 100, 100); //SECOND FLOOR (135 units difference in Y-axis between floors)
//x-coordinate, y-coordinate, width, height



//Line for the door
graphics.setColor(Color.BLACK);
graphics.drawLine(rectX+50, 850-movefloorup, rectX+50, 950-movefloorup); //match the y-coordinate for the rectangle, add 100 for the y-coordinate of the other end

System.out.println(movefloorup);
System.out.println(switchmarker);
}


else
{
graphics.setColor(Color.GRAY);
graphics.fillRect(190, 850, 100, 100); //this needs to match the stats of the rectangle to fill it properly
graphics.drawRect(190, 850, 100, 100); //FIRST FLOOR
graphics.drawRect(190, 850, 100, 100); //SECOND FLOOR (135 units difference in Y-axis between floors)
//x-coordinate, y-coordinate, width, height
//Line for the door
graphics.setColor(Color.BLACK);
graphics.drawLine(240, 850, 240, 950); //match the y-coordinate for the rectangle, add 100 for the y-coordinate of the other end

//System.out.println("In else!");

}

}

}


The main class just gets input from the user, such as the number of floors, time of day, etc.



Answer



This is going to be a little messy.



Start by creating a custom component that extends from JPanel (I'll call it ElevatorPane).



Take the contents of the current paint method and place them within this components paintComponent method. This will involve moving the instance variables that the paintComponent method will need including, totnumoffloors, bordercount, up, down, movefloorup, switchmarker, rectX



This is where it gets a little messy...



You need to take the contents of your ActionListeners and translate these into methods within the ElevatorPane, this way you expose the functionality without exposing the details...




Create a constructor within ElevatorPane that takes the number of floors.



Override the getPrefferedSize method of ElevatorPane and return the size that the component needs to be to satisfy your needs...



Create an instance field of ElevatorPane in MyCanvas, instantiate it and add it to the frame.



Clean, build, run...


No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...