功能架构图
1.主方法的实现
package controller;
/**
* 游戏资源总调度
*/
import view.MainWin;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import model.GameData;
import model.ImageModel;
public class GameController {
public static void main(String[] args) {
// 加载游戏数据
GameData gamedata = new GameData();
// 加载主窗口
MainWin mainwin = new MainWin(gamedata);
// 初始化操作区
OprationControl oprationControl = new OprationControl(gamedata, mainwin);
mainwin.setOprationArea(oprationControl);
// 初始化全局操作
mainwin.addFunAera(ImageModel.SETTING_IMG.getImage(), oprationControl.onSettingClick);
mainwin.addFunAera(ImageModel.LOGEIN_IMG.getImage(), oprationControl.onSigninclick);
// 窗口事件监听
mainwin.addWindowStateListener(new WindowStateListener() {
public void windowStateChanged(WindowEvent state) {
if (state.getNewState() == 0) {
System.out.println("窗口恢复到初始状态");
mainwin.validate();
}
}
});
// 按键事件监听
mainwin.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
// TODO 打印输入字符
// System.out.println(code);
if(code == oprationControl.rotaKey){
oprationControl.rotate.doClick();
}
if(code == oprationControl.downKey){
oprationControl.down.doClick();
}
if(code == oprationControl.leftKey){
oprationControl.left.doClick();
}
if(code == oprationControl.righKey){
oprationControl.right.doClick();
}
}
public void keyTyped(KeyEvent e) {
;
}
public void keyReleased(KeyEvent e) {
;
}
});
// 展示主窗
mainwin.setVisible(true);
mainwin.setFocusable(true);
}
}
// 每秒下降控制
class DownControll extends Thread {
int resttime;
int sleepTime;
GameData gamedata;
MainWin mainwin;
int score;
OprationControl oprationControl;
DownControll(OprationControl op, GameData gd, MainWin mw) {
resttime = 200;
sleepTime = 800;
gamedata = gd;
mainwin = mw;
oprationControl = op;
}
@Override
public void run() {
while (true) {
try {
if (gamedata.state == 1) {
if (!gamedata.move(false, 1)) {
gamedata.deletLine();
score = gamedata.getScore();
(mainwin.getGameDataArea()).repaint();
}
(mainwin.getgameCanvas()).repaint();
sleep(sleepTime-(gamedata.getScore()<500?gamedata.getScore():500));
} else if (gamedata.state == 3) {
mainwin.alert("游戏结束" + gamedata.getScore() + "分");
oprationControl.startStop.setText("新的");
(mainwin.getgameCanvas()).repaint();
gamedata.state = 0;
} else if ((gamedata.state == 2)) {
sleep(resttime);
DownControll.yield();
} else {
return;
}
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}
}
package controller;
import javax.swing.ButtonGroup;
/**
* 操作按键控制区,对点击事件的处理
*/
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.Dimension;
import model.GameData;
import model.ImageModel;
import view.AlertFrame;
import view.MainWin;
import view.elements.FunArea;
import view.elements.ImageButtom;
public class OprationControl {
/**
* 游戏数据
*/
GameData gameData;
MainWin mainwin;
DownControll downControl;
public int downKey;
public int rotaKey;
public int leftKey;
public int righKey;
/**
* 添加设置事件
*/
class Setting implements FunArea.Clickable {
@Override
public void onClick() {
int statebake = gameData.state;
gameData.state = 2;
ButtonGroup choseblock = new ButtonGroup();
JRadioButton block1 = new JRadioButton("晶莹");
JRadioButton block2 = new JRadioButton("立方");
choseblock.add(block1);
choseblock.add(block2);
JPanel Jpanel = new JPanel();
Jpanel.setSize(123,160);
Jpanel.setPreferredSize(new Dimension(123, 160));
Jpanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 30, 20));
JLabel jlchoseblock = new JLabel("设置格子主题:");
Jpanel.add(jlchoseblock);
Jpanel.add(block1);
Jpanel.add(block2);
if(gameData.blocksType == 0){
block1.setSelected(true);
}else{
block2.setSelected(true);
}
JLabel jlSetKeys = new JLabel("按键设置:(不填写默认为方向键) ");
Jpanel.add(jlSetKeys);
JLabel jlro = new JLabel("旋转");
JLabel jld = new JLabel("向下");
JLabel jll = new JLabel("向左");
JLabel jlri = new JLabel("向右");
JTextField jtro = new JTextField((rotaKey==38)?"":""+(char)rotaKey,2);
JTextField jtd = new JTextField((downKey==40)?"":""+(char)downKey,2);
JTextField jtl = new JTextField((leftKey==37)?"":""+(char)leftKey,2);
JTextField jpri = new JTextField((righKey==39)?"":""+(char)righKey,2);
Jpanel.add(jlro);
Jpanel.add(jtro);
Jpanel.add(jld );
Jpanel.add(jtd );
Jpanel.add(jll );
Jpanel.add(jtl );
Jpanel.add(jlri);
Jpanel.add(jpri);
Jpanel.setBackground(Color.white);
JScrollPane jsp = new JScrollPane();
jsp.setBackground(Color.white);
jsp.setSize(290, 130);
jsp.setViewportView(Jpanel);
AlertFrame af = new AlertFrame(mainwin, true,
new Container[]{jsp},
new int[]{27, 52, 290, 130}) {
private static final long serialVersionUID = -3163280776393079548L; // 序列化
@Override
public void goahead() {
if(!jtd.getText().equals("")){
downKey = jtd.getText().toUpperCase().charAt(0);
}else{
downKey = KeyEvent.VK_DOWN;
}
if(!jtro.getText().equals("")){
rotaKey = jtro .getText().toUpperCase().charAt(0);
}else{
rotaKey = KeyEvent.VK_UP;
}
if(!jtl .getText().equals("")){
leftKey = jtl .getText().toUpperCase().charAt(0);
}else{
leftKey = KeyEvent.VK_LEFT;
}
if(!jpri.getText().equals("")){
righKey = jpri.getText().toUpperCase().charAt(0);
}else{
righKey = KeyEvent.VK_RIGHT;
}
if(block1.isSelected()){
gameData.blocksType = 0;
}else{
gameData.blocksType = 1;
}
closeDialog();
}
};
af.setOKText("使用");
af.showDialog();
gameData.state = statebake;
}
};
public Setting onSettingClick = new Setting();
/**
* 添加登录事件
*/
class Signin implements FunArea.Clickable {
@Override
public void onClick() {
int statebake = gameData.state;
gameData.state = 2;
JLabel jb1 = new JLabel("昵称:");
JLabel jb2 = new JLabel("密码:");
JTextField jta = new JTextField(gameData.playername=="未知玩家"?"":gameData.playername,15);
JPasswordField jpa = new JPasswordField(15);
jpa.setEchoChar('*');
AlertFrame af = new AlertFrame(mainwin, true, new Container[] { jb1, jb2, jta, jpa },
new int[] { 40, 60, 70, 30, 40, 116, 70, 30, 120, 60, 120, 30, 120, 116, 120, 30 }) {
private static final long serialVersionUID = -3163280776393079548L; // 序列化
@Override
public void goahead() {
if(((JTextField) this.extreElements[2]).getText()=="") {
this.note("名字为空,以“未知玩家”进行记录");
}else if (gameData.testPlayer(((JTextField) this.extreElements[2]).getText(),
((JPasswordField) this.extreElements[3]).getPassword())) {
closeDialog();
}else{
this.note("只用拥有密码才可以使用该昵称");
}
}
};
af.setOKText("登录/注册");
af.showDialog();
gameData.state = statebake;
}
};
public Signin onSigninclick = new Signin();
abstract class OprationButtom extends ImageButtom {
private static final long serialVersionUID = 4966748868577177335L; // 序列化
OprationButtom(ImageIcon image) {
super(image, 42, 42);
}
@Override // 添加点击事件
public void doClick() {
if (gameData.state == 1) {
onClick();
(mainwin.getgameCanvas()).repaint();
}
}
/**
* 需要重写的事件
*/
abstract void onClick();
}
/**
* 添加旋转事件
*/
public OprationButtom rotate;
public OprationButtom left;
public OprationButtom right;
public OprationButtom down;
public JButton startStop = new JButton("开始");
OprationControl op;
OprationControl(GameData gameData, MainWin mainwin) {
/**
* 接收游戏数据
*/
this.gameData = gameData;
/**
* 接收游戏面板
*/
this.mainwin = mainwin;
/**
* 备份一个自己一遍传值
*/
op = this;
/**
* 初始按键值
*/
downKey = KeyEvent.VK_DOWN;
rotaKey = KeyEvent.VK_UP;
leftKey = KeyEvent.VK_LEFT;
righKey = KeyEvent.VK_RIGHT;
/**
* 游戏进行状态控制
*/
startStop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
switch (gameData.state) {
case 0:
startStop.setText("暂停");
// 窗口更新与数据绑定
gameData.init();
mainwin.setDynamic();
mainwin.setZindex();
downControl = new DownControll(op, gameData, mainwin);
downControl.start();
gameData.setState(1);
break;
case 1:
startStop.setText("继续");
gameData.setState(2);
break;
case 2:
startStop.setText("暂停");
gameData.setState(1);
break;
}
mainwin.requestFocus();
}
});
/**
* 绑定旋转事件
*/
rotate = new OprationButtom(ImageModel.ROTATE_IMG) {
private static final long serialVersionUID = 1L; // 序列化
@Override // 添加点击事件
public void onClick() {
gameData.Rotate();
}
};
/**
* 绑定左移事件
*/
left = new OprationButtom(ImageModel.LEFT_IMG) {
private static final long serialVersionUID = 1L; // 序列化
@Override // 添加点击事件
public void onClick() {
gameData.move(true, -1);
}
};
/**
* 绑定右移事件
*/
right = new OprationButtom(ImageModel.RIHGT_IMG) {
private static final long serialVersionUID = 1L; // 序列化
@Override // 添加点击事件
public void onClick() {
gameData.move(true, 1);
}
};
/**
* 绑定下移事件
*/
down = new OprationButtom(ImageModel.DOWN_IMG) {
private static final long serialVersionUID = 1L; // 序列化
@Override // 添加点击事件
public void onClick() {
if (!gameData.move(false, 1)) {
gameData.deletLine();
(mainwin.getGameDataArea()).repaint();
}
;
}
};
}
}
2.实现代码的底层逻辑,及方块的下落,旋转,消去,分数的统计等特征
package model;
/**
* 俄罗斯方块模板
*/
import java.awt.Point;
public class Block{
Point[] points; // 格子顶点集
static int INIT_X = 4; // 初始化横坐标
static int INIT_Y = 1; // 初始化纵坐标
public static int SIZE = 20; // 每一个格子的大小 单位px
int shiftX;
int shiftY;
// 构造器: 仅用于设置7类基础方块
Block(int[] x, int[] y){
points = new Point[4];
for(int i=0; i<4; i++){
points[i] = new Point(x[i]+INIT_X, y[i]+INIT_Y);
}
}
/**
* 拷贝构造方法,用于每次生成的方块实例
*/
public Block(Block b){
points = new Point[4];
for(int i=0; i<4; i++){
points[i] = new Point((b.points[i]).x, (b.points[i]).y);
}
shiftX = INIT_X;
shiftY = INIT_Y;
}
/**
* 移动方法
* @param ishrizontal 是否水平移动
* @param step 移动的格数
*/
public void move(Boolean ishrizontal, int step){
if(ishrizontal){
for(int i=0; i<4; i++){
points[i].x += step;
}
shiftX += step;
}else{
for(int i=0; i<4; i++){
points[i].y += step;
}
shiftY += step;
}
}
/**
* 顺时针旋转
* 1. 将坐标减去偏置变为原始坐标
* 2. 利用旋转公式进行旋转 y=x; x=-y;
* 3. 再将原始坐标加上偏置转化为实体坐标
*/
public void rotate(){
for(int i=0; i<4; i++){
points[i].x -= shiftX;
points[i].y -= shiftY;
int temp = points[i].y;
points[i].y = points[i].x;
points[i].x = -temp;
points[i].x += shiftX;
points[i].y += shiftY;
}
}
// getter
public Point[] getPoints(){
return points;
}
}
package model;
import java.awt.Point;
import java.util.List;
import java.util.Random;
/**
* 玩家在进行游戏时产生的所有数据都通过这个类,在内存中实例;
*/
public class GameData{
/**
* 常量方块,包含每个方块之间的相对位置信息
*/
public static Block[] BLOCKS = new Block[]{
new Block(new int[]{-1, 0, 1, 1}, new int[]{ 0, 0, 0,-1}),
new Block(new int[]{-1, 0, 1, 2}, new int[]{ 0, 0, 0, 0}),
new Block(new int[]{-1,-1, 0, 1}, new int[]{-1, 0, 0, 0}),
new Block(new int[]{-1, 0, 0, 1}, new int[]{ 0, 0,-1,-1}),
new Block(new int[]{ 0, 0, 1, 1}, new int[]{ 0,-1, 0,-1}),
new Block(new int[]{-1, 0, 0, 1}, new int[]{-1, 0,-1, 0}),
new Block(new int[]{-1, 0, 0, 1}, new int[]{ 0, 0,-1, 0})
};
/**
* 旋转中心距真实中心的偏移量,用于居中输出,单位为1/2
*/
public static int[] DEVIATE = new int[]{0, -1, 0, 0, -1, 0, 0};
/**
* playData
*/
PlayerData playerData;
public String playername;
String playerpassword;
/**
* 当前的方块 包含当前方块的位置和形状
*/
Block currentBlock;
/**
* 当前累积的方块
*/
int[][] existBlocks;
/**
* 换行数组:记录每一行需要下降的格数
*/
int[] deletNum;
/**
* 随机数产生器
*/
Random rand;
/**
* 预设分值
*/
static int[] scores = new int[]{0, 10, 30, 60, 100};
/**
* 玩家的分数
*/
int score;
/**
* 下一个物块的id
*/
int next;
/**
* 现在物块的id
*/
int currentid;
/**
* 格子样式
*/
public int blocksType;
/**
* 游戏状态 0.没有游戏进行 1。游戏中... 2.游戏暂停 3.游戏结束
*/
public volatile int state;
/**
* 初始化随机过程。初始画存在的方块矩阵
*/
public GameData(){
state = 0;
blocksType = 0;
playername = "未知玩家";
playerpassword = "12345";
playerData = new PlayerData(playername, playerpassword);
init();
}
/**
* 初始化
*/
public void init(){
existBlocks = new int[20][10];
rand = new Random();
next = rand.nextInt(7);
currentid = next;
score = 0;
deletNum = new int[20];
randomBlock();
}
/**
* 随机生成方块
*/
public void randomBlock(){
currentid = next;
currentBlock = new Block(BLOCKS[next]);
next = rand.nextInt(7);
//TODO 提示代码
// System.out.println("下一个是" + next);
}
/**
* currentBlock的移动方法
* 1. 判断是否可以移动
* 2. 可以移动时调用移动方法
* @return 是否到达底部
*/
public Boolean move(Boolean ishrizontal, int step){
Boolean islegal = true;
try{
if(ishrizontal){
for(int i=0; i<4; i++){
if(currentBlock.points[i].x + step > 9||
currentBlock.points[i].x + step < 0 ||
existBlocks[currentBlock.points[i].y][currentBlock.points[i].x + step] != 0){
islegal = false;
break;
};
}
}else{
for(int i=0; i<4; i++){
if(currentBlock.points[i].y + step>19 ||
existBlocks[currentBlock.points[i].y + step ][currentBlock.points[i].x ]!=0){
saveBlock();
randomBlock();
islegal = false;
return false;
};
}
}
if(islegal){
currentBlock.move(ishrizontal, step);
}
}catch(IndexOutOfBoundsException e){
System.out.println("超界了,不过不影响游戏");
}
return true;
}
/**
* 旋转方法
* 1. 判断是否可以旋转
* 2. 可以旋转调用Block的旋转方法
*/
public void Rotate(){
for(int i=0; i<4; i++){
int y = (currentBlock.points[i].x - currentBlock.shiftX) + currentBlock.shiftY;
int x = -(currentBlock.points[i].y - currentBlock.shiftY) + currentBlock.shiftX;
try{
if(y<0|| y>20 || x<0 || x>10 ||existBlocks[y][x]!=0){
return;
}
}catch(IndexOutOfBoundsException e){
System.out.println("超界了,不过不影响游戏");
return;
}
}
currentBlock.rotate();
}
/**
* 保存Block,用于将CurrentBlock写入到existBlocks里
*
*/
void saveBlock(){
for(Point point: currentBlock.points){
existBlocks[point.y][point.x] = getCurrent() + 1;
}
}
/**
* 消行方法,并计算是否游戏结束;
*/
public void deletLine(){
boolean canDelet;
// 计算要消的行数数组
for(int i=19; i>=2; i--){
canDelet = true;
for(int j=0; j<10 ;j++){
if(existBlocks[i][j] == 0){
canDelet = false;
break;
}
}
if(i != 0){
if(canDelet){
deletNum[i-1] = deletNum[i] + 1;
}else{
deletNum[i-1] = deletNum[i];
}
}
}
// 进行消行
for(int i=19; i>=2; i--){
if(deletNum[i] == 0){
continue;
}
for(int j=0; j<10 ;j++){
existBlocks[i+deletNum[i]][j] = existBlocks[i][j];
}
}
for(int i=0; i<9; i++){
if(existBlocks[2][i] != 0){
state = 3;
saveScore();
playerData = new PlayerData(playername, playerpassword);
return;
}
}
score += scores[deletNum[2]];
deletNum = new int[20];
}
/**
* 保存分数
*/
void saveScore(){
playerData.savedata(score);
}
// getter
public Block getBlock(){
return currentBlock;
}
public int[][] getExistBlocks(){
return existBlocks;
}
public int getScore(){
return this.score;
}
public int getNext(){
return next;
}
public int getCurrent(){
return currentid;
}
// getter
public List<String> getPlayersName(){
return playerData.playersName;
}
public List<Integer> getPlayerScore(){
return playerData.playerScore;
};
public void setState(int state) {
this.state = state;
}
/**
* 检查用户是否合法
* @param text
* @param password
* @return
*/
public boolean testPlayer(String text, char[] password) {
String pass = new String(password);
if(playerData.signin(text, pass)){
playername = text;
playerpassword = pass;
return true;
};
return false;
}
}
package model;
/**
* 图片类信息获取
*/
import javax.swing.ImageIcon;
public class ImageModel {
/**
* notes:这里用ImageIcon来读取图片,以避免ImageIO.read时需要错误控制。
* 您可以使用ImageIcon.getImg()来获取Image对象
*/
public static ImageIcon BACK_IMAGE = new ImageIcon("imgs/back3.png");
public static ImageIcon LEFT_IMG = new ImageIcon("imgs/left.png");
public static ImageIcon RIHGT_IMG = new ImageIcon("imgs/right.png");
public static ImageIcon DOWN_IMG = new ImageIcon("imgs/down.png");
public static ImageIcon ROTATE_IMG = new ImageIcon("imgs/rotate.png");
public static ImageIcon SETTING_IMG = new ImageIcon("imgs/setting.png");
public static ImageIcon LOGEIN_IMG = new ImageIcon("imgs/signin.png");
public static ImageIcon[] MASK_IMG = new ImageIcon[]{
new ImageIcon("imgs/mask0.png"),
new ImageIcon("imgs/mask1.png"),
}
;
}
package model;
import java.util.List;
import java.util.ArrayList;
import java.sql.*;
public class PlayerData {
Connection c;
Statement stmt;
List<String> playersName;
List<Integer> playerScore;
String currentname;
String password;
PlayerData(String name, String password) {
currentname = name;
this.password = password;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:data/player.db");
System.out.println("Opened database successfully");
stmt = c.createStatement();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
}
createTable();
getPlayerInfor(5);
}
boolean createTable() {
try {
String sql = "CREATE TABLE Players " + "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ " name TEXT NOT NULL, " + " password CHAR(20) NOT NULL, "
+ " score INT)";
stmt.executeUpdate(sql);
return true;
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
return false;
}
}
void getPlayerInfor(int num) {
playersName = new ArrayList<String>();
playerScore = new ArrayList<Integer>();
try {
ResultSet rs = stmt.executeQuery("SELECT name,score FROM Players ORDER BY score DESC LIMIT 4");
while (rs.next()) {
System.out.println(rs.getString("NAME") + rs.getInt("SCORE"));
playersName.add(rs.getString("NAME"));
playerScore.add(rs.getInt("SCORE"));
}
} catch (SQLException e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
}
}
boolean savedata(int score) {
System.out.println(currentname + password);
try {
stmt.executeQuery("INSERT INTO Players (name, password, score) VALUES ('" + this.currentname + "', '"
+ this.password + "', '" + score + "')");
c.commit();
return true;
} catch (SQLException e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
return false;
}
}
public boolean signin(String name, String pass) {
try {
ResultSet rs = stmt.executeQuery("SELECT password FROM Players WHERE name = '" + name + "'");
if(rs.next()){
if(!(""+rs.getString("password")).equals(pass)){
System.out.println(rs.getString("password") + " " + pass);
return false;
}
}
} catch (SQLException e) {
// TODO 修改下面的检测函数
e.printStackTrace();
}
this.currentname = name;
this.password = pass;
return true;
}
}
class Player {
Player(String name, int score){
this.name = name;
this.score = score;
}
String name;
int score;
}
对游戏界面进行设计
package view.elements;
import java.awt.Container;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public abstract class FunArea {
// 点击是事件接口
@FunctionalInterface
public interface Clickable{
abstract public void onClick();
}
public int x;
public int y;
public int w;
public int h;
public FunArea(Container fatherContainer, int x, int y, int w, int h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
fatherContainer.addMouseListener(new MouseListener(){
@Override
public void mouseClicked(MouseEvent e) {
if(e.getX()>=x && e.getX()<=x+w){
if(e.getY()>=y && e.getY()<=y+h){
onClick();
}
}
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
});
}
// 设置点击事件
abstract public void onClick();
}
package view.elements;
/**
* 网格组布局的Panel
*/
import javax.swing.JPanel;
import java.awt.Insets;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
public class GridBagPanel extends JPanel{
// 序列化
private static final long serialVersionUID = -1410281569702346504L;
// 应用网格组布局
protected GridBagPanel() {
setLayout(new GridBagLayout());
}
// 获取单元格位置
protected GridBagConstraints setPostion (int x, int y, int w, int h){
return setPostion(x,y,w,h,0);
}
protected GridBagConstraints setPostion (int x, int y, int w, int h, int paddingtop){
GridBagConstraints g1 = new GridBagConstraints();
g1.insets = new Insets(paddingtop, 0, 0, 0);
g1.gridx = x;
g1.gridy = y;
g1.gridwidth = w;
g1.gridheight = h;
g1.weighty = 1;
g1.weightx = 1;
g1.fill = GridBagConstraints.BOTH;
return g1;
}
}
package view.elements;
import java.awt.RenderingHints;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public abstract class ImageButtom extends JPanel{
ImageIcon img;
FunArea funArea;
int weight;
int height;
// 序列化
private static final long serialVersionUID = 2191075283557461594L;
// 初始化
public ImageButtom(ImageIcon img, int x, int y){
super();
setOpaque(false);
this.img = img;
this.weight = x;
this.height = y;
funArea = new FunArea(this, 0, 0, x, y){
@Override
public void onClick() {
doClick();
}
};
}
@Override
protected void paintComponent(Graphics g){
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(img.getImage(), 0,0, weight, height, null);
}
public ImageButtom() {
}
public abstract void doClick();
}