Problema de repintado de JPanel

Tengo un JFrame que contiene 2 subclase JPanel y 2 JLabel en BorderLayout. Uno de los JPanel contiene JButtons y el otro se usa para mostrar gráficos. Los JLabels están en el norte y el sur, el botón JPanel en el oeste y la pantalla JPanel en el centro.

La pantalla JPanel requiere actualización constante, por lo que invoco su método de repintado () a través del evento de acción generado por el temporizador de swing. También anulo su método paintComponent () para hacer mis dibujos.

En lugar de mostrar lo que he dibujado, el “contenido del JFrame” se dibuja en la pantalla JPanel. Soy consciente de que puedo simplemente “borrar” la pantalla JPanel usando g.fillRect () o super.paintComponent () antes de hacer mis dibujos.

Solo tengo curiosidad por qué sucede esto.

estoy usando jdk 1.6u27. a continuación está mi código:

package test; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class Main { public static void main(String[] args) { Simulation sim = new Simulation(); } } class Simulation extends JFrame { public JLabel state; private JLabel id; private ButtonPanel control; private Display display; public Simulation() { id = new JLabel("Test"); state = new JLabel("Test"); 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); this.setSize(500, 600); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public ButtonPanel getControl() { return this.control; } } class ButtonPanel extends JPanel implements ActionListener { public JButton b[] = new JButton[8]; public boolean bp[] = new boolean[8]; public ButtonPanel() { this.setLayout(new GridLayout(8, 1)); for (int i = 0; i < b.length; i++) { b[i] = new JButton(""+i); b[i].addActionListener(this); bp[i] = false; this.add(b[i]); } } public void actionPerformed(ActionEvent e) { //do something } } class Display extends JPanel implements ActionListener { private Timer tm; private int yco; private Simulation sim; public Display(Simulation sim) { tm = new Timer(100, this); tm.start(); yco = 0; this.sim = sim; } @Override public void paintComponent(Graphics g) { //draw something g.drawLine(0, yco, 100, 100); } public void actionPerformed(ActionEvent e) { yco ++; this.repaint(); } } 

captura de pantalla

Sin super.paintComponent(g) , el resultado depende del valor predeterminado de su plataforma para la propiedad de opacidad del delegado de IU de PanelUI , PanelUI . El mío es true , pero puedes experimentar en tu plataforma, como se sugiere a continuación.

Adición: “Si no paintComponent() la propiedad opaca, es probable que veas artefactos visuales” – paintComponent() . El artefacto que observe variará según la plataforma, pero no es atípico. En efecto, estás rompiendo la promesa de dibujar cada píxel, y ves lo que queda en algún buffer.

Principal

 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 list = new ArrayList(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); } }