JAVA - 用循环创建一排彩色盒子?

时间:2015-01-28 00:54:07

标签: java graphics nested-loops

我是初学者,有图形,还有Java。似乎无论我做什么,这个程序都行不通! :(无论如何,目标是“使用嵌套循环,图形和Math.random()打印出方形图案” 该图案是14行×20列,彼此相邻的30x30个正方形。 到目前为止,这是我的代码:

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;
		    
		    
		}   
			
	  

}
}

每个方格也应该是不同的随机颜色。我做错了什么? 非常感谢你:))

1 个答案:

答案 0 :(得分:2)

首先查看Performing Custom PaintingPainting in AWT and Swing,了解有关绘画实际效果的详细信息。

您无法控制绘画过程,这意味着绘画可能因任何原因随时发生,其中许多原因超出您的控制范围。这意味着,每次调用drawBoxes时,您都会生成新的颜色。

绘画也是由一系列方法调用组成的,这有助于提供更好的自定义机会,但是你通过不先调用super.paint来打破这个颜料链。

我要做的是首先创建一个List或颜色数组,它们代表网格中的每个单独的单元格。每次调用paint时我都会使用它来确保绘画是一致的

Pretty Grid

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();
        }

    }

}

<强>更新

基本问题围绕如何计算每个单元格的行/列位置以及误用Graphics#draw/fillRectangle方法。

虽然您可以简单地增加x/y内每个网格的for-loop位置,但更简单的方法是根据您当前的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;

下一个问题是滥用Graphics#draw/fillRect。 JavaDocs说明了

  

public abstract void fillRect(int x,
  int y,
  int width,
  int height)

填充指定的矩形。矩形的左右边缘位于x和x +宽度 - 1   顶部和底部边缘位于y和y +高度 - 1.结果   矩形覆盖区域宽度像素宽高度像素高。该   使用图形上下文的当前填充矩形   颜色。

参数:
x - x的坐标   要填充的矩形。
y - 矩形的y坐标   填充。
宽度 - 要填充的矩形的宽度   height - 要填充的矩形的高度。

这意味着最后两个参数应为30, 30,而不是您当前传递给它们的任何参数。

在执行任何自定义绘画之前,您还必须调用super.paint(window);