Search code examples
javaswinggraphicspaintcomponentjspinner

Set color of FillRect() using value of scrollbar or spinner


I have created two JPanels and added them on to a mainpanel, then added this JPanel on the JFrame. I am unable to set the color of rectangle using changing value of spinner or scrollbar. If any one have solution then help me for this paroblem.

TestColorFrame.java

import java.awt.BorderLayout;
import java.awt.GridLayout;import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.metal.MetalLookAndFeel;
import com.swing.Myframe;

public class TestColorFrame extends JFrame {

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (ClassNotFoundException | InstantiationException
                | IllegalAccessException | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
        JFrame f = new JFrame();
        JPanel Mainpanel = new JPanel(new GridLayout(2, 1));

        ColorPanel1 p = new ColorPanel1();
        ColorPanel2 p1 = new ColorPanel2();

        //f.getContentPane().setLayout(new BorderLayout() );
        f.add(Mainpanel);

        Mainpanel.add(p);
        Mainpanel.add(p1,BorderLayout.SOUTH);

        f.setVisible(true);
        f.setResizable(false);
        f.setSize(500,500);
        f.setTitle("My Color Frame");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    }
}

ColorPanel1.java

import java.awt.Adjustable;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ColorPanel1 extends JPanel implements
                    AdjustmentListener,ChangeListener { 
    ColorPanel2 p;
    private JLabel jLabelred,jLabelgreen,jLabelblue;

    public JScrollBar jRedScrollbar,jGreenScollbar,jBlueScrollbar;
    //private JTextField jRedtext,jGreentext,jBluetext;
    protected JSpinner jRed, jGreen, jBlue;
    ColorPanel2 color2;
    public Color current;

    public ColorPanel1() {
        setLayout(new GridLayout(3, 3,60,60));
        jLabelred = new JLabel("RED");
        add(jLabelred);

        SpinnerModel spinnerModel = new SpinnerNumberModel(100, 0, 255, 1) ;
        jRed = new JSpinner(spinnerModel);
        add(jRed); 
        jRedScrollbar = new JScrollBar(JScrollBar.HORIZONTAL, 100, 40, 0, 255);
        add(jRedScrollbar);

        jLabelgreen = new JLabel("GREEN");
        add(jLabelgreen);
        SpinnerModel spinnerModel1 = new SpinnerNumberModel(200, 0, 255, 1);
        jGreen = new JSpinner(spinnerModel1);
        add(jGreen);

        jGreenScollbar = new JScrollBar(JScrollBar.HORIZONTAL, 200, 4, 0, 255);
        add(jGreenScollbar);

        jLabelblue = new JLabel("BLUE");
        add(jLabelblue);
        SpinnerModel spinnerModel2 = new SpinnerNumberModel(50, 0, 255, 1);
        jBlue = new JSpinner(spinnerModel2);
        add(jBlue);

        jBlueScrollbar = new JScrollBar(JScrollBar.HORIZONTAL, 50, 40, 0, 255);
        add(jBlueScrollbar);

        jRedScrollbar.addAdjustmentListener(this);
        jBlueScrollbar.addAdjustmentListener(this);
        jGreenScollbar.addAdjustmentListener(this);
        spinnerModel.addChangeListener(this);
        spinnerModel1.addChangeListener(this);
        spinnerModel2.addChangeListener(this);
    }

    @Override
    public void adjustmentValueChanged(AdjustmentEvent e) {
        int r = jRedScrollbar.getValue();
        int g = jGreenScollbar.getValue();
        int b = jBlueScrollbar.getValue();

        jRed.setValue(jRedScrollbar.getValue()); 
        jBlue.setValue(jBlueScrollbar.getValue());
        jGreen.setValue(jGreenScollbar.getValue());
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        SpinnerModel spinnerModel = jRed.getModel();
        if (spinnerModel instanceof SpinnerModel) {
            jRedScrollbar.setValue((int) spinnerModel.getValue());
        }
        SpinnerModel spinnerModel1 = jGreen.getModel();
        if(spinnerModel1 instanceof SpinnerModel) {
            jGreenScollbar.setValue((int) jGreen.getValue());
        }
        SpinnerModel spinnerModel2 = jBlue.getModel();
        if(spinnerModel2 instanceof SpinnerModel) {
            jBlueScrollbar.setValue((int) jBlue.getValue());
        }           
    } 
}

ColorPanel2.java

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;

public class ColorPanel2 extends JPanel {

    private JColorChooser colorchooser;
    ColorPanel1 color=new ColorPanel1();

    public ColorPanel2() {
        setLayout(new BorderLayout());
    }

    public void paintComponent(Graphics graphics) {   
        super.paintComponent(graphics);
        int r = (int) color.jRed.getValue();
        int g = (int) color.jGreen.getValue();
        int b = (int) color.jBlue.getValue();
        graphics.setColor(new Color(r,g,b));
        graphics.fillRect(100, 50, 300, 150);
    } 
}

Solution

  • You need a class member Color in your ColorPanel class. And also have a setter for it. In the setter, call repaint(). In your paintComponent method, use the class member Color instead of creating a create a new Color(). Something like

    public class ColorPanel extends JPanel {
        private Color color;
    
        public void setColor(Color color) {
            this.color = color;
            repaint();
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            ...
            g.setColor(color);
        }
    }
    

    When you setColor on on the ColorPanel passing the new color, the panel will be repainted with the updated color.

    Here's a complete example

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JSpinner;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.SwingUtilities;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    
    
    public class TestColorFrame {
    
        private static final int DEFAULT_VALUE = 100;
    
        private JSpinner rSpinner;
        private JSpinner gSpinner;
        private JSpinner bSpinner;
        private ColorPanel colorPanel;
    
        public TestColorFrame() {
            colorPanel = new ColorPanel();
    
            rSpinner = createRGBSpinner();
            gSpinner = createRGBSpinner();
            bSpinner = createRGBSpinner();
    
            JPanel spinnerPanel = new JPanel();
            spinnerPanel.add(new JLabel("R"));
            spinnerPanel.add(rSpinner);
            spinnerPanel.add(new JLabel("G"));
            spinnerPanel.add(gSpinner);
            spinnerPanel.add(new JLabel("B"));
            spinnerPanel.add(bSpinner);
    
            JFrame frame = new JFrame("Color Spinners");
            frame.add(colorPanel);
            frame.add(spinnerPanel, BorderLayout.NORTH);
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
    
        }
    
        private JSpinner createRGBSpinner() {
            SpinnerNumberModel model = new SpinnerNumberModel(DEFAULT_VALUE, 0, 255, 1);
            JSpinner spinner = new JSpinner(model);
            spinner.addChangeListener(new ChangeListener(){
                public void stateChanged(ChangeEvent e) {
                    int[] values =  getModelValues();
                    colorPanel.setColor(new Color(values[0], values[1], values[2]));
                }
            });
            return spinner;
        }
    
        private int[] getModelValues() {
            int r = (Integer)((SpinnerNumberModel)rSpinner.getModel()).getValue();
            int g = (Integer)((SpinnerNumberModel)gSpinner.getModel()).getValue();
            int b = (Integer)((SpinnerNumberModel)bSpinner.getModel()).getValue();
            return new int[] {r, g, b};
        }
    
        class ColorPanel extends JPanel {
            private Color color = new Color(DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE);
    
            public void setColor(Color color) {
                this.color = color;
                repaint();
            }
    
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(color);
                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(){
                public void run() {
                    new TestColorFrame();
                }
            });
        }
    }
    

    Aside, you should probably look into using a JSlider, which seems more natural than using a JScrollBar for value adjustment


    UPDATE

    With refactor

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.GridLayout;
    import java.awt.event.AdjustmentEvent;
    import java.awt.event.AdjustmentListener;
    import javax.swing.JColorChooser;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollBar;
    import javax.swing.JSpinner;
    import javax.swing.SpinnerModel;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    
    public class TestColorFrame extends JFrame {
    
        public static void main(String[] args) {
            JFrame f = new JFrame();
            JPanel Mainpanel = new JPanel(new GridLayout(2, 1));
    
    
            ColorPanel2 p1 = new ColorPanel2();
            ColorPanel1 p = new ColorPanel1(p1);
    
            //f.getContentPane().setLayout(new BorderLayout() );
            f.add(Mainpanel);
    
            Mainpanel.add(p);
            Mainpanel.add(p1, BorderLayout.SOUTH);
    
            f.setVisible(true);
            f.setResizable(false);
            f.setSize(500, 500);
            f.setTitle("My Color Frame");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }
    
    class ColorPanel1 extends JPanel implements
            AdjustmentListener, ChangeListener {
        private JLabel jLabelred, jLabelgreen, jLabelblue;
    
        public JScrollBar jRedScrollbar, jGreenScollbar, jBlueScrollbar;
        //private JTextField jRedtext,jGreentext,jBluetext;
        protected JSpinner jRed, jGreen, jBlue;
        ColorPanel2 colorPanel2;
        public Color current;
    
        public ColorPanel1(ColorPanel2 colorPanel2) {
            this.colorPanel2 = colorPanel2;
            setLayout(new GridLayout(3, 3, 60, 60));
            jLabelred = new JLabel("RED");
            add(jLabelred);
    
            SpinnerModel spinnerModel = new SpinnerNumberModel(100, 0, 255, 1);
            jRed = new JSpinner(spinnerModel);
            add(jRed);
            jRedScrollbar = new JScrollBar(JScrollBar.HORIZONTAL, 100, 40, 0, 255);
            add(jRedScrollbar);
    
            jLabelgreen = new JLabel("GREEN");
            add(jLabelgreen);
            SpinnerModel spinnerModel1 = new SpinnerNumberModel(200, 0, 255, 1);
            jGreen = new JSpinner(spinnerModel1);
            add(jGreen);
    
            jGreenScollbar = new JScrollBar(JScrollBar.HORIZONTAL, 200, 4, 0, 255);
            add(jGreenScollbar);
    
            jLabelblue = new JLabel("BLUE");
            add(jLabelblue);
            SpinnerModel spinnerModel2 = new SpinnerNumberModel(50, 0, 255, 1);
            jBlue = new JSpinner(spinnerModel2);
            add(jBlue);
    
            jBlueScrollbar = new JScrollBar(JScrollBar.HORIZONTAL, 50, 40, 0, 255);
            add(jBlueScrollbar);
    
            jRedScrollbar.addAdjustmentListener(this);
            jBlueScrollbar.addAdjustmentListener(this);
            jGreenScollbar.addAdjustmentListener(this);
            spinnerModel.addChangeListener(this);
            spinnerModel1.addChangeListener(this);
            spinnerModel2.addChangeListener(this);
        }
    
        @Override
        public void adjustmentValueChanged(AdjustmentEvent e) {
            int r = jRedScrollbar.getValue();
            int g = jGreenScollbar.getValue();
            int b = jBlueScrollbar.getValue();
    
            jRed.setValue(jRedScrollbar.getValue());
            jBlue.setValue(jBlueScrollbar.getValue());
            jGreen.setValue(jGreenScollbar.getValue());
            setNewPanelColor();
        }
    
        @Override
        public void stateChanged(ChangeEvent e) {
            SpinnerModel spinnerModel = jRed.getModel();
            if (spinnerModel instanceof SpinnerModel) {
                jRedScrollbar.setValue((int) spinnerModel.getValue());
                setNewPanelColor();
            }
            SpinnerModel spinnerModel1 = jGreen.getModel();
            if (spinnerModel1 instanceof SpinnerModel) {
                jGreenScollbar.setValue((int) jGreen.getValue());
                setNewPanelColor();
            }
            SpinnerModel spinnerModel2 = jBlue.getModel();
            if (spinnerModel2 instanceof SpinnerModel) {
                jBlueScrollbar.setValue((int) jBlue.getValue());
                setNewPanelColor();
            }
        }
    
        public void setNewPanelColor() {
            int r = (int)((SpinnerModel)jRed.getModel()).getValue();
            int g = (int)((SpinnerModel)jGreen.getModel()).getValue();
            int b = (int)((SpinnerModel)jBlue.getModel()).getValue();
            colorPanel2.setColor(new Color(r, g, b));
        }
    }
    
    class ColorPanel2 extends JPanel {
    
        private JColorChooser colorchooser;
        private Color color = new Color(100, 200, 50);
    
        public ColorPanel2() {
            setLayout(new BorderLayout());
        }
    
        public void setColor(Color color) {
            this.color = color;
            repaint();
        }
    
        @Override
        public void paintComponent(Graphics graphics) {
            super.paintComponent(graphics);
    
            graphics.setColor(color);
            graphics.fillRect(100, 50, 300, 150);
        }
    }