Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
297 views
in Technique[技术] by (71.8m points)

java - How to know what r,g,b values to use for get other colours to paint a JFrame dynamically?

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:

The rgb of these colours can be found here

rgb(241, 196, 15) rgb(230, 126, 34) rgb(231, 76, 60) rgb(236, 240, 241) rgb(149, 165, 166) rgb(26, 188, 156) rgb(46, 204, 113) rgb(52, 152, 219) rgb(155, 89, 182) rgb(52, 73, 94)

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:

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 ...).

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...