当前位置: 首页 > 知识库问答 >
问题:

制作健壮、可调整大小的摇摆棋GUI[关闭]

陶富
2023-03-14

我将如何着手制作这个可调整大小的国际象棋图形用户界面?

我们公司的任务是制作象棋游戏。它需要在Windows、OS X和Linux/UNIX机器上工作,我们选择了Java来实现这一点,同时保持一个通用的代码库(既便于维护,又能降低成本)。

我的任务是创建GUI。用户设计团队已经清除了以下规范。和客户一起。

    null
    null

GUI的其余部分将由棋盘本身组成。它将:

  • 国际象棋棋盘的主要区域。如果用户指向一个棋子,它应该用边框显示焦点。它也应该是键盘可访问的。客户端将提供多个象棋棋子的sprite表(具有各种大小、样式和颜色),以允许用户更改游戏外观。
  • 国际象棋棋盘将有标识列(从左到右:A、B、C、D、E、F、G和H)和行(从上到下:8、7、6、5、4、3、2和1)的标签
  • 国际象棋棋盘和列/行标签将由一个1px的黑色边框加边,并在其周围加上一个8px的填充。
  • 当玩家增加游戏的大小时,棋盘应该保持正方形,但否则会填满可用的空间。
  • 棋盘后面的底色应该是赭色,但在下面的模型中,我们将棋盘后面的区域设置为绿色,以突出显示调整大小的行为。

共有1个答案

薛英卫
2023-03-14

>

  • 国际象棋棋盘的左边和上面都有列,它由9x9GridLayout提供。网格布局的第一个单元格是一个没有文本的标签。

    为了简化游戏逻辑,我们保留了一个单独的8x8按钮数组。

    为了允许键盘功能,我们在棋盘位置使用按钮。这也提供了内置的焦点指示。移除按钮的边距以允许它们收缩到图标的大小。我们可以将ActionListener添加到按钮中,它将响应键盘和鼠标事件。

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    import javax.swing.border.*;
    import java.net.URL;
    import javax.imageio.ImageIO;
    
    public class ChessGUI {
    
        private final JPanel gui = new JPanel(new BorderLayout(3, 3));
        private JButton[][] chessBoardSquares = new JButton[8][8];
        private Image[][] chessPieceImages = new Image[2][6];
        private JPanel chessBoard;
        private final JLabel message = new JLabel(
                "Chess Champ is ready to play!");
        private static final String COLS = "ABCDEFGH";
        public static final int QUEEN = 0, KING = 1,
                ROOK = 2, KNIGHT = 3, BISHOP = 4, PAWN = 5;
        public static final int[] STARTING_ROW = {
            ROOK, KNIGHT, BISHOP, KING, QUEEN, BISHOP, KNIGHT, ROOK
        };
        public static final int BLACK = 0, WHITE = 1;
    
        ChessGUI() {
            initializeGui();
        }
    
        public final void initializeGui() {
            // create the images for the chess pieces
            createImages();
    
            // set up the main GUI
            gui.setBorder(new EmptyBorder(5, 5, 5, 5));
            JToolBar tools = new JToolBar();
            tools.setFloatable(false);
            gui.add(tools, BorderLayout.PAGE_START);
            Action newGameAction = new AbstractAction("New") {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    setupNewGame();
                }
            };
            tools.add(newGameAction);
            tools.add(new JButton("Save")); // TODO - add functionality!
            tools.add(new JButton("Restore")); // TODO - add functionality!
            tools.addSeparator();
            tools.add(new JButton("Resign")); // TODO - add functionality!
            tools.addSeparator();
            tools.add(message);
    
            gui.add(new JLabel("?"), BorderLayout.LINE_START);
    
            chessBoard = new JPanel(new GridLayout(0, 9)) {
    
                /**
                 * Override the preferred size to return the largest it can, in
                 * a square shape.  Must (must, must) be added to a GridBagLayout
                 * as the only component (it uses the parent as a guide to size)
                 * with no GridBagConstaint (so it is centered).
                 */
                @Override
                public final Dimension getPreferredSize() {
                    Dimension d = super.getPreferredSize();
                    Dimension prefSize = null;
                    Component c = getParent();
                    if (c == null) {
                        prefSize = new Dimension(
                                (int)d.getWidth(),(int)d.getHeight());
                    } else if (c!=null &&
                            c.getWidth()>d.getWidth() &&
                            c.getHeight()>d.getHeight()) {
                        prefSize = c.getSize();
                    } else {
                        prefSize = d;
                    }
                    int w = (int) prefSize.getWidth();
                    int h = (int) prefSize.getHeight();
                    // the smaller of the two sizes
                    int s = (w>h ? h : w);
                    return new Dimension(s,s);
                }
            };
            chessBoard.setBorder(new CompoundBorder(
                    new EmptyBorder(8,8,8,8),
                    new LineBorder(Color.BLACK)
                    ));
            // Set the BG to be ochre
            Color ochre = new Color(204,119,34);
            chessBoard.setBackground(ochre);
            JPanel boardConstrain = new JPanel(new GridBagLayout());
            boardConstrain.setBackground(ochre);
            boardConstrain.add(chessBoard);
            gui.add(boardConstrain);
    
            // create the chess board squares
            Insets buttonMargin = new Insets(0, 0, 0, 0);
            for (int ii = 0; ii < chessBoardSquares.length; ii++) {
                for (int jj = 0; jj < chessBoardSquares[ii].length; jj++) {
                    JButton b = new JButton();
                    b.setMargin(buttonMargin);
                    // our chess pieces are 64x64 px in size, so we'll
                    // 'fill this in' using a transparent icon..
                    ImageIcon icon = new ImageIcon(
                            new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
                    b.setIcon(icon);
                    if ((jj % 2 == 1 && ii % 2 == 1)
                            //) {
                            || (jj % 2 == 0 && ii % 2 == 0)) {
                        b.setBackground(Color.WHITE);
                    } else {
                        b.setBackground(Color.BLACK);
                    }
                    chessBoardSquares[jj][ii] = b;
                }
            }
    
            /*
             * fill the chess board
             */
            chessBoard.add(new JLabel(""));
            // fill the top row
            for (int ii = 0; ii < 8; ii++) {
                chessBoard.add(
                        new JLabel(COLS.substring(ii, ii + 1),
                        SwingConstants.CENTER));
            }
            // fill the black non-pawn piece row
            for (int ii = 0; ii < 8; ii++) {
                for (int jj = 0; jj < 8; jj++) {
                    switch (jj) {
                        case 0:
                            chessBoard.add(new JLabel("" + (9-(ii + 1)),
                                    SwingConstants.CENTER));
                        default:
                            chessBoard.add(chessBoardSquares[jj][ii]);
                    }
                }
            }
        }
    
        public final JComponent getGui() {
            return gui;
        }
    
        private final void createImages() {
            try {
                URL url = new URL("http://i.stack.imgur.com/memI0.png");
                BufferedImage bi = ImageIO.read(url);
                for (int ii = 0; ii < 2; ii++) {
                    for (int jj = 0; jj < 6; jj++) {
                        chessPieceImages[ii][jj] = bi.getSubimage(
                                jj * 64, ii * 64, 64, 64);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
        
        /**
         * Initializes the icons of the initial chess board piece places
         */
        private final void setupNewGame() {
            message.setText("Make your move!");
            // set up the black pieces
            for (int ii = 0; ii < STARTING_ROW.length; ii++) {
                chessBoardSquares[ii][0].setIcon(new ImageIcon(
                        chessPieceImages[BLACK][STARTING_ROW[ii]]));
            }
            for (int ii = 0; ii < STARTING_ROW.length; ii++) {
                chessBoardSquares[ii][1].setIcon(new ImageIcon(
                        chessPieceImages[BLACK][PAWN]));
            }
            // set up the white pieces
            for (int ii = 0; ii < STARTING_ROW.length; ii++) {
                chessBoardSquares[ii][6].setIcon(new ImageIcon(
                        chessPieceImages[WHITE][PAWN]));
            }
            for (int ii = 0; ii < STARTING_ROW.length; ii++) {
                chessBoardSquares[ii][7].setIcon(new ImageIcon(
                        chessPieceImages[WHITE][STARTING_ROW[ii]]));
            }
        }
    
        public static void main(String[] args) {
            Runnable r = new Runnable() {
    
                @Override
                public void run() {
                    ChessGUI cg = new ChessGUI();
    
                    JFrame f = new JFrame("ChessChamp");
                    f.add(cg.getGui());
                    // Ensures JVM closes after frame(s) closed and
                    // all non-daemon threads are finished
                    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    // See https://stackoverflow.com/a/7143398/418556 for demo.
                    f.setLocationByPlatform(true);
    
                    // ensures the frame is the minimum size it needs to be
                    // in order display the components within it
                    f.pack();
                    // ensures the minimum size is enforced.
                    f.setMinimumSize(f.getSize());
                    f.setVisible(true);
                }
            };
            // Swing GUIs should be created and updated on the EDT
            // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
            SwingUtilities.invokeLater(r);
        }
    }
    

  •  类似资料:
    • 问题内容: 不知道我需要什么。我有一个包含一些内部元素的容器(JPanel)。我想知道是否有可能迫使内部元素适应容器的大小。我需要使它们完全可见,即调整其大小以适合面板的尺寸,并且不剪切内部元素的某些部分。 滚动不是一种选择。 使用Layout或其他方法可以做到吗? 编辑:重要说明:问题是我无法访问内部元素,也无法访问其属性,因此我想说需要一个能够调整子元素大小以适合其大小的Layoutmanag

    • 所以,我试图在JavaFX中显示一个棋盘。我将不得不执行不同的操作和绘制一些瓷砖,所以我选择使用画布为每个瓷砖和一个网格窗格为我以网格的方式排列它们。 不幸的是,我有一些问题与网格瓷砖的大小;我想让我的整个棋盘自动适应它的大小来适应场景。因此,我在GridPane的height和width属性中添加了一个ChangeListener,它负责调整瓷砖的大小。这只在窗口变大时起作用,当窗口缩小到更小的

    • 我有一个java项目(tomcat webapp)和一些REST Api。我想为他们生成大摇大摆的文档。我从本教程(github)开始。我没有maven我们使用蚂蚁任务。我加入了swagger-annotations-1.5.0。jar和所有随swagger jaxrs jar 1.5.0版本附带的jar(如果有用的话,我可以包括一个完整的列表),我已经注释了一些方法,我有一个如下的配置类: }

    • 有没有人用spring-data-rest配置了swagger。我知道swagger有DocumentationConfig类,它扫描所有spring-mvc请求映射。但是,如何将其用于spring-data-rest,因为没有定义显式的请求映射。非常感谢在这方面的任何帮助。此外,我还想知道,是否有其他支持Spring-Data-REST的文档框架。

    • Unix 至少设立了三层内部边界来防范恶意用户或有缺陷的程序。一层是内存管理:Unix 用硬件自身的内存管理单元(MMU)来保证各自的进程不会侵入到其它进程的内存地址空间。第二层是为多用户设置的真正权限组——普通用户(非 root用户)的进程未经允许,就不能更改或者读取其他用户的文件。第三层是把涉及关键安全性的功能限制在尽可能小的可信代码块上。在 Unix 中,即使是 shell(系统命令解释器)

    • 我正在使用Spring Boot2开发一个REST api。我在build.gradle文件中为Swagger2和Swagger-UI添加了SpringFox依赖项,如下所示: 不幸的是,像@enableswagger2这样的大摇大摆的注释似乎没有被识别出来。我该怎么办?