所以我有一个JPanel对象作为JFrame的一个组件,我定期用Timer对象重绘JPanel的内容。一切正常,除了在JFrame菜单顶部重绘JPanel,因此菜单项不可读。有没有办法解决这个问题,而不必在每次用户访问菜单时暂停计时器?
控制框架类
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ControlFrame extends JFrame implements ActionListener{
/*======Public Constants======*/
public static int DEFAULT_HEIGHT = 400;
public static int DEFAULT_WIDTH = 400;
/*======Private Instance Variables======*/
private AnimationPanel animPane;
private JMenu menu;
private JMenuItem menuExit;
private JMenuBar menuBar;
/*======Constructors======*/
public ControlFrame(){
initialize();
}
/*======Public Instance Methods======*/
public void actionPerformed(ActionEvent ae) {
if(ae.getActionCommand().equals("exit")){
System.exit(0);
}
}
/*======Private Instance Methods======*/
private void initialize(){
this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new GridLayout(0,2));
this.animPane = new AnimationPanel(this.getWidth(), this.getHeight());
this.add(animPane);
createCFMenu();
this.setVisible(true);
}
private void createCFMenu(){
this.menuBar = new JMenuBar();
this.menu = new JMenu("File");
this.menu.setMnemonic(KeyEvent.VK_F);
this.menuBar.add(this.menu);
this.menuExit = new JMenuItem("Exit", KeyEvent.VK_X);
this.menuExit.addActionListener(this);
this.menuExit.setActionCommand("exit");
this.menu.add(menuExit);
this.setJMenuBar(this.menuBar);
}
/*======Main Method======*/
public static void main(String[] args){
ControlFrame cf = new ControlFrame();
}
}
AnimationPanel类
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
public class AnimationPanel extends JPanel implements ActionListener{
/*======Private Instance Variables======*/
private int timeInterval;
private Timer animTimer;
/*======Constructor======*/
public AnimationPanel(int width, int height){
timeInterval = 50;
this.setSize(width, height);
this.animTimer = new Timer(timeInterval, this);
animTimer.start();
}
public void actionPerformed(ActionEvent arg0) {
paint();
}
/*======Private Instance Variables======*/
private void paint(){
BufferedImage bImage = new BufferedImage(this.getWidth(),
this.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics bg = bImage.getGraphics();
bg.setColor(Color.WHITE);
bg.fillRect(0, 0, bImage.getWidth(), bImage.getHeight());
this.getGraphics().drawImage(bImage, 0, 0, this);
}
}
问题是动画面板正在绘制ControlFrames菜单的顶部
答案 0 :(得分:4)
不要在Java代码中调用getGraphics()
。 Java GUI必须在被告知这样做时重新绘制,并且应该使用paint(Graphics)
或paintComponent(Graphics)
进行重新绘制。这就是菜单消失的原因。
此版本的AnimationPanel
已解决该错误。
class AnimationPanel extends JPanel implements ActionListener{
/*======Private Instance Variables======*/
private int timeInterval;
private Timer animTimer;
/*======Constructor======*/
public AnimationPanel(int width, int height){
timeInterval = 50;
this.setSize(width, height);
this.animTimer = new Timer(timeInterval, this);
animTimer.start();
}
public void actionPerformed(ActionEvent arg0) {
repaint();
}
/*======Private Instance Variables======*/
public void paintComponent(Graphics g){
// important to get the component to paint itself & borders etc.
super.paintComponent(g);
BufferedImage bImage = new BufferedImage(this.getWidth(),
this.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics bg = bImage.getGraphics();
bg.setColor(Color.WHITE);
bg.fillRect(0, 0, bImage.getWidth(), bImage.getHeight());
bg.dispose(); // Assist the garbage collector!
g.drawImage(bImage, 0, 0, this);
}
}
答案 1 :(得分:4)
您的代码存在的一个问题是您的错误。你几乎从不使用组件的getGraphics来获取它的Graphics对象,因为如果有任何重绘,这个对象将不会持久存在。相反,应该在JPanel的paintComponent方法中被动地执行绘制。
编辑:正如安德鲁在他更快的帖子中所展示的那样! 1+给他!
但是如果你从这个练习中得到任何东西,那就是你需要通过Java Swing图形教程来学习如何在Swing中绘制,因为你需要抛弃一些错误的假设(你和我们所有人) )在开始做这种编码时有。