JMenuBar显示在JFrame和JPanel中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JMenuBar显示在JFrame和JPanel中相关的知识,希望对你有一定的参考价值。

我有一个奇怪的事情,JMenuBar出现在我的JFrame和JPanel中。我不知道这是怎么回事。我不确定它是否因为菜单栏和JPanel属于不同的类或者可能来自观察者模式。

What it looks like when I run it.

enter image description here

JFrame代码

package model;

import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class TetrisGUI extends JFrame implements Observer {

/**
 * 
 */
private static final long serialVersionUID = -2900288878430508454L;

private final Board myBoard;

private final TetrisMenu myMenu;

private final TetrisBoardPanel myGamePanel;

public TetrisGUI()  {
    super("Tetris");
    myBoard = new Board();
    myMenu = new TetrisMenu();
    myGamePanel = new TetrisBoardPanel();
    this.setJMenuBar(myMenu.getMenuBar());
}

public void start() {
    add(myGamePanel.getGamePanel());
    this.pack();
    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(false);
    this.pack();
}

public JMenuBar createMenu()    {
    JMenuBar menubar = new JMenuBar();
    menubar.add(new JMenu("Game"));
    return menubar;
}

@Override
public void update(Observable o, Object arg) {
    // TODO Auto-generated method stub

}

JPanel代码

 package model;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JPanel;
import javax.swing.Timer;

public class TetrisBoardPanel extends JPanel implements Observer {

/**
 * auto generated SID.
 */
private static final long serialVersionUID = 5916557959811294203L;

private final Board myBoard;

private Block[][] myBlocks;

private final Timer myTimer;

private Color myBlockColor;

public TetrisBoardPanel()   {
    myBoard = new Board();
    myBoard.addObserver(this);
    this.setPreferredSize(new Dimension(300,658));
    System.out.println(myBlocks);
    myTimer = new Timer(1000, timeAction());
    myBoard.newGame();
    myTimer.start();

}

@Override
protected void paintComponent(Graphics g)  {
    if (myBlocks == null) {
        for (int j = 3; j < 280; j+=30) {
            for (int i = 28; i < 600; i+=30)    {
                g.fillRect(j, i, 30, 30);
            }
        }
    } else  {
        int x = 3;
        int y = 28;
        for (int i = 20; i > -1; i--)   {
            for (int j=0; j<myBlocks[i].length; j++)   {
                if (myBlocks[i][j] == null)  {
                    g.setColor(Color.BLACK);
                    g.fillRect(x, y, 30, 30);

                } else  {
                    if (myBlocks[i][j].equals(Block.I))   {
                        myBlockColor = Color.ORANGE;
                    } else if (myBlocks[i][j].equals(Block.J))   {
                        myBlockColor = Color.CYAN;
                    } else if (myBlocks[i][j].equals(Block.L)) {
                        myBlockColor = Color.RED;
                    } else if (myBlocks[i][j].equals(Block.O))   {
                        myBlockColor = Color.PINK;
                    } else if (myBlocks[i][j].equals(Block.S))   {
                        myBlockColor = Color.MAGENTA;
                    } else if (myBlocks[i][j].equals(Block.T))   {
                        myBlockColor = Color.GREEN;
                    } else if (myBlocks[i][j].equals(Block.Z))   {
                        myBlockColor = Color.LIGHT_GRAY;
                    }
                    g.setColor(myBlockColor);
                    g.fillRect(x, y, 30, 30);
                    g.setColor(Color.white);
                    g.fillRect(x+7,y+7,17,17);

                }
                x += 30;

            }
            x = 3;
            y += 30;
        }

    }

    repaint();

}

public ActionListener timeAction()   {
    ActionListener task = new ActionListener()  {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            myBoard.step();   
        }

    };
    return task;
}

@Override
public void update(Observable theOb, Object theArg) {
    if (theArg instanceof Block[][])    {
        myBlocks = (Block[][]) theArg;
        System.out.println(((Block[][]) theArg).length);
        for (final Block[] row : (Block[][])theArg)   {
            for (final Block b : row)   {
                if (b == null)  {
                    System.out.print("[ ]");
                } else  {
                    System.out.print("[" + b +"]"); 
                }

            }
            System.out.println();
    } 

}

}

public JPanel getGamePanel()    {
    JPanel pan = new JPanel();
    pan.add(this);
    return pan;
}

菜单条形码

 package model;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class TetrisMenu {

 private final JMenuBar myMenuBar;
 private final JMenu myGameMenu;
 private final JMenuItem myNewGame;
 private final JMenuItem myEndGame;
 private final JMenuItem myExit;

 public TetrisMenu()    {
     myMenuBar = new JMenuBar();
     myGameMenu = new JMenu("Game");
     myNewGame = new JMenuItem("New Game");
     myEndGame = new JMenuItem("End Game");
     myExit = new JMenuItem("Exit");
     createMenu();
 }

 private void createMenu() {
     myMenuBar.add(myGameMenu);
     myGameMenu.add(myNewGame);
     myGameMenu.add(myEndGame);
     myGameMenu.addSeparator();
     myGameMenu.add(myExit);
 }

 public JMenuBar getMenuBar()   {
     return myMenuBar;
 }

 public JMenuItem getNewGame() {
     return myNewGame;
 }

 public JMenuItem getEndGame()  {
     return myEndGame;
 }

 /**
  * 
 * @return
 */
public JMenuItem getExit() {
     return myExit;
 }
答案

你的JPanel的paintComponent方法不会调用super的相同方法,因此该方法会破坏绘画链,而JPanel无法进行内务绘画,包括删除脏像素。不要这样做。在你的覆盖中调用super的方法。

@Override
protected void paintComponent(Graphics g)  {
    super.paintComponent(g);
    // .....

以上是关于JMenuBar显示在JFrame和JPanel中的主要内容,如果未能解决你的问题,请参考以下文章

无法将 JMenuBar 添加到扩展的 JFrame

java中jframe 和jpanel的区别

JPanel 未显示在 JFrame 中,但 JFrame 仍会更改大小

图像未显示在 jPanel 中

JPanel 更改未在 Jframe 上显示

如果在 JFrame 代码中调用 repaint(),JPanel 不会重新绘制