【问题标题】:Creating a color chooser JSlider to effect the fill color of rectangle创建颜色选择器 JSlider 以影响矩形的填充颜色
【发布时间】:2018-09-28 22:58:01
【问题描述】:

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

原来的请求是:

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

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

我改变了一些东西,它似乎可以工作,任何 cmets 都会受到赞赏。

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

【问题讨论】:

  • 我发布了修改后的代码。感谢您的建议
  • 请考虑回复我的回答。有关这方面的更多信息,请从帮助站点阅读此部分:someone answers

标签: java swing colors jslider


【解决方案1】:

这没什么用:

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

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

您也应该在 paintComponent 方法中创建 RectPanel。

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


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

ColorSliderPanel 的某些部分如下所示:

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:

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 将所有内容连接在一起,如下所示:

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

更新更完整的版本:

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

}

【讨论】:

  • 如何通过颜色选择器对象发送它
  • @IanMcCoy:有几种方法,包括“M-V-C”,但最简单的方法是将彩色 JPanel 传入颜色选择器对象。
  • 这是我第一次尝试的方法,但无法让它发挥作用,你能提供一个例子吗?
  • @IanMcCoy:我在上面发布了一个部分示例,只是为了向您展示我是如何“连接”的,但我还没有发布我的整个程序跨度>
  • @IanMcCoy:现在有意义吗?如果没有,那么请考虑 editing your original post 展示您自己尝试更改 visualized 绘图 JPanel 的状态。
猜你喜欢
  • 2020-10-28
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
  • 2015-09-20
  • 2020-12-12
  • 2015-06-07
  • 1970-01-01
  • 2014-10-27
相关资源
最近更新 更多