2012-02-04 37 views
3

因此,我有一个JPanel对象作为JFrame的组件,并且我定期用Timer对象重新绘制JPanel的内容。除了在JFrame菜单顶部重绘JPanel时,一切都工作正常,因此导致菜单项无法读取。有没有办法解决这个问题,而不必每次用户访问菜单时都暂停计时器?Janel内的JFrame在JFrame的菜单顶部绘制

控制框架类

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菜单

+1

解决方案是修复您的代码中的错误。如果您需要我们的帮助,您需要显示该代码,或者其中的一部分。要发布的最佳代码是创建一个[SSCCE](http://sscce.org),它是一个最小的可编译和可运行程序,可以显示您的问题,并且没有与手头问题无关的代码。我不太清楚你如何在没有这些重要信息的情况下猜测错误,但也许是因为你是新来的。顺便提一下,欢迎使用stackoverflow。 – 2012-02-04 04:30:32

+1

添加了代码。 – pmurph 2012-02-04 04:53:06

+0

发布代码的好处。 +1 – 2012-02-04 05:05:53

回答

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); 
    } 
} 
+0

打败我吧! 1+ – 2012-02-04 05:04:53

+0

修复了这个问题,感谢帮助 – pmurph 2012-02-04 05:12:07

4

您的代码的一个问题是您绘制的所有错误。几乎从不使用组件的getGraphics来获取其Graphics对象,因为如果有任何重绘,此对象将不会保留。相反,绘图应该在您的JPanel的paintComponent方法中被动地执行。

编辑:安德鲁在他的更快的帖子显示! 1+给他!

但是,如果您从本练习中得到任何东西,那就需要通过Java Swing图形教程来学习如何绘制Swing,因为您需要抛出一些错误的假设,即您(以及所有我们)已经开始做这种编码了。

+0

对本教程的建议+1,但主要是为了提示'邮政编码'。 :) – 2012-02-04 05:08:28