I am subclassing both JFrame
and JPanel
objects to build a simple menu UI for a game. The menu is a PNG
image that will be rendered inside the JPanel’s paintComponent(Graphics)
method. I hooked a KeyListener
to the JFrame
in order to receive keyboard commands, and it is working (space bar exits the program). Although I am declaring a layout manager (BorderLayout
), as advised by other Stack Overflow posts, JPanel’s paintComponent()
is not called.
My code follows below:
public class MainScreen extends JFrame { public MainScreen() { super(); initialize(); } public final void initialize() { setLayout(new BorderLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); add(new Menu(this), BorderLayout.CENTER); setResizable(false); setLocationRelativeTo(null); } class Menu extends JPanel implements KeyListener { JFrame frame; Image imagem; public Menu(JFrame frame) { super(); this.frame = frame; initialize(); } public final void initialize() { frame.removeAll(); frame.setTitle("Menu principal"); frame.setSize(new Dimension(Comuns.LARGURA, Comuns.ALTURA)); frame.addKeyListener(this); ImageIcon icone = new ImageIcon("res\MenuScreen.png"); imagem = icone.getImage(); frame.setVisible(true); } @Override public void keyTyped(KeyEvent e) { // nada aqui } @Override public void keyPressed(KeyEvent e) { int c = e.getKeyCode(); switch (c) { case KeyEvent.VK_1: frame.removeKeyListener(this); new Fase_1(frame); break; ... case KeyEvent.VK_SPACE: frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING)); break; default: break; } } @Override public void keyReleased(KeyEvent e) { // nada aqui } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D gd = (Graphics2D) g; if (imagem != null) { gd.drawImage(imagem, 0, 0, frame); } } @Override public Dimension getPreferredSize() { return new Dimension(Comuns.LARGURA, Comuns.ALTURA); } } }
Answer
This question was answered in the comments by @STaefi so I’m making this answer a CW
In the public final void initialize()
of Menu class, remove the frame.removeAll();
and there you go.
A good practice is to call the JFrame#setVisible
after all the initialization, not int the initialization a child component.