简体   繁体   English

渐变色画布上的Java挑战

[英]Java Challenge on A Gradient Color Canvas

This is probably an elementary question. 这可能是一个基本问题。 However, I have completed reading the 9th Chapter of Java Programming for the Absolute Beginner and have approached the Challenges section. 但是,我已经阅读了《 Java编程入门》第9章,并且已经进入“挑战”部分。 I cannot quite get the progam to show a gradient from dark to light. 我不能完全理解该程序来显示从暗到亮的渐变。

The question asks: 问题问:

"Create a Canvas that paints a gradient that's dark on one side and slowly gets lighter as it moves to the other side." “创建一个画布,该画布在一侧涂上深色阴影,并在移至另一侧时逐渐变亮。”

I have looked at the Java Challenge on Creating a Canvas page (which I asked about before) and got a better understanding of creating a color gradient canvas, however, I am still having great difficulty. 我看过“创建画布”页面Java挑战 (我之前曾问过),并且对创建颜色渐变画布有更好的理解,但是,我仍然遇到很大困难。

I think that my main problem is how to get the gray colors in between as the program shows a completely black square or when run with just the first for loop, a completely white square. 我认为我的主要问题是,当程序显示一个完全为黑色的正方形或仅在第一个for循环(一个完全为白色的正方形)运行时,如何获得介于两者之间的灰色。 I THINK THAT MY FOR LOOPS ARE PROBLEMATIC AND DO NOT CORRECTLY IDENTIFY THE VARIABLES. 我认为我的问题是有问题的,并且不能正确识别变量。

An answer to this question can potentially aid many new Java programmers in understanding Graphics and Canvas. 这个问题的答案可能会帮助许多新的Java程序员理解Graphics和Canvas。

I do not know JFrame, Swing, Points, JPanels, BufferedImage, or GradientPaint. 我不知道JFrame,Swing,Points,JPanels,BufferedImage或GradientPaint。

Thank you very much for your time and cooperation reagrding this matter. 非常感谢您抽出宝贵时间与合作解决此问题。

HERE IS THE CODE: 代码如下:

import java.awt.*;

public class RandomColorSquare extends GUIFrame {
    Canvas slight;
    public final static int MIN = 0,
        MAX = 225;

    public RandomColorSquare(int r, int g, int b) {
        super("Random Color Square");
        r = r >= MIN && r <= MAX ? r : MIN;
        g = g >= MIN && g <= MAX ? g : MIN;
        b = r >= MIN && b <= MAX ? b : MIN;
        slight = new Canvas();
        slight.setBackground(new Color(r,g, b));
        slight.setSize(200, 150);
        add(slight, BorderLayout.CENTER);

        for(r=0; r<225; r++) {
            Color c = slight.getBackground().brighter();
            slight.setBackground(c);
        }

        for (g=0; g<225; g++) {
            Color d = slight.getBackground().darker();
            slight.setBackground(d);
        }
        for (b=0; b<225; b++) {
             Color e = slight.getBackground().darker();
             slight.setBackground(e);
        }

        pack();
        setVisible(true);
    }

    public static void main(String args[]) {
        if (args.length != 3) {
            new RandomColorSquare(0, 0, 0);
        }
        else {
            new RandomColorSquare(Integer.parseInt(args[0]),                                     Integer.parseInt(args[1]),
                   Integer.parseInt(args[2]));
        }
    }
}

First of all, as I mentioned in the comment, when you setBackground you are changing the background of the Canvas , not adding to it. 首先,正如我在评论中提到的那样,当您设置setBackground您是在更改Canvas的背景,而不是对其进行添加。 So whatever you set it to last is what you see. 因此,只要将其设置为last,就可以看到。 In your case, that is the darkest form of blue, which is just black. 在您的情况下,这是蓝色的最暗形式,也就是黑色。 If you comment out the last two loops, you get a white background (the brightest red). 如果注释掉最后两个循环,则会得到白色背景(最亮的红色)。

However. 然而。 Using only what you know this is the best I can come up with. 仅使用您所知道的,这就是我能想到的最好的方法。 It involves creating your own custom Canvas , which I called CustomCanvas . 它涉及创建自己的自定义Canvas ,我称之为CustomCanvas In there, you can override the paint method and keep drawing progressively lighter filled rectangles across the screen. 在这里,您可以覆盖绘画方法,并在整个屏幕上逐渐绘制较亮的填充矩形。 Here's a small sample to help you understand what I mean: 这是一个小样本,可以帮助您理解我的意思:

class CustomeCanvas extends Canvas{
    public void paint(Graphics g){
        Color background = new Color(30,30,120); //Set this accordingly
        for(int i=0;i<getWidth();i++){
            g.setColor(background);
            background = getBrighter(background);
            g.fillRect(i,0, 1, getHeight());
        }
    }

    private Color getBrighter(Color c) {
        int r = c.getRed();
        int g = c.getGreen();
        int b = c.getBlue();

        if(r< MAX) r+=1;
        if(g< MAX) g+=1;
        if(b< MAX) b+=1;

        return new Color(r,g,b);
    }
}

Which produces this background: 产生此背景:

在此处输入图片说明

I still recommend reading about GradientPaint which makes this process a lot easier and nicer. 我仍然建议阅读有关GradientPaint的内容 ,这使此过程变得更加容易和友好。

You can override paint() in your Canvas in a manner similar to how this example does for Panel . 您可以以类似于本示例Panel进行操作的方式在Canvas中覆盖paint() In your implementation, use drawImage() to render a BufferedImage in which you've used setRGB() to construct your gradient. 在您的实现中,使用drawImage()渲染BufferedImage在其中使用setRGB()构造渐变。

Addendum: The example below illustrates the approach by creating a random image. 附录:以下示例通过创建随机图像说明了该方法。 You can create a gradient similarly. 您可以类似地创建渐变。

图片]

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/** @see https://stackoverflow.com/a/14096121/230513 */
public class AWTImage {

    public static void main(String[] args) throws IOException {
        Frame frame = new Frame();
        frame.add(new ImageCanvas());
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.pack();
        frame.setVisible(true);
    }

    private static class ImageCanvas extends Canvas {

        private static final Random r = new Random();
        private BufferedImage image;

        public ImageCanvas() {
            image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
            for (int row = 0; row < image.getHeight(); row++) {
                for (int col = 0; col < image.getWidth(); col++) {
                    image.setRGB(col, row, r.nextInt());
                }
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(image.getWidth(), image.getHeight());
        }

        @Override
        public void paint(Graphics g) {
            g.drawImage(image, 0, 0, this);
        }
    }
}

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

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