Search code examples
javaswingjpaneljslider

JPanel with JSlider not displaing the Graphics


All i have is a JPanel with a white background and the JSlider on the bottom, not displaying the square, i think i have made some mistake with the JPanel class but i can't figure it out. Just before i made another project with g.fillOval and it worked properly, i checked it out and every line of code seems the same, i am really confused.

public class Main00 {

    public static void main(String[] args) {
        Gui asd=new Gui();
        asd.setVisible(true);
        asd.setSize(500,400);
    }
}  

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class Gui extends JFrame {

    private JSlider slider;
    private DrawSquare square;

    public Gui() {
        super("square modificator");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        square = new DrawSquare();
        square.setBackground(Color.WHITE);
        slider = new JSlider(SwingConstants.HORIZONTAL, 0, 300,
                    square.getSide());
        slider.setMajorTickSpacing(20);
        slider.setPaintTicks(true);
        add(square);
        add(slider, BorderLayout.SOUTH);
        slider.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                square.setSide(slider.getValue());
            }
        });
    }
}

import java.awt.*;
import javax.swing.*;

public class DrawSquare extends JPanel {

    private int side = 10;

    public void paintComponents(Graphics g) {
        super.paintComponents(g);
        g.setColor(Color.RED);
        g.fillRect(20, 20, side, side);
    }

    public void setSide(int side) {
        this.side=(side>=0)?side:0;
        repaint();
    }

    public Dimension getPrefferedSize(){
        return new Dimension(200,200);
    }

    public Dimension getMinimumSize(){
        return getPrefferedSize();
    }

    public int getSide(){
        return side;
    }
}

Solution

  • You're overriding paintComponents rather than the correct paintComponent. These two methods have drastically different effects, and the effect of the second is the one you want.

    From the API:

    • paintComponents API entry: Paints each of the components in this container.
    • paintComponent API entry: Calls the UI delegate's paint method, if the UI delegate is non-null. We pass the delegate a copy of the Graphics object to protect the rest of the paint code from irrevocable changes

    Again, you are interested in painting the component itself via its delegate and not in painting the components held by this component.