创建颜色选择器 JSlider 来影响矩形的填充颜色 [英] Creating a color chooser JSlider to effect the fill color of rectangle

查看:33
本文介绍了创建颜色选择器 JSlider 来影响矩形的填充颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任务是创建一个颜色选择器.为什么当我移动滑块时颜色没有改变?我必须使用 JSlider 来影响矩形的填充颜色.

The assignment is to create a color chooser. Why is it when I move the slider the color is not changing? I have to use a JSlider to effect the fill color of rectangle.

原始请求是:

(创建颜色选择器)声明一个 JPanel 的子类,名为 MyColorChooser,它提供三个 JSlider 对象和三个 JTextField对象.每个 JSlider 代表颜色的红色、绿色和蓝色部分从 0 到 255 的值.使用这些值作为 Color 构造函数的参数来创建一个新的 Color 对象.在对应的JTextField中显示每个JSlider的当前值.当用户更改 JSlider 的值时,JTextField 应相应更改.将您的新 GUI 组件用作应用程序的一部分,该应用程序通过绘制一个实心矩形来显示当前的 Color 值.

(Creating a Color Chooser) Declare a subclass of JPanel called MyColorChooser that provides three JSlider objects and three JTextField objects. Each JSlider represents the values from 0 to 255 for the red, green and blue parts of a color. Use these values as the arguments to the Color constructor to create a new Color object. Display the current value of each JSlider in the corresponding JTextField. When the user changes the value of the JSlider, the JTextField should be changed accordingly. Use your new GUI component as part of an application that displays the current Color value by drawing a filled rectangle.

package creatingacolorchooser;

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 *
 * @author ian20
 */
public class MyColorChooser extends JPanel
{
    private JLabel redLabel;
    private JLabel greenLabel;
    private JLabel blueLabel;
    private JTextField redText;
    private JTextField greenText;
    private JTextField blueText;
    private JSlider redSlider;
    private JSlider greenSlider;
    private JSlider blueSlider;


   /**
    * Constructor
     */
    public MyColorChooser()
    {        
    //Create FlowLayout manager.
    setLayout(new FlowLayout());

    //Create message Labels
    redLabel = new JLabel("Red: ");
    greenLabel = new JLabel("Green: ");
    blueLabel = new JLabel("Blue: ");

    //Create read only text fields.
    redText = new JTextField("0", 5);
    greenText = new JTextField("0", 5);
    blueText = new JTextField("0", 5);

    //Create JSlider
    redSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
    redSlider.setPreferredSize(new Dimension(1000,75));
    redSlider.setMajorTickSpacing(10);
    redSlider.setMinorTickSpacing(1);
    redSlider.setPaintTicks(true);
    redSlider.setPaintLabels(true);
    redSlider.addChangeListener(new RedSlideListener());

    greenSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
    greenSlider.setPreferredSize(new Dimension(1000,75));
    greenSlider.setMajorTickSpacing(10);
    greenSlider.setMinorTickSpacing(1);
    greenSlider.setPaintTicks(true);
    greenSlider.setPaintLabels(true);
    greenSlider.addChangeListener(new GreenSlideListener());

    blueSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
    blueSlider.setPreferredSize(new Dimension(1000,75));
    blueSlider.setMajorTickSpacing(10);
    blueSlider.setMinorTickSpacing(1);
    blueSlider.setPaintTicks(true);
    blueSlider.setPaintLabels(true);
    blueSlider.addChangeListener(new BlueSlideListener());

    //
    add(redLabel);
    add(redSlider);
    add(redText);
    add(greenLabel);
    add(greenSlider);
    add(greenText);
    add(blueLabel);
    add(blueSlider);
    add(blueText);        
    }

    /**
     * Private inner class to handle the the change events that are 
     *  generated when the slider is moved 
     */
private class RedSlideListener implements ChangeListener
{
    public void stateChanged(ChangeEvent e)
    {
        int redInt;

        //get slider value
        redInt = redSlider.getValue();

        //Create object and set value.
        RectPanel rp = new  RectPanel();
        rp.setRed(redInt = redSlider.getValue());

        //Display slider value in text field.
        redText.setText(Integer.toString(redInt));
    }
}

/**
 * Private inner class to handle the the change events that are generated 
 * when the slider is moved 
 */
private class GreenSlideListener implements ChangeListener
{
    public void stateChanged(ChangeEvent e)
    {
        int greenInt;

        //get slider value
        greenInt = greenSlider.getValue();

        //Create object and set value.
        RectPanel rp = new  RectPanel();
        rp.setGreen(greenInt = greenSlider.getValue());

        //Display slider value in text field.
        greenText.setText(Integer.toString(greenInt));
    }
}

/**
 * Private inner class to handle the the change events that are generated 
 * when the slider is moved 
 */
private class BlueSlideListener implements ChangeListener
{
    public void stateChanged(ChangeEvent e)
    {
        int blueInt;

        //get slider value
        blueInt = blueSlider.getValue();

        //Create object and set value.
        RectPanel rp = new  RectPanel();
        rp.setBlue(blueInt = blueSlider.getValue());

        //Display slider value in text field.
        blueText.setText(Integer.toString(blueInt));
    }
   }
}


enter code here                

            package creatingacolorchooser;
            import java.awt.Color;
            import javax.swing.*;
            import java.awt.Graphics;

            /**
             *
             * @author ian20
             */
            public class RectPanel extends JPanel
            {
                private int red;
                private int blue;
                private int green;

                /**
                 * The setRed method sets int red to a int value.
                 * @param r 
                 */
                public void setRed(int r)
                {
                    red = r;
                }

                /**
                 * The setBlue method sets int blue to a int value.
                 * @param r 
                 */
                public void setBlue(int b)
                {
                    blue = b;
                }

                /**
                 * The setGreen method sets int Green to a int value.
                 * @param r 
                 */
                public void setGreen(int g)
                {
                    green = g;
                }

                /**
                 * The getRed method returns int value called red.
                 * @return 
                 */
                public int getRed()
                {
                    return red;
                }

                /**
                 * The getBlue method returns int value called blue.
                 * @return 
                 */
                public int getBlue()
                {
                    return blue;
                }

                /**
                 * The getGreen method returns int value called blue.
                 * @return 
                 */
                public int getGreen()
                {
                    return green;
                }

                @Override
                public void paintComponent(Graphics g) 
                {
                    super.paintComponent(g);

                    RectPanel rp = new RectPanel();

                    g.setColor(new Color(rp.getRed(),rp.getBlue(),rp.getGreen()));
                    g.fillRect(475, 50, 200, 200);
                }
            }


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package creatingacolorchooser;
import java.awt.GridLayout;
import javax.swing.JFrame;

/**
 *
 * @author ian20
 */
public class MainColor 
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Change Rectangle Color");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        RectPanel rect = new RectPanel();
        rect.repaint();

        MyColorChooser mcc = new MyColorChooser();
        frame.setLayout(new GridLayout(2, 1));
        frame.add(rect);
        frame.add(mcc);
        frame.setSize(1150, 600);
        frame.setVisible(true);        
    }
}

代码中唯一不能按我想要的方式工作的部分是滑块不影响 setColor.

The only part of the code that does not work the way I want is the slider does not effect the setColor.

我改变了一些东西,它似乎有效,任何评论都将不胜感激.

I changed things around and it seems to work any comments would be appreciated.

    /*
     * Class MyColorChooser holds sliders affecting text fields, labels, and a 
     * graphic affected by the position of the sliders.
     */
    package creatingacolorchooser;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import javax.swing.*;
    import java.awt.Graphics;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;

    /**
     *
     * @author ian20
     */
    public class MyColorChooser extends JPanel
    {
        private int red;              //Holds int value as red.
        private int green;            //Holds int value as green.
        private int blue;             //Holds int value as blue.  
        private JLabel redLabel;      //Holds red color label
        private JLabel greenLabel;    //Holds blue color label
        private JLabel blueLabel;     //Holds green color label
        private JTextField redText;   //Holds numerical value of red colod
        private JTextField greenText; //Holds numerical value of green colod
        private JTextField blueText;  //Holds numerical value of blue colod
        private JSlider redSlider;    //Holds the red JSlider
        private JSlider greenSlider;  //Holds the green JSlider
        private JSlider blueSlider;   //Holds the blue JSlider

        public MyColorChooser()
        {
            //Create layout
            setLayout(new FlowLayout());

            //Create labels
            redLabel = new JLabel("Red: ");
            greenLabel = new JLabel("Green: ");
            blueLabel = new JLabel("Blue: ");

            //Create read only text fields.
            redText = new JTextField("0", 5);
            redText.setEditable(false);
            greenText = new JTextField("0", 5);
            greenText.setEditable(false);
            blueText = new JTextField("0", 5);
            blueText.setEditable(false);

            //Create JSlider
            redSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
            redSlider.setPreferredSize(new Dimension(1000,75));
            redSlider.setMajorTickSpacing(10);
            redSlider.setMinorTickSpacing(1);
            redSlider.setPaintTicks(true);
            redSlider.setPaintLabels(true);
            redSlider.addChangeListener(new ColorSlideListener());

            greenSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
            greenSlider.setPreferredSize(new Dimension(1000,75));
            greenSlider.setMajorTickSpacing(10);
            greenSlider.setMinorTickSpacing(1);
            greenSlider.setPaintTicks(true);
            greenSlider.setPaintLabels(true);
            greenSlider.addChangeListener(new ColorSlideListener());

            blueSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
            blueSlider.setPreferredSize(new Dimension(1000,75));
            blueSlider.setMajorTickSpacing(10);
            blueSlider.setMinorTickSpacing(1);
            blueSlider.setPaintTicks(true);
            blueSlider.setPaintLabels(true);
            blueSlider.addChangeListener(new ColorSlideListener());

            //Add components to the panel        
            add(redLabel);
            add(redSlider);
            add(redText);
            add(greenLabel);
            add(greenSlider);
            add(greenText);
            add(blueLabel);
            add(blueSlider);
            add(blueText);
        }

        /**
         * Private inner class to handle the the change events that are generated 
         * when the slider is moved 
         */
        private class ColorSlideListener implements ChangeListener
        {
            public void stateChanged(ChangeEvent e)
            {   
                //get slider value
                red = redSlider.getValue();
                green = greenSlider.getValue();
                blue = blueSlider.getValue();            

                //Display slider value in text field.
                redText.setText(Integer.toString(red));
                greenText.setText(Integer.toString(green));
                blueText.setText(Integer.toString(blue));

                //Set rectangle color.
                repaint();
            }
        }
        /**
         * The paintComponent creates a rectangle with adjustable coloring
         * @param g 
         */
        @Override
        public void paintComponent(Graphics g) 
        {
            super.paintComponent(g);

            g.setColor(new Color(red, green, blue));
            g.fillRect(420, 300, 300, 100);
        }
    }


    /*
     * The MainColor creates the GUI for the Selected RectPanel application.
     */
    package creatingacolorchooser;
    import java.awt.GridLayout;
    import javax.swing.JFrame;

    /**
     *
     * @author ian20
     */
    public class MainColor 
    {
        public static void main(String[] args)
        {
            //Create frame object
            JFrame frame = new JFrame("Change Rectangle Color");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            //Create rect object
            MyColorChooser mcc = new MyColorChooser();

            //Add to the frame, set layout, set size, and make it viable.
            frame.setLayout(new GridLayout(1, 1));
            frame.add(mcc);
            frame.setSize(1150, 500);
            frame.setVisible(true);        
        }
    }

推荐答案

这没有任何用处:

RectPanel rp = new  RectPanel();
rp.setRed(redInt = redSlider.getValue());

当您创建一个 JPanel 时,更改其属性并无处显示.相反,您应该更改已显示的 RectPanel JPanel 的状态,而不是创建一个新的.这意味着必须将要更改颜色的 JPanel 的引用传递到您的颜色选择器对象中,以便可以更改其状态(颜色).

as you're creating a new JPanel, changing its properties and displaying it nowhere. Instead you should change the state of your already displayed RectPanel JPanel, not create a new one. This means that the reference to the JPanel's who color is to be changed must be passed into your color chooser object so that its state (color) can be changed.

此外,您应该不要在paintComponent方法中创建一个RectPanel.

Also you should not be creating a RectPanel within the paintComponent method.

你的问题相当于你拥有一辆蓝色的福特野马,然后你去车店买了一辆新的福特野马,把它涂成绿色,然后想知道为什么原来的野马还是蓝色的,这个问题源于关于什么是对象以及它们如何工作的基本混淆.每次使用 new 运算符调用类的构造函数时,请了解您正在创建该类型对象的全新且唯一的实例,并且该实例完全独立于之前可能已创建的其他实例.

Your problem is equivalent to your owning a blue Ford Mustang, then you go the car shop, buy a new Ford Mustang, have it painted green, and then wonder why the original Mustang is still blue, and this problem stems from a fundamental confusion about what objects are and how they work. Every time you call a class's constructor using the new operator, understand that you are creating a completely new and unique instance of that type of object, and this instance is completely independent from other instances that may have been created before.

我创建了一个工作示例,但我不会在这里发布整个内容,因为我们不做作业,但我会发布其中的一部分.请注意,我创建了一个用于 3 种不同颜色的 JPanel,称为 ColorSliderPanel.我还称我的绘图 JPanel MyColorPanel.

I created a working example, but am not going to post the entire thing here, since we don't do homework, but I will post part of it. Note that I created a single JPanel to be used with the 3 different colors, called ColorSliderPanel. I also called my drawing JPanel MyColorPanel.

ColorSliderPanel 的部分看起来像这样:

Portions of the ColorSliderPanel look like this:

public class ColorSliderPanel extends JPanel {
    private static final int MAX_COLOR = 255;
    private Color color;
    private JSlider slider = new JSlider(0, MAX_COLOR, 0);
    private JTextField textField = new JTextField("0", 5);
    private MyColorPanel myColorPanel;

    // here is the key, my constructor takes MyColorPanel reference
    public ColorSliderPanel(String text, Color color, MyColorPanel myColorPanel) {
        this.color = color;
        this.myColorPanel = myColorPanel;  // and then sets the field of the class

        slider.setMajorTickSpacing(20);
        slider.setMinorTickSpacing(1);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        slider.addChangeListener(new SliderListener());

        // .....

        setBorder(BorderFactory.createTitledBorder(text)); 

        // .....

    }

    private class SliderListener implements ChangeListener {
        @Override
        public void stateChanged(ChangeEvent cEvt) {
            int newValue = slider.getValue();

            // call getColor() on the original MyColorPanel object
            Color origClr = myColorPanel.getColor(); // get the original color
            textField.setText("" + newValue);

            // here we decide what the new color's r,g,b should be----

            // ......

            Color newColor = new Color(r, g, b);

            // set the color of the original MyColorPanel object
            myColorPanel.setColor(newColor);
        }
    }
}

MyColorPanel 的部分内容.请注意,我为它提供了 getColor()setColor(Color color) 方法,但如果您愿意,您可以使用自己的红色/蓝色/绿色 getter/setter:>

Portions of the MyColorPanel. Note that I give it getColor() and setColor(Color color) methods, but you can use your individual red/blue/green getters/setters if you wish:

public class MyColorPanel extends JPanel {
    private static final Color INIT_COLOR = Color.BLACK;
    private static final int RECT_WIDTH = 200;
    private Color color = INIT_COLOR;

    // ...

    public Color getColor() {
        return color;
    }

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

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(color);
        int rectX = (getWidth() - RECT_WIDTH) / 2;
        int rectY = (getHeight() - RECT_WIDTH) / 2;
        g.fillRect(rectX, rectY, RECT_WIDTH, RECT_WIDTH);
    }
}   

主 GUI 将所有内容连接在一起,如下所示:

The main GUI hooked everything together like so:

public class MyColorFoo extends JPanel {
    private MyColorPanel myColorPanel = new MyColorPanel(1000, 400);

    public MyColorFoo() {
        JPanel slidersPanel = new JPanel(new GridLayout(0, 1, 3, 3));
        slidersPanel.add(new ColorSliderPanel("Red", Color.RED, myColorPanel));
        slidersPanel.add(new ColorSliderPanel("Green", Color.GREEN, myColorPanel));
        slidersPanel.add(new ColorSliderPanel("Blue", Color.BLUE, myColorPanel));

        setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
        setLayout(new BorderLayout(3, 3));
        add(myColorPanel, BorderLayout.CENTER);
        add(slidersPanel, BorderLayout.PAGE_END);
    }

<小时>

更新更完整的版本:


A newer more complete version:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.*;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class ColorExample extends JPanel {
    private ColorSliderPanel[] sliders = { 
            new ColorSliderPanel(Color.RED, "Red"),
            new ColorSliderPanel(Color.GREEN, "Green"), 
            new ColorSliderPanel(Color.BLUE, "Blue") };
    private JPanel colorPanel = new JPanel();

    public ColorExample() {
        JPanel sliderPanel = new JPanel(new GridLayout(0, 1));
        for (ColorSliderPanel colorSliderPanel : sliders) {
            sliderPanel.add(colorSliderPanel);
            colorSliderPanel.addListener(evt -> setColorPanelBackground());
        }

        colorPanel.setPreferredSize(new Dimension(600, 300));
        setLayout(new GridLayout(0, 1));
        add(colorPanel);
        add(sliderPanel);
        setColorPanelBackground();
    }

    private void setColorPanelBackground() {
        int rgb = 0;
        for (ColorSliderPanel colorSliderPanel : sliders) {
            Color c = colorSliderPanel.getColor();
            int value = colorSliderPanel.getValue();

            // numeric magic here:
            rgb |= value * (0x10101 & c.getRGB());
        }
        colorPanel.setBackground(new Color(rgb));
    }

    private static void createAndShowGui() {
        ColorExample mainPanel = new ColorExample();

        JFrame frame = new JFrame("Color Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

@SuppressWarnings("serial")
class ColorSliderPanel extends JPanel {
    private final static int MAX_VALUE = 255;
    private Color color;
    private String text;
    private JSlider slider = new JSlider(0, MAX_VALUE, MAX_VALUE / 2);

    public ColorSliderPanel(Color color, String text) {
        this.color = color;
        this.text = text;
        setBackground(color);

        // lighter color
        int colorInt = color.getRGB() | 0x7f7f7f;
        slider.setBackground(new Color(colorInt));
        slider.setMajorTickSpacing(50);
        slider.setMinorTickSpacing(5);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);

        setLayout(new BorderLayout());
        add(slider);
        setBorder(BorderFactory.createTitledBorder(text));
    }

    public Color getColor() {
        return color;
    }

    public String getText() {
        return text;
    }

    public int getValue() {
        return slider.getValue();
    }

    public void addListener(ChangeListener listener) {
        slider.addChangeListener(listener);
    }

}

这篇关于创建颜色选择器 JSlider 来影响矩形的填充颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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