简体   繁体   English

JAVA-创建带有循环的彩色框行?

[英]JAVA - Creating a Row of Colored Boxes with Loops?

I'm a beginner with graphics, as well as Java all together. 我是图形和Java的初学者。 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: :(无论如何,目标是“使用嵌套循环,图形和Math.random()来打印正方形图案”模式是30x30正方形,彼此相邻,每14行20列。这是到目前为止的代码:

 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. 首先看一下在AWT和Swing中 执行自定义绘画绘画,以了解有关绘画实际工作的详细信息。

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. 这意味着,每次调用drawBoxes ,您都在生成新的颜色。

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. 绘画也由一系列方法调用组成,这有助于提供更好的自定义机会,但是您不首先调用super.paint就打破了这个绘画链。

What I would do is first create a List or array of colors, which represent each individual cell in your grid. 我要做的是首先创建一个颜色List或颜色数组,它们代表网格中的每个单元格。 I would use this each time paint was called to ensure that the painting was consistent 每当调用paint ,我都会使用此方法来确保paint一致

漂亮网格

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. 基本问题围绕着如何计算每个单元格的行/列位置以及是否滥用Graphics#draw/fillRectangle方法。

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 虽然您可以简单地增加for-loop内每个网格的x/y位置,但一种更简单的方法是根据当前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 . 下一个问题是滥用Graphics#draw/fillRect The JavaDocs state that JavaDocs指出

public abstract void fillRect(int x, 公共抽象无效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. 矩形的左边缘和右边缘位于x和x +宽度-1。顶部和底部边缘位于y和y +高度-1。所得的矩形覆盖着一个宽像素宽乘高像素高的区域。 The rectangle is filled using the graphics context's current color. 使用图形上下文的当前颜色填充矩形。

Parameters: 参数:
x - the x coordinate of the rectangle to be filled. x-要填充的矩形的x坐标。
y - the y coordinate of the rectangle to be filled. y-要填充的矩形的y坐标。
width - the width of the rectangle to be filled. width-要填充的矩形的宽度。
height - the height of the rectangle to be filled. height-要填充的矩形的高度。

This means that last two parameters should be 30, 30 , not what ever you're currently passing to them. 这意味着最后两个参数应该是30, 30 ,而不是您当前传递给它们的任何参数。

Also you MUST call super.paint(window); 您还必须调用super.paint(window); before you perform any custom painting. 在执行任何自定义绘画之前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM