俄罗斯方块java

功能架构图

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值