JPanel repaint issue

Without super.paintComponent(g), the result depends on your platform’s default for the opacity property of the JPanel UI delegate, PanelUI. Mine happens to be true, but you can experiment on your platform, as suggested below.

Addendum: “If you do not honor the opaque property you will likely see visual artifacts.”—paintComponent(). The artifact you observe will vary by platform, but it is not atypical. In effect, you are breaking the promise to draw every pixel, and you see whatever is left over in some buffer.

Main

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

public class Main {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                Simulation sim = new Simulation();
            }
        });
    }
}

class Simulation extends JFrame {

    public JCheckBox state;
    private JLabel id;
    private ButtonPanel control;
    private Display display;

    public Simulation() {
        id = new JLabel("Test");
        state = new JCheckBox("Opaque");
        control = new ButtonPanel();
        display = new Display(this);

        this.setLayout(new BorderLayout());
        this.add(id, BorderLayout.NORTH);
        this.add(control, BorderLayout.WEST);
        this.add(display, BorderLayout.CENTER);
        this.add(state, BorderLayout.SOUTH);
        state.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                display.setOpaque(e.getStateChange() == ItemEvent.SELECTED);
            }
        });
        state.setSelected(true);

        this.pack();
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public ButtonPanel getControl() {
        return this.control;
    }
}

class ButtonPanel extends JPanel {

    private static final int N = 8;
    private List<JToggleButton> list = new ArrayList<JToggleButton>(N);

    public ButtonPanel() {
        this.setLayout(new GridLayout(0, 1));
        for (int i = 0; i < N; i++) {
            final JToggleButton b = new JToggleButton(String.valueOf(i));
            b.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    //System.out.println(b.isSelected());
                }
            });
            list.add(b);
            this.add(b);
        }
    }
}

class Display extends JPanel {

    private Simulation sim;
    private Timer tm;
    private int yco;

    public Display(Simulation sim) {
        this.setPreferredSize(new Dimension(320, 320));
        this.setOpaque(true);
        this.sim = sim;
        tm = new Timer(100, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                yco++;
                repaint();
            }
        });
        tm.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        //super.paintComponent(g);
        g.drawLine(0, yco, getWidth() / 2, getHeight() / 2);
    }
}

Leave a Comment