Reputation: 71
When I try to add a second instance of an elevator class, the first one disappears. How can I rearrange this code in order to see both objects?
Here is my main class:
public class MainClass extends JPanel implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame("title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000, 700);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Component component1 = frame.add(new elevator(0,0));
Component component2 = frame.add(new elevator(505,50));
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
And this is the elevator class:
public class elevator extends JPanel implements ActionListener {
Timer timer;
private double angle = 0;
private double scale = 1;
private double delta = 0.01;
private int x=0;
private int y=0;
Rectangle.Float r = new Rectangle.Float(0, 0, 3, 3);
public elevator(int input_x, int input_y) {
x=input_x;
y=input_y;
timer = new Timer(10, this);
timer.start();
}
public elevator() {
timer = new Timer(10, this);
timer.start();
}
public void paint(Graphics g) {
this.setSize(100,200);
this.setLocation(x, y);
int h = getHeight();
int w = getWidth();
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.translate(w / 5, scale*140);
g2d.scale(20, 20);
g2d.fill(r);
}
public void actionPerformed(ActionEvent e) {
if (scale < 0.01 || scale > 0.99) {
delta = -delta;
}
scale += delta;
angle += 0.01;
repaint();
}
}
Upvotes: 2
Views: 6079
Reputation: 1544
UPDATED
Strictly speaking, all I think you need to do to get the code working may be this. Specify a BorderLayout position when you add to the frame:
frame.add(new elevator(0, 0), BorderLayout.WEST);
frame.add(new elevator(505, 50), BorderLayout.EAST);
The other answers here are of course proposing better long term approaches to your project code.
(Thanks sbat for pointing out that the default layout is actually BorderLayout not FlowLayout).
Cheers,
Upvotes: 0
Reputation: 208994
Don't make elevator
extends JPanel
at all. Just make it a class for holding state, manipulating the state, and drawing the state. Then just have one main drawing panel, that you add elevators
to, using a List<elevator>
.
Elevator.java (notice Java naming convention)
public class Elevator {
public void draw(Graphics g) {}
public void move() {}
}
ElevatorPanel.java
public class ElevatorPanel extends JPanel {
List<Elevator> elevators;
@Override
protected void paintComponent(Grapchics g) {
super.paintComponent(g);
for (Elevator elevator: elevators) {
elevator.draw(g);
}
}
}
Just have the timer (only one) in the ElevatorPanel
class and loop through the list of elevators and call the move
method.
Timer timer = new Timer(40, new ActionListener(){
public void actionPerformed(ActionEvent e) {
for (Elevator elevator : elevators) {
elevator.move();
}
repaint();
}
});
You can see a bunch of similar examples here and here and here and here and here and here.
Side Notes:
Follow Java naming convention. Class names begin with upper case letters.
You should be override paintComponent
and not paint
Swing apps should be run on the Event Dispatch Thread. See Initial Threads
Upvotes: 2
Reputation: 8422
You will need some sort of container to put both of the components in. You could use a JPanel
, in which case your code would look like:
JPanel panel = new JPanel();
panel.add(new elevator(0,0));
panel.add(new elevator(505,50));
frame.add(panel);
For both of them to take up the same area (and for the JPanel
to fill up all the space it can), you could pass in a GridLayout
to the JPanel
constructor:
JPanel panel = new JPanel(new GridLayout(2, 1)); // 2 rows, 1 column
or
JPanel panel = new JPanel(new GridLayout(1, 2)); // 1 row, 2 columns
Upvotes: 2
Reputation: 3884
A frame can only handle one component by default. Create a JPanel and add it to the JFrame, then specify a layout for your JPanel and start adding components to it, instead of the frame
Upvotes: 1