I have a program that displays many elements of one class at different positions. For this I'm using the constructor of the class many times. But the problem is that only the last element is shown and not the others.
The initialization of the the frame and where the constuctors are called:
private void initComponents() {
setExtendedState(MAXIMIZED_BOTH);
int width = (int) getContentPane().getBounds().getWidth();
int height = (int) getContentPane().getBounds().getHeight();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new gleis(0, 0, 0, 0));
add(new gleis(1, 0, 1, 0));
add(new gleis(2, 0, 2, 0));
this.setVisible(true);
}
The class of the element called 'gleis':
public class gleis extends JPanel {
int xposition;
int yposition;
int id;
int status;
public gleis(int xpos, int ypos, int id, int status){
this.xposition = xpos * 11;
this.yposition = ypos * 11 + 4;
this.id = id;
this.status = status;
System.out.println(this.id);
}
public void paintComponent(Graphics g1) {
super.paintComponent(g1);
Graphics2D g = (Graphics2D) g1;
g.setColor(Color.black);
g.fillRect(this.xposition, this.yposition, 11, 4);
if (this.status == 0)
g.setColor(Color.gray);
else if (this.status == 1)
g.setColor(Color.red);
else if (this.status == 2)
g.setColor(Color.yellow);
else
g.setColor(Color.gray);
g.fillRect(this.xposition + 2, this.yposition + 1, 7, 2);
}
}
So how can I show all elements I want to have?
You're likely adding your component to a JFrame's contentPane, a component that uses BorderLayout as its default layout, and for this reason the last component entered is covering all the others, since they're being added defaultwise to the BorderLayout.CENTER position.
Based on your code and my assumption of your use case, I'd suggest changing your whole approach:
public void draw(Graphics2D g2)
method.draw(...)
on each Gleis instance.For example:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class GleisMain {
private static void createAndShowGui() {
GleisPainter gleisPainter = new GleisPainter();
gleisPainter.addGleis(new Gleis(10, 10, 0, 0));
gleisPainter.addGleis(new Gleis(20, 20, 1, 1));
gleisPainter.addGleis(new Gleis(30, 30, 2, 2));
// I try to avoid having classes extend JFrame and instead use JFrames when needed
JFrame frame = new JFrame("Gleis Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(gleisPainter);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
// a single class that extend JPanel and that draws all the Gleis objects
class GleisPainter extends JPanel {
// an ArrayList to hold all the Gleis objects
private List<Gleis> gleisList = new ArrayList<>();
// to allow outside classes to add Gleis objects
public void addGleis(Gleis gleis) {
gleisList.add(gleis);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// loop through our gleis list and draw each instance
Graphics2D g2 = (Graphics2D) g;
for (Gleis gleis : gleisList) {
gleis.draw(g2); // by calling its draw(...) method
}
}
}
// don't have this extend JPanel
class Gleis {
// fields should be private
private int xposition;
private int yposition;
private int id;
private int status;
public Gleis(int xpos, int ypos, int id, int status) {
this.xposition = xpos * 11;
this.yposition = ypos * 11 + 4;
this.id = id;
this.status = status;
System.out.println(this.id);
}
// give this a public draw method where each instance can draw itself
public void draw(Graphics2D g2) {
g2.setColor(Color.black);
// you'll want to avoid "magic" numbers like you're using here:
g2.fillRect(this.xposition, this.yposition, 11, 4);
if (this.status == 0)
g2.setColor(Color.gray);
else if (this.status == 1)
g2.setColor(Color.red);
else if (this.status == 2)
g2.setColor(Color.yellow);
else
g2.setColor(Color.gray);
// ditto about use of "magic" numbers
g2.fillRect(this.xposition + 2, this.yposition + 1, 7, 2);
}
}