Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

java - Creating a color chooser JSlider to effect the fill color of rectangle

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.

The original request was:

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

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(gree

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

1 Reply

0 votes
by (71.8m points)

This does nothing of use:

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

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.

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

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.


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.

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

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

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

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...