I'm a beginner with graphics, as well as Java all together. It seems that no matter what I do, this program is not working! :( Anyway, the goal is to "Use nested loops, Graphics, and Math.random() to print out the square pattern" The pattern is 30x30 squares next to each other in 14 rows by 20 columns. Here is my code so far:
import java.awt.Color; import java.awt.Font; import java.awt.Canvas; class ColoredBoxes extends Canvas { public ColoredBoxes() { setBackground(Color.BLACK); } public void paint( Graphics window ) { window.setColor(Color.RED); window.setFont(new Font("TAHOMA",Font.BOLD,12)); window.drawString("**Fun Fact: I hate snow.**", 20, 40 ); window.drawString("Drawing boxes with nested loops ", 20, 80 ); //private static final int WIDTH = 800; //private static final int HEIGHT = 600; //Boxes: 20 Across, 14 Down drawBoxes(window); } public void drawBoxes(Graphics window) { //nested loops to draw the pretty boxes //int drawRow = 1; //int drawCol = 1; int c1 = (int)(Math.random()*256); int c2 = (int)(Math.random()*256); int c3 = (int)(Math.random()*256); Color random = new Color (c1,c2,c3); int dS = 30; //Distance from the side (left) int dT = 100; //Distance from the top int x = 30; //Width int y = 30; //Height for(int drawRow = 1; drawRow <= 14; drawRow++) { for(int drawCol = 1; drawCol <= 20; drawCol++) { window.setColor(Color.white); window.fillRect(dS, dT, x, y); window.setColor(Color.black); window.drawRect(dS, dT, x, y); System.out.println(); dS = dS+y; } dT = dT+x; } } }
Each square should also be a different, random color. What did I do wrong? Thank you so much :)
Start by taking a look through Performing Custom Painting and Painting in AWT and Swing for details about painting actually works.
You don't control the paint process, this means that painting may occur at any time for any reason, many of which are outside of your control. This means, that each time drawBoxes
is called, you are generating new colors.
Painting is also made up of a chain of method calls, which helps provide better customisation opportunities, but you are breaking this paint chain by not calling super.paint
first.
What I would do is first create a List
or array of colors, which represent each individual cell in your grid. I would use this each time paint
was called to ensure that the painting was consistent
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ColoredBoxes {
public static void main(String[] args) {
new ColoredBoxes();
}
public ColoredBoxes() {
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 static class TestPane extends JPanel {
protected static final int ROWS = 14;
protected static final int COLS = 20;
protected static final int BOX_SIZE = 30;
private List<Color> colors;
public TestPane() {
int length = ROWS * COLS;
colors = new ArrayList<>(length);
for (int index = 0; index < length; index++) {
int c1 = (int) (Math.random() * 255);
int c2 = (int) (Math.random() * 255);
int c3 = (int) (Math.random() * 255);
colors.add(new Color(c1, c2, c3));
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(COLS * BOX_SIZE, ROWS * BOX_SIZE);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int xOffset = (getWidth() - (COLS * BOX_SIZE)) / 2;
int yOffset = (getHeight() - (ROWS * BOX_SIZE)) / 2;
System.out.println("...");
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
int index = (row * COLS) + col;
g2d.setColor(colors.get(index));
g2d.fillRect(xOffset + (col * BOX_SIZE),
yOffset + (row * BOX_SIZE),
BOX_SIZE, BOX_SIZE);
}
}
g2d.dispose();
}
}
}
Updated
The basic problem revolves around how you are calculating the row/col position for each cell and the misuse of the Graphics#draw/fillRectangle
method.
While you could simply increment the x/y
position of each grid within the for-loop
, a simpler approach would be to simply calculate them based on your current row/col
int xOffset = 50;
int yOffset = 100;
for (int drawRow = 0; drawRow < 14; drawRow++) {
for (int drawCol = 0; drawCol < 20; drawCol++) {
int x = drawCol * 30 + xOffset;
int y = (drawRow * 30) + yOffset;
The next issue is the misuse of Graphics#draw/fillRect
. The JavaDocs state that
public abstract void fillRect(int x,
int y,
int width,
int height)
Fills the specified rectangle. The left and right edges of the rectangle are at x and x + width - 1. The top and bottom edges are at y and y + height - 1. The resulting rectangle covers an area width pixels wide by height pixels tall. The rectangle is filled using the graphics context's current color.
x - the x coordinate of the rectangle to be filled.
y - the y coordinate of the rectangle to be filled.
width - the width of the rectangle to be filled.
height - the height of the rectangle to be filled.
This means that last two parameters should be 30, 30
, not what ever you're currently passing to them.
Also you MUST call super.paint(window);
before you perform any custom painting.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.