I have a class called DrawRectangles
that takes an array of integers.
What I am trying to do is go through the numbers in the array and for each one, create a new panel using the number in the array as the panel's width and X position.
Let's say I pass in [2, 4, 6, 8]. I want to create a new panel to add to the JFrame
with each of these numbers.
So the first panel should start at position 2 and have a width of 2. I also have a random color generator which is supposed to create a new color for each panel. Here is what I have:
public class DrawRectangles {
JFrame frame;
DrawPanel panel;
Random randomGenerator = new Random();
int red = randomGenerator.nextInt(255);
int green = randomGenerator.nextInt(255);
int blue = randomGenerator.nextInt(255);
Color randomColor;
int[] newWidth;
DrawRectangles(int[] width){
this.newWidth = width;
}
public void setUpFrame(){
frame = new JFrame();
frame.setSize(500,100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for(int x = 0; x < newWidth.length; x++){
panel = new DrawPanel(newWidth[x]);
frame.add(panel);
}
}
class DrawPanel extends JPanel{
int newWidth;
DrawPanel(int width){
this.newWidth = width;
System.out.println(newWidth);
}
public void paint(Graphics g) {
super.paint(g);
randomColor = new Color(red,green,blue);
g.setColor(randomColor);
g.fillRect(newWidth, 10, newWidth, 30);
}
}
}
You have a number of issues...
BorderLayout
by default. This will only allow a single component to occupy any one of the pre-defined position available to it. This means that only the last pane will be visible.randomColor
changes values, all the components referencing it
will also be repainted with it on the next paint cycle.paintComponent
instead of paint
This is a basic example using a single DrawRectangle
component to paint all the rectangles.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DrawRectangles {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
DrawRectangles dr = new DrawRectangles(new int[]{2, 4, 6, 8});
dr.setUpFrame();
}
});
}
JFrame frame;
DrawPanel panel;
Random randomGenerator = new Random();
int[] newWidth;
DrawRectangles(int[] width) {
this.newWidth = width;
}
public void setUpFrame() {
frame = new JFrame();
frame.setSize(500, 100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawPanel panel = new DrawPanel();
for (int x = 0; x < newWidth.length; x++) {
int red = randomGenerator.nextInt(255);
int green = randomGenerator.nextInt(255);
int blue = randomGenerator.nextInt(255);
panel.addRectangle(new Color(red, green, blue), newWidth[x]);
}
frame.setSize(200, 200);
frame.add(panel);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class MyRectangle {
private Color color;
private Rectangle rectangle;
public MyRectangle(Color color, int width) {
this.color = color;
rectangle = new Rectangle(width, 10, width, 30);
}
public Color getColor() {
return color;
}
public Rectangle getRectangle() {
return rectangle;
}
public void draw(Graphics2D g2d) {
g2d.setColor(color);
g2d.fill(rectangle);
}
}
public class DrawPanel extends JPanel {
private List<MyRectangle> rectangles;
public DrawPanel() {
rectangles = new ArrayList<>();
}
public void addRectangle(Color color, int width) {
rectangles.add(new MyRectangle(color, width));
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g.create();
for (MyRectangle rect : rectangles) {
rect.draw(g2d);
}
g2d.dispose();
}
}
}
You could use a different layout manager, but then your DrawRectangle
component must also return a preferredSize
so that the layout manager doesn't layout out the component with a size of 0x0