So I have a JPanel object as a component of a JFrame, and I am periodically redrawing the contents of the JPanel with a Timer object. Everything is working fine except for the JPanel being redrawn over top of the JFrame’s menu when therefore making the menu items unreadable. Is there a way around this problem without having to pause the timer every time the user goes to access the menu?
Control Frame Class
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 Class
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);
}
}
The problem is the Animation Panel is drawing over top of the ControlFrames Menu
Don’t call
getGraphics()in Java code. A Java GUI must repaint when it is told to do so, and should do so using eitherpaint(Graphics)orpaintComponent(Graphics). That is why the menu was vanishing.The bug is solved in this version of
AnimationPanel.