在 JFrame 和 JPanel 中显示的 JMenuBar
JMenuBar showing in both the JFrame and JPanel
我遇到了一件奇怪的事情,JMenuBar 同时出现在我的 JFrame 和 JPanel 中。我不知道这是怎么回事。我不太确定是因为菜单栏和 JPanel 不同 类 还是来自观察者模式。
What it looks like when I run it.
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
}
J面板代码
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 无法进行 house-keeping 绘画,包括去除脏像素。不要这样做。在您的覆盖中调用 super 的方法。
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// .....
我遇到了一件奇怪的事情,JMenuBar 同时出现在我的 JFrame 和 JPanel 中。我不知道这是怎么回事。我不太确定是因为菜单栏和 JPanel 不同 类 还是来自观察者模式。
What it looks like when I run it.
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
}
J面板代码
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 无法进行 house-keeping 绘画,包括去除脏像素。不要这样做。在您的覆盖中调用 super 的方法。
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// .....