简体   繁体   English

JMenuBar同时显示在JFrame和JPanel中

[英]JMenuBar showing in both the JFrame and JPanel

I'm having this weird thing where a JMenuBar shows up in both my JFrame and JPanel. 我有一个奇怪的事情,在我的JFrame和JPanel中都出现了一个JMenuBar。 I have no idea how this is happening. 我不知道这是怎么回事。 I'm not really sure if its because the menu bar and the JPanel are in different classes or could be from the observer pattern. 我不太确定是否是因为菜单栏和JPanel位于不同的类中,或者可能来自观察者模式。

What it looks like when I run it. 我运行它时的外观。

在此处输入图片说明

JFrame code 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 code 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;
}

Menu bar code 菜单条码

 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;
 }

Your JPanel's paintComponent method does not call the super's same method, and so the method breaks the painting chain and the JPanel cannot do house-keeping painting, including removal of dirty pixels. 您的JPanel的paintComponent方法不会调用super的相同方法,因此该方法会中断绘画链,并且JPanel无法进行内部管理绘画,包括删除脏像素。 Don't do this. 不要这样 Call the super's method in your override. 在您的替代中调用超级方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM