我有一个JFrame,在BorderLayout中包含2个JPanel子类和2个JLabel。其中一个JPanel包含JButtons,另一个用于显示图形。 JLabels位于北部和南部,西部是JPanel按钮,中间是JPanel。
显示JPanel需要不断刷新,所以我通过swing计时器生成的动作事件调用它的repaint()方法。我也覆盖它的paintComponent()方法来做我的绘图。
不是显示我绘制的内容,而是将“JFrame的内容”绘制到显示JPanel上。我知道在完成绘图之前,我可以通过使用g.fillRect()或super.paintComponent()简单地“清除”显示JPanel。
我只是好奇为什么会这样。
我正在使用jdk 1.6u27。下面是我的代码:
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();
}
}
答案 0 :(得分:9)
如果没有super.paintComponent(g)
,则结果取决于您的平台JPanel
UI委托PanelUI
属性的默认值true
。我的情况恰好是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);
}
}
,但你可以在你的平台上进行试验,如下所示。
附录:“如果你不尊重opacity,你可能会看到视觉opaque property。” - artifacts。您观察到的paintComponent()
会因平台而异,但并非典型。实际上,你违背了绘制每个像素的承诺,你会看到在某个缓冲区中遗留下来的东西。
{{1}}