Search code examples
javaswinggraphicsjframejcomponent

Add buttons that change color of drawing


The drawing is basically a two-leaf window with sky and sun as if you're looking out that window. I need to add buttons Day and Night. By clicking each button the color of sky changes to dark blue and light blue, the color of the sun changes to color of the moon correspondingly. I have added the buttons and they appear but I can't seem to wrap my head around the way where I should place my actionListener and how to get access to my g2 variable in order to change those colors.

public class DrawingOne extends JFrame{
    public DrawingOne() {
        Container container = getContentPane();
        container.setBackground(new Color(224, 196, 214));
        container.setLayout(new BorderLayout(20, 20));
        JButton j1 = new JButton("Day");
        JButton j2 = new JButton("Night");
        container.add(j1, BorderLayout.SOUTH);
        container.add(j2, BorderLayout.NORTH);
        setSize(DEFAULT_WITDH, DEFAULT_HEIGHT);
        DrawComponent c = new DrawComponent();
        add(c);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static final int DEFAULT_WITDH = 700;
    public static final int DEFAULT_HEIGHT = 500;
}
class DrawComponent extends JComponent {

    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        //the base for window
        Rectangle2D.Double rectangle2Drect2 = new Rectangle2D.Double(37, 26, 458, 280);
        g2.setStroke(new BasicStroke(3));
        g2.setColor(Color.black);
        g2.draw(rectangle2Drect2);
        g2.setColor(Color.white);
        g2.fill(rectangle2Drect2);

        //left half-window
        rectangle2Drect2 = new Rectangle2D.Double(51, 40, 160, 250);
        g2.setStroke(new BasicStroke(3));
        g2.setColor(Color.black);
        g2.draw(rectangle2Drect2);
        g2.setColor(new Color(135, 206, 235));
        g2.fill(rectangle2Drect2);

        //right half-window
        rectangle2Drect2 = new Rectangle2D.Double(230, 40, 250, 250);
        g2.setStroke(new BasicStroke(3));
        g2.setColor(Color.black);
        g2.draw(rectangle2Drect2);
        g2.setColor(new Color(135, 206, 235));
        g2.fill(rectangle2Drect2);


        //основа ручки
        rectangle2Drect2 = new Rectangle2D.Double(215, 140, 10, 10);
        g2.setStroke(new BasicStroke(2));
        g2.setColor(Color.black);
        g2.draw(rectangle2Drect2);
        g2.setColor(Color.white);
        g2.fill(rectangle2Drect2);

        //ручка
        rectangle2Drect2 = new Rectangle2D.Double(217, 142, 4, 30);
        g2.setStroke(new BasicStroke(2));
        g2.setColor(Color.black);
        g2.draw(rectangle2Drect2);
        g2.setColor(Color.white);
        g2.fill(rectangle2Drect2);

        //the sun
        g2.setColor(Color.getHSBColor(197.4F, 42.6F, 92.2F));
        g2.fillOval(100, 60, 80, 80);

        //горшок
        int[] xpoints = {230 + 60, 300 + 60, 285 + 61, 244 + 60};
        int[] ypoints = {240, 240, 290, 290};
        int npoints = 4;
        g2.setColor(new Color(172, 86, 30));
        g2.fillPolygon(xpoints, ypoints, npoints);

        //ствол цветка
        g2.setStroke(new BasicStroke(5));
        g2.setColor(new Color(0, 128, 0));
        g2.drawLine(325, 200, 325, 238);

        //лепестки
        g2.setColor(new Color(255, 192, 203));

        g2.fillOval(317, 200, 22, 22);
        g2.fillOval(317, 175, 22, 22);
        g2.fillOval(317 - 15, 190, 22, 22);
        g2.fillOval(317 + 13, 190, 22, 22);
        //  g2.fillOval(317,190,22,22);

        //центр цветка
        g2.setColor(new Color(255, 165, 0));
        g2.fillOval(317, 190, 15, 15);
    }
    public static void main(String[] args) {
        DrawingOne frame = new DrawingOne();
    }
}

Solution

  • I made a night sky from your GUI.

    Night Sky GUI

    I had to make quite a few changes to your code to get this to work.

    1. I had to make the JComponent class an inner class, so it could reference DrawingOne class variables.

    2. I had to move the main method in the DrawingOne class, so I could start the application.

    3. I started the Java application with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.

    4. I rearranged the order of your statements in the DrawingOne constructor, so they made more sense. I made the drawing panel your preferred size, rather than the JFrame. The size of the drawing panel is what's important, not the JFrame size.

    5. I made the sky and sun colors DrawingOne class variables, so they could be changed. I wrote a couple of methods to change the colors.

    6. I wrote an ActionListener class that changes the colors depending on which button you left-click.

    Here's the complete runnable code.

    import java.awt.BasicStroke;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.geom.Rectangle2D;
    
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import javax.swing.WindowConstants;
    
    public class DrawingOne extends JFrame {
    
        private static final long serialVersionUID = 1L;
    
        public static final int DEFAULT_WIDTH = 700;
        public static final int DEFAULT_HEIGHT = 500;
    
        public Color sunColor;
        public Color skyColor;
        
        public DrawComponent c;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new DrawingOne();
                }
            });
        }
    
        public DrawingOne() {
            setDaySky();
    
            Container container = getContentPane();
            container.setBackground(new Color(224, 196, 214));
            container.setLayout(new BorderLayout(20, 20));
            container.setPreferredSize(
                    new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
            
            ButtonListener listener = new ButtonListener();
    
            JButton j1 = new JButton("Day");
            j1.addActionListener(listener);
            JButton j2 = new JButton("Night");
            j2.addActionListener(listener);
            container.add(j1, BorderLayout.SOUTH);
            container.add(j2, BorderLayout.NORTH);
    
            c = new DrawComponent();
            container.add(c, BorderLayout.CENTER);
    
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            pack();
            setVisible(true);
        }
    
        public void setNightSky() {
            this.sunColor = Color.getHSBColor(197.4F, 42.6F, 92.2F);
            this.skyColor = new Color(7, 78, 107);
        }
    
        public void setDaySky() {
            this.sunColor = Color.getHSBColor(197.4F, 42.6F, 92.2F);
            this.skyColor = new Color(135, 206, 235);
        }
    
        public class DrawComponent extends JComponent {
    
            private static final long serialVersionUID = 1L;
    
            @Override
            public void paint(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
                // the base for window
                Rectangle2D.Double rectangle2Drect2 = 
                        new Rectangle2D.Double(37, 26, 458, 280);
                g2.setStroke(new BasicStroke(3));
                g2.setColor(Color.black);
                g2.draw(rectangle2Drect2);
                g2.setColor(Color.white);
                g2.fill(rectangle2Drect2);
    
                // left half-window
                rectangle2Drect2 = 
                        new Rectangle2D.Double(51, 40, 160, 250);
                g2.setStroke(new BasicStroke(3));
                g2.setColor(Color.black);
                g2.draw(rectangle2Drect2);
                g2.setColor(skyColor);
                g2.fill(rectangle2Drect2);
    
                // right half-window
                rectangle2Drect2 = 
                        new Rectangle2D.Double(230, 40, 250, 250);
                g2.setStroke(new BasicStroke(3));
                g2.setColor(Color.black);
                g2.draw(rectangle2Drect2);
                g2.setColor(skyColor);
                g2.fill(rectangle2Drect2);
    
                // основа ручки
                rectangle2Drect2 = 
                        new Rectangle2D.Double(215, 140, 10, 10);
                g2.setStroke(new BasicStroke(2));
                g2.setColor(Color.black);
                g2.draw(rectangle2Drect2);
                g2.setColor(Color.white);
                g2.fill(rectangle2Drect2);
    
                // ручка
                rectangle2Drect2 = 
                        new Rectangle2D.Double(217, 142, 4, 30);
                g2.setStroke(new BasicStroke(2));
                g2.setColor(Color.black);
                g2.draw(rectangle2Drect2);
                g2.setColor(Color.white);
                g2.fill(rectangle2Drect2);
    
                // the sun
                g2.setColor(sunColor);
                g2.fillOval(100, 60, 80, 80);
    
                // горшок
                int[] xpoints = { 230 + 60, 300 + 60, 285 + 61, 244 + 60 };
                int[] ypoints = { 240, 240, 290, 290 };
                int npoints = 4;
                g2.setColor(new Color(172, 86, 30));
                g2.fillPolygon(xpoints, ypoints, npoints);
    
                // ствол цветка
                g2.setStroke(new BasicStroke(5));
                g2.setColor(new Color(0, 128, 0));
                g2.drawLine(325, 200, 325, 238);
    
                // лепестки
                g2.setColor(new Color(255, 192, 203));
    
                g2.fillOval(317, 200, 22, 22);
                g2.fillOval(317, 175, 22, 22);
                g2.fillOval(317 - 15, 190, 22, 22);
                g2.fillOval(317 + 13, 190, 22, 22);
                // g2.fillOval(317,190,22,22);
    
                // центр цветка
                g2.setColor(new Color(255, 165, 0));
                g2.fillOval(317, 190, 15, 15);
            }
    
        }
    
        public class ButtonListener implements ActionListener {
    
            @Override
            public void actionPerformed(ActionEvent event) {
                JButton button = (JButton) event.getSource();
                if (button.getText().equals("Night")) {
                    setNightSky();
                } else {
                    setDaySky();
                }
                c.repaint();
            }
    
        }
    
    }