?? minepanel.java
字號:
/*
* MinePanel.java 1.0 2003-6-15
*
* Copyleft (c) 2003 RatKing.
*/
package jmine;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.*;
/**
* 總面板,包括上側的笑臉按鈕面板和下側的雷區面板
*/
public class MinePanel extends JPanel implements MouseListener {
private JMine jmine;
public static final int ONE_SECOND = 1000; // 1秒 = 1000毫秒
public static final int LOW_LEVEL = 0; // 初級
public static final int MIDDLE_LEVEL = 1; // 中級
public static final int HIGH_LEVEL = 2; // 高級
public static final int CUSTOM_LEVEL = 3; // 自定義...
public static final int READY = 0; // 準備就緒
public static final int PLAY = 1; // 開始游戲
public static final int PAUSE = 2; // 暫停游戲
public static final int WIN = 3; // 勝利結束
public static final int LOSE = 4; // 失敗結束
private int gameLevel = LOW_LEVEL; // 難度級別
private int mineRows = 0; // 雷區高度
private int mineColumns = 0; // 雷區寬度
private int totalMines = 0; // 地雷總數
public boolean isMark = true; // 標記
public boolean isColor = true; // 顏色
public boolean isSound = true; // 聲音
private int state = READY; // 系統運行狀態
/**
* 是否鼠標中鍵按下
* 當鼠標中鍵按下,或鼠標左右鍵同時按下時,為true
* 當釋放了鼠標中鍵,或鼠標左右鍵同時按下后釋放任意一個,則為false
*/
private boolean isMiddlePressed = false;
/** 開始按鈕面板 */
JPanel startPanel = new JPanel();
/** 雷區面板 */
JPanel mineField = new JPanel();
GridLayout gridLayout = new GridLayout();
Border raisedbevel = BorderFactory.createRaisedBevelBorder();
Border loweredbevel = BorderFactory.createLoweredBevelBorder();
Border margin1 = new EmptyBorder(6,6,6,6);
Border margin2 = new EmptyBorder(4,6,4,6);
BorderLayout borderLayout = new BorderLayout();
public FaceButton faceButton; // 笑臉按鈕
public MineButton[][] mineButton; // 雷區按鈕
public Counter remainMines; // 剩余地雷數
public Counter totalTime; // 所用時間(秒數)
public Timer timer; // 計時器
public MinePanel(JMine jmine) {
this(jmine, LOW_LEVEL);
}
public MinePanel(JMine jmine, int gameLevel) {
this.jmine = jmine;
init();
setGameLevel(gameLevel);
}
/** 面板初始化,組裝面板,制定布局與邊框 */
public void init() {
// 設置面板的邊框
this.setBorder(new CompoundBorder(raisedbevel, margin1));
startPanel.setBorder(new CompoundBorder(loweredbevel, margin2));
mineField.setBorder(loweredbevel);
// 設置面板的布局
borderLayout.setVgap(6); // 設置總面板中開始面板與地雷面板之間的間距
this.setLayout(borderLayout);
mineField.setLayout(gridLayout);
startPanel.setLayout(new BoxLayout(startPanel, BoxLayout.X_AXIS));
// 組裝開始按鈕
faceButton = new FaceButton(jmine);
remainMines = new Counter(jmine, totalMines);
totalTime = new Counter(jmine, 0);
totalTime.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
// 若按下中鍵,或同時按下鼠標左鍵和右鍵,則暫停計時
if ((e.getButton() == MouseEvent.BUTTON2
|| (e.getModifiersEx() & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
== (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))) {
if (timer.isRunning()) {
timer.stop();
//state = PAUSE;
}
else if (state == PLAY) {
timer.start();
}
}
}
});
startPanel.add(remainMines);
startPanel.add(Box.createHorizontalGlue());
startPanel.add(faceButton);
startPanel.add(Box.createHorizontalGlue());
startPanel.add(totalTime);
faceButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
replay();
}
});
// 定義時鐘及其事件處理方法
timer = new Timer(ONE_SECOND, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
totalTime.increase(); // “計時器”每增加1秒,“所用時間”就也增加1秒
if (isSound) {
Toolkit.getDefaultToolkit().beep();
}
}
});
// 組裝總面板
this.add(startPanel, BorderLayout.NORTH);
this.add(mineField, BorderLayout.CENTER);
this.addMouseListener(this);
} // init()
public int getGameLevel() {
return gameLevel;
}
public void setGameLevel(int gameLevel) {
this.gameLevel = gameLevel;
if (gameLevel == LOW_LEVEL) {
reset(9, 9, 10);
}
else if (gameLevel == MIDDLE_LEVEL) {
reset(16, 16, 40);
}
else if (gameLevel == HIGH_LEVEL) {
reset(16, 30, 99);
}
}
public void setGameLevel(int mineRows, int mineColumns, int totalMines) {
gameLevel = CUSTOM_LEVEL;
reset(mineRows, mineColumns, totalMines);
}
public void replay() {
reset(mineRows, mineColumns, totalMines);
}
/**
* 系統重置
*/
private void reset(int mineRows, int mineColumns, int totalMines) {
state = READY;
timer.stop();
remainMines.setNumber(totalMines);
faceButton.setIconStyle(FaceButton.FACE_SMILE);
totalTime.setNumber(0);
// 是否雷區大小發生改變
boolean isChanged = false;
if (this.mineRows != mineRows
|| this.mineColumns != mineColumns
|| this.totalMines != totalMines) {
isChanged = true;
this.mineRows = mineRows;
this.mineColumns = mineColumns;
this.totalMines = totalMines;
}
if (isChanged) {
// 清除雷區所有地雷按鈕
mineField.removeAll();
// 重置mineField面板中GridLayout布局的高度與寬度
gridLayout.setRows(mineRows); // 設置地雷的行數
gridLayout.setColumns(mineColumns); // 設置地雷的列數
// 生成地雷按鈕,并組裝到地雷面板中
mineButton = new MineButton[mineRows][mineColumns];
for (int i = 0; i < mineRows; i++) {
for (int j = 0; j < mineColumns; j++) {
mineButton[i][j] = new MineButton(jmine, i, j);
mineButton[i][j].addMouseListener(this);
mineField.add(mineButton[i][j]);
}
}
}
// 重置所有地雷按鈕為初始狀態
for (int i = 0; i < mineRows; i++) {
for (int j = 0; j < mineColumns; j++) {
mineButton[i][j].setMine(false);
mineButton[i][j].setIconStyle(MineButton.ICON_NULL);
}
}
// 隨機分布地雷
Random random = new Random();
int k = 0;
while (k < totalMines) {
int r = random.nextInt(mineRows);
int c = random.nextInt(mineColumns);
if (!mineButton[r][c].isMine()) {
mineButton[r][c].setMine(true);
k++;
}
}
validate(); // 使改動生效
}
public int getMineRows() {
return mineRows;
}
public void setMineRows(int mineRows) {
this.mineRows = mineRows;
}
public int getMineColumns() {
return mineColumns;
}
public void setMineColumns(int mineColumns) {
this.mineColumns = mineColumns;
}
public int getTotalMines() {
return totalMines;
}
public void setTotalMines(int totalMines) {
this.totalMines = totalMines;
}
// 定義鼠標事件處理方法
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
if (state != READY && state != PLAY)
return;
faceButton.setIconStyle(FaceButton.FACE_O);
Object object = e.getSource();
if (!(object instanceof MineButton))
return;
int button = e.getButton();
int modifiers = e.getModifiers();
int modifiersEx = e.getModifiersEx();
MineButton mb = (MineButton) object;
// 按鈕呈凹下的樣子
if (mb.getIconStyle() == MineButton.ICON_NULL
|| mb.getIconStyle() == MineButton.ICON_MARK) {
mb.setBorderDown();
}
// 若僅按下鼠標右鍵,且左鍵未按下
if (button == MouseEvent.BUTTON3
&& (modifiersEx & InputEvent.BUTTON1_DOWN_MASK)
!= InputEvent.BUTTON1_DOWN_MASK) {
// 處理插上小紅旗過程
if (mb.getIconStyle() == MineButton.ICON_NULL) {
mb.setIconStyle(MineButton.ICON_FLAG);
remainMines.decrease();
if (checkWinning()) {
doWin();
}
}
else if (mb.getIconStyle() == MineButton.ICON_FLAG) {
if (isMark) {
mb.setIconStyle(MineButton.ICON_MARK);
}
else {
mb.setIconStyle(MineButton.ICON_NULL);
}
remainMines.increase();
}
else if (mb.getIconStyle() == MineButton.ICON_MARK) {
mb.setIconStyle(MineButton.ICON_NULL);
}
return;
}
// 若按下中鍵,或同時按下鼠標左鍵和右鍵
if (button == MouseEvent.BUTTON2
|| (modifiersEx & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
== (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) {
isMiddlePressed = true;
doDownAround(mb);
}
}
public void mouseReleased(MouseEvent e) {
if (state != READY && state != PLAY)
return;
faceButton.setIconStyle(FaceButton.FACE_SMILE);
Object object = e.getSource();
if (!(object instanceof MineButton))
return;
MineButton mb = (MineButton) object;
int button = e.getButton();
int modifiers = e.getModifiers();
int modifiersEx = e.getModifiersEx();
// 如果在地雷按鈕外部釋放鼠標,則把該鼠標釋放事件傳輸到鼠標所在的按鈕
if (!mb.contains(e.getX(), e.getY())) {
int x = e.getX();
int y = e.getY();
int width = mb.getSize().width;
int height = mb.getSize().height;
int row = mb.getRow();
int column = mb.getColumn();
//System.out.println("Debug: row = " + row + ", column = " + column + ", e = " + e);
if (y > 0)
row += y / height;
else
row -= -y / height + 1;
if (x > 0)
column += x / width;
else
column -= -x / width + 1;
if (row >= 0 && column >= 0 && row < mineRows && column < mineColumns) {
//System.out.println("Debug2: row = " + row + ", column = " + column
// + ", e = " + SwingUtilities.convertMouseEvent(mb, e, mineButton[row][column]));
mineButton[row][column].dispatchEvent(SwingUtilities.convertMouseEvent(mb, e, mineButton[row][column]));
}
return;
}
// 若釋放了左鍵,且此時右鍵未按下
if (button == MouseEvent.BUTTON1 && !isMiddlePressed
&& ((modifiersEx & InputEvent.BUTTON3_DOWN_MASK) != InputEvent.BUTTON3_DOWN_MASK)) {
treadMineButton(mb);
}
// 若釋放了中鍵,或釋放了左右鍵同時按下后的任何一個
if (isMiddlePressed || button == MouseEvent.BUTTON2
|| (button == MouseEvent.BUTTON1
&& (modifiersEx & InputEvent.BUTTON3_DOWN_MASK) == InputEvent.BUTTON3_DOWN_MASK)
|| (button == MouseEvent.BUTTON3
&& (modifiersEx & InputEvent.BUTTON1_DOWN_MASK) == InputEvent.BUTTON1_DOWN_MASK)) {
isMiddlePressed = false;
doDoubleDownReleased(mb);
}
}
public void mouseEntered(MouseEvent e) {
if (state != READY && state != PLAY)
return;
Object object = e.getSource();
int modifiersEx = e.getModifiersEx();
if (!(object instanceof MineButton))
return;
MineButton mb = (MineButton) object;
// 若按下了鼠標左鍵、或中鍵,或同時按下了左右鍵
if ((modifiersEx & InputEvent.BUTTON1_DOWN_MASK) == InputEvent.BUTTON1_DOWN_MASK
|| (modifiersEx & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK
|| (modifiersEx & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
== (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) {
// 按鈕呈凹下的樣子
if (mb.getIconStyle() == MineButton.ICON_NULL
|| mb.getIconStyle() == MineButton.ICON_MARK) {
mb.setBorderDown();
}
}
// 若按下了鼠標中鍵,或同時按下了鼠標左鍵和右鍵
if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK
||(modifiersEx & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
== (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) {
// 周圍按鈕呈凹下的樣子
doDownAround(mb);
}
}
public void mouseExited(MouseEvent e) {
if (state != READY && state != PLAY)
return;
Object object = e.getSource();
int modifiersEx = e.getModifiersEx();
if (!(object instanceof MineButton))
return;
MineButton mb = (MineButton) object;
// 按鈕呈凸出的樣子
if (mb.getIconStyle() == MineButton.ICON_NULL
|| mb.getIconStyle() == MineButton.ICON_MARK) {
mb.setBorderUp();
}
// 若按下了鼠標中鍵,或同時按下了鼠標左鍵和右鍵
if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK
||(modifiersEx & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
== (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) {
// 周圍按鈕呈凸出的樣子
doUpAround(mb);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -