如何知道什么r,g,b值用于获得其他颜色动态绘制JFrame? [英] How to know what r,g,b values to use for get other colours to paint a JFrame dynamically?

查看:186
本文介绍了如何知道什么r,g,b值用于获得其他颜色动态绘制JFrame?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何管理 rgb 值来动态更改JFrame的背景颜色,现在我只能从绿色更改为蓝色,反之亦然;这是我需要的颜色:

I want to know how to manage the rgb values to change the background colour of a JFrame dynamically, by now i can only change from green to blue and versa vice; this are the colours that i need:

这些颜色的rgb可以找到这里

The rgb of these colours can be found here

这里是如何动态从绿色变为蓝色的示例代码:

Here's my sample code of how to change from green to blue dynamically:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ChangeColor {

    public ChangeColor() {
        JFrame frame = new JFrame();
        frame.add(new ColorPanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public class ColorPanel extends JPanel {

        private static final int DELAY = 30;
        private static final int INCREMENT = 15;
        private Color currentColor = Color.BLUE;
        boolean isBlue = true;
        boolean isGreen = false;
        private int r,g,b;

        private Timer timer = null;
        private JButton greenButton = null;
        private JButton blueButton = null;

        public ColorPanel() {
            r = 0; g = 0; b = 255;

            greenButton = createGreenButton();
            blueButton = createBlueButton();

            timer = new Timer(DELAY, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    if (isBlue) {
                        if (b == 0) {
                            stopTimer();
                            enableButtons();
                        } else {
                            blueToGreen();
                            setColor(new Color(r, b, g));
                        }
                    } 

                    if (isGreen) {
                        if (g == 0) {
                            stopTimer();
                            enableButtons();
                        } else {
                            greenToBlue();
                            setColor(new Color(r, b, g));
                        }
                    }

                    repaint();
                }
            });

            add(blueButton);
            add(greenButton);
        }

        public JButton createBlueButton() {
            JButton button = new JButton("BLUE");
            button.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (currentColor != new Color(0, 255, 0)) {
                        System.out.println("turn blue");
                        isBlue = true;
                        isGreen = false;
                        diableButtons();
                        startTimer();   
                    }
                }
            });
            return button;
        }

        public void diableButtons() {
            blueButton.setEnabled(false);
            greenButton.setEnabled(false);
        }

        public void enableButtons() {
            blueButton.setEnabled(true);
            greenButton.setEnabled(true);
        }

        public JButton createGreenButton() {
            JButton button = new JButton("GREEN");
            button.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (currentColor != new Color(0, 0, 255)) {
                        System.out.println("turn green");
                        isGreen = true;
                        isBlue = false;
                        diableButtons();
                        startTimer();

                    }
                }
            });
            return button;
        }

        private void blueToGreen() {
            b -= INCREMENT;
            g += INCREMENT;
        }

        private void greenToBlue() {
            g -= INCREMENT;
            b += INCREMENT;
        }



        public void setColor(Color color) {
            this.currentColor = color;
        }

        public void startTimer() {
            timer.start();
        }

        public void stopTimer() {
            timer.stop();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(currentColor);
            g.fillRect(0, 0, getWidth(), getHeight());
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                new ChangeColor();
            }
        });

    }
}

代码有一些错误,它不是最强大的代码,所以如果你可以改进它,我会感谢

The code has some bugs, and it's not the most robust code, so that if you can improve it, i'll be thanked

下面是示例代码的输出:

Here's the output of the sample code:

>

推荐答案

您当前的方法确实不容易推广。 蓝色和绿色按钮的硬编码部分,特别是像 blueToGreen 的特殊方法使得不可能用合理的努力来扩展颜色数量。 (您不想创建方法 blueToYellow blueToRed blueToTheThirdColorFromThisListForWhichIDontKnowAName ...)。

Your current approach is indeed not easily generalizable. The hard-coded parts of the buttons for "blue" and "green", and especially the special methods like blueToGreen make it impossible to extend the number of colors with reasonable effort. (You don't want to create methods blueToYellow, blueToRed, blueToTheThirdColorFromThisListForWhichIDontKnowAName ...).

有很多可能的方法来概括这个。你没有说明预期的结构和职责。但是你应该至少创建一个方法,它可以用给定的步数在两个任意颜色之间插值。在下面的代码片段中,这是在'createColorsArrayArgb`方法中完成的,它创建了一个任意颜色序列(我最近需要这个颜色)的ARGB颜色数组。但你可以煮到2种颜色,如果你想。

There are many possible ways of generalizing this. You did not say much about the intended structure and responsibilities. But you should at least create a method that can interpolate between two arbitrary colors with a given number of steps. In the code snippet below, this is done in the ´createColorsArrayArgb` method, which creates an array of ARGB colors from an arbitrary sequence of colors (I needed this recently). But you can probably boil it down to 2 colors, if you want to.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ChangeColor
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new ChangeColor();
            }
        });
    }

    public ChangeColor()
    {
        JFrame frame = new JFrame();

        ColorPanel colorPanel = new ColorPanel(Color.BLUE);
        ColorInterpolator ci = new ColorInterpolator(colorPanel, Color.BLUE);

        colorPanel.addColorButton(createButton("Blue", Color.BLUE, ci));
        colorPanel.addColorButton(createButton("Green", Color.GREEN, ci));
        colorPanel.addColorButton(createButton("Red", Color.RED, ci));
        colorPanel.addColorButton(createButton("Cyan", Color.CYAN, ci));
        colorPanel.addColorButton(createButton("Yellow", Color.YELLOW, ci));
        colorPanel.addColorButton(createButton("Magenta", Color.MAGENTA, ci));

        frame.add(colorPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static JButton createButton(String name, final Color color, 
        final ColorInterpolator colorInterpolator)
    {
        JButton button = new JButton(name);
        button.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                colorInterpolator.interpolateTo(color);
            }
        });
        return button;
    }


    /**
     * Creates an array with the given number of elements, that contains the
     * ARGB representations of colors that are linearly interpolated between the
     * given colors
     * 
     * @param steps The number of steps (the size of the resulting array)
     * @param colors The colors to interpolate between
     * @return The array with ARGB colors
     */
    static int[] createColorsArrayArgb(int steps, Color... colors)
    {
        int result[] = new int[steps];
        double normalizing = 1.0 / (steps - 1);
        int numSegments = colors.length - 1;
        double segmentSize = 1.0 / (colors.length - 1);
        for (int i = 0; i < steps; i++)
        {
            double relative = i * normalizing;
            int i0 = Math.min(numSegments, (int) (relative * numSegments));
            int i1 = Math.min(numSegments, i0 + 1);
            double local = (relative - i0 * segmentSize) * numSegments;

            Color c0 = colors[i0];
            int r0 = c0.getRed();
            int g0 = c0.getGreen();
            int b0 = c0.getBlue();

            Color c1 = colors[i1];
            int r1 = c1.getRed();
            int g1 = c1.getGreen();
            int b1 = c1.getBlue();

            int dr = r1 - r0;
            int dg = g1 - g0;
            int db = b1 - b0;

            int r = (int) (r0 + local * dr);
            int g = (int) (g0 + local * dg);
            int b = (int) (b0 + local * db);
            int argb = (0xFF << 24) | (r << 16) | (g << 8) | (b << 0);
            result[i] = argb;
        }
        return result;
    }
}

class ColorInterpolator
{
    private static final int DELAY = 20;

    private Color currentColor;
    private int currentIndex = 0;
    private int currentColorsArgb[];
    private final Timer timer;
    private final ColorPanel colorPanel;

    ColorInterpolator(final ColorPanel colorPanel, Color initialColor)
    {
        this.colorPanel = colorPanel;

        currentColor = initialColor;
        currentColorsArgb = new int[]{ initialColor.getRGB() };
        timer = new Timer(DELAY, new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                currentIndex++;
                if (currentIndex >= currentColorsArgb.length-1)
                {
                    timer.stop();
                    colorPanel.enableButtons();
                }
                else
                {
                    int argb = currentColorsArgb[currentIndex];
                    currentColor = new Color(argb);
                    colorPanel.setColor(currentColor);
                }
            }
        });
    }

    void interpolateTo(Color targetColor)
    {
        colorPanel.diableButtons();
        currentColorsArgb = ChangeColor.createColorsArrayArgb(
            40, currentColor, targetColor);
        currentIndex = 0;
        timer.start();
    }
}


class ColorPanel extends JPanel
{
    private Color currentColor;
    private List<JButton> buttons;

    public ColorPanel(Color initialColor)
    {
        currentColor = initialColor;
        buttons = new ArrayList<JButton>();
    }

    void addColorButton(JButton button)
    {
        buttons.add(button);
        add(button);
    }

    public void diableButtons()
    {
        for (JButton button : buttons)
        {
            button.setEnabled(false);
        }
    }

    public void enableButtons()
    {
        for (JButton button : buttons)
        {
            button.setEnabled(true);
        }
    }

    public void setColor(Color color)
    {
        currentColor = color;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(currentColor);
        g.fillRect(0, 0, getWidth(), getHeight());
    }

    @Override
    public Dimension getPreferredSize()
    {
        return new Dimension(600, 300);
    }
}

这篇关于如何知道什么r,g,b值用于获得其他颜色动态绘制JFrame?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆