当我运行代码时,我希望在JPanel
中看到JFrame
,但没有显示任何内容。我在框架中有一个按钮,它出现了。但JPanel
没有出现,我甚至用红色着色。
以下是我JPanel
的代码:
import java.awt.*;
import javax.swing.JPanel;
public class graphic extends JPanel {
private static final long serialVersionUID = -3458717449092499931L;
public Game game;
public graphic(Game game){
this.game = game;
this.setPreferredSize(new Dimension(400,400));
this.setBackground(Color.RED);
}
public void paintComponent(Graphics g){
for (Line l:game.mirrors){
g.setColor(Color.BLACK);
g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
}
}
}
我的JFrame代码:
import java.awt.Container;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.*;
public class Viewer implements ActionListener {
public JFrame frame;
public JButton drawShoot;
public boolean draw;
public Game game;
public graphic graphic;
public TimerTask timert;
public Timer timer;
public Viewer(){
draw = true;
game = new Game();
}
public static void main(String args[]){
Viewer v = new Viewer();
v.setup();
}
public void setup(){
frame = new JFrame("Laser Stimulator");
drawShoot = new JButton("Edit Mode");
graphic = new graphic(game);
graphic.repaint();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(300, 300, 600, 600);
Container contentPane = frame.getContentPane();
SpringLayout layout = new SpringLayout();
contentPane.setLayout(layout);
drawShoot.addActionListener(this);
timert = new TimerTask() {
@Override
public void run() {
}
};
timer =new Timer();
timer.scheduleAtFixedRate(timert, 0, 1000/30);
contentPane.add(graphic);
layout.putConstraint(SpringLayout.NORTH, graphic, 0, SpringLayout.NORTH, contentPane);
layout.putConstraint(SpringLayout.WEST, graphic, 0, SpringLayout.WEST, contentPane);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==drawShoot){
draw = !draw;
drawShoot.setText((draw)?"Edit Mode":"Shoot Mode");
}
}
}
答案 0 :(得分:5)
所以基本的问题是你没有兑现油漆链。在覆盖绘制方法时必须调用super.paintXxx
...
此方法必须调用super.paintComponent(g)
,因为它负责清除背景;)
public void paintComponent(Graphics g) {
for (Line l : game.mirrors) {
g.setColor(Color.BLACK);
g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
}
}
public class QuickTestPaintPane {
public static void main(String[] args) {
new QuickTestPaintPane();
}
public QuickTestPaintPane() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
Viewer v = new Viewer();
v.setup();
}
});
}
public class Viewer implements ActionListener {
public JFrame frame;
public JButton drawShoot;
public boolean draw;
// public Game game;
public graphic graphic;
public TimerTask timert;
public Timer timer;
public Viewer() {
draw = true;
// game = new Game();
}
public void setup() {
frame = new JFrame("Laser Stimulator");
drawShoot = new JButton("Edit Mode");
graphic = new graphic();
// graphic.repaint();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(300, 300, 600, 600);
// Container contentPane = frame.getContentPane();
SpringLayout layout = new SpringLayout();
frame.setLayout(layout);
drawShoot.addActionListener(this);
timert = new TimerTask() {
@Override
public void run() {
}
};
timer = new Timer();
timer.scheduleAtFixedRate(timert, 0, 1000 / 30);
frame.add(graphic);
layout.putConstraint(SpringLayout.NORTH, graphic, 0, SpringLayout.NORTH, frame.getContentPane());
layout.putConstraint(SpringLayout.WEST, graphic, 0, SpringLayout.WEST, frame.getContentPane());
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == drawShoot) {
draw = !draw;
drawShoot.setText((draw) ? "Edit Mode" : "Shoot Mode");
}
}
}
public class graphic extends JPanel {
private static final long serialVersionUID = -3458717449092499931L;
// public Game game;
// public graphic(Game game) {
public graphic() {
// this.game = game;
this.setPreferredSize(new Dimension(400, 400));
this.setBackground(Color.RED);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.drawLine(0, 0, getWidth(), getHeight());
// for (Line l : game.mirrors) {
// g.setColor(Color.BLACK);
// g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
// }
}
}
}
答案 1 :(得分:4)
@MadProgrammer已经回答了这个问题(给他+1)。在大多数覆盖方法中,有人要求他们的 super 不要忘记尊重这个,否则这些小小的打嗝就会浮出水面。
另一方面说明:
请勿在{{1}}上致电setBounds(..)
(我无法理解您的需要),而是在设置JFrame
可见之前致电JFrame#pack()
。
从Java 6开始,无需执行JFrame
。只需使用:
frame.getContentPane()
或frame.add()
。
作为一种契约
frame.setLayout(..)
及其变体,add
和remove
已经存在 根据需要覆盖转发到 contentPane 。
你也有:
setLayout
我无法理解为什么在第一次看到组件时会调用graphic = new graphic(game);
graphic.repaint();
来调用repaint()
相反覆盖repaint()
getPreferredSize
而不是调用JPanel
除非通过其他类访问,否则不要在类中实现setPreferredSize()
。而是像这样使用匿名ActionListener
:
Listener