java 为什么我不能用while循环在桌面上画棋盘,却可以在笔记本电脑上画?

ffscu2ro  于 2023-02-20  发布在  Java
关注(0)|答案(1)|浏览(73)

我尝试用while循环做一个棋盘,但是当我用while循环时,棋子显示了一秒钟,然后就消失了。
面板的代码

package chess;

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.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

public class ChessBoard extends JPanel{

    public int tileSize = 90;
    public int cols = 8;
    public int rows = 8;
    public int maxCols = cols * tileSize;
    public int maxRows = rows * tileSize;
    TileManager tileM = new TileManager(this);
    
    ChessBoard(){
        
        this.setPreferredSize(new Dimension(maxCols, maxRows));
        this.setBackground(Color.black);
        this.setDoubleBuffered(true); 
        this.setFocusable(true); 
        
    }
    
    public void paintComponent(Graphics g) {
        
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        tileM.drawTiles(g2);
        
    }

}

图形的代码

package chess;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.imageio.ImageIO;

public class TileManager {

    ChessBoard cb;
    public static int [] types = new int[10];
    private static int rows = 0;
    private static int cols = 0;
    private boolean c = true;
    String [] alpha = {"a", "b", "c", "d", "e", "f", "g", "h"};
    String [] num = {"8", "7", "6", "5", "4", "3", "2", "1"};
    
    TileManager(ChessBoard cb){
        
        this.cb = cb;
        
    }
    
    public void drawTiles(Graphics g) {
        
        Graphics2D g2 = (Graphics2D)g;
        
        while (rows < cb.rows && cols < cb.cols) {
            
            if (c)  g.setColor(Color.white);
            if (!c) g.setColor(Color.black);
            
            g2.setFont(new Font("Comic Sans", Font.BOLD, 20));
            g2.fillRect(cols * cb.tileSize, rows * cb.tileSize, cb.tileSize, cb.tileSize);
            g2.setColor(Color.green);
            g2.drawString(alpha[cols], 5 + cols * cb.tileSize, 20 + rows * cb.tileSize);
            g2.drawString(num[rows], 75 + cols * cb.tileSize, 85 + rows * cb.tileSize);
            
            c = !c;
            cols++;

            if (cols == 8) {
                
                c = !c;
                cols = 0;
                rows++;
                
            }
            
        }
        
    }
    
}

奇怪的是,这段代码在我的笔记本电脑上运行得很好,但是当我将它导出到桌面时,它出现了这个问题。

bxfogqkk

bxfogqkk1#

这在很多层面上都是有问题的...

public class TileManager {

    private static int rows = 0;
    private static int cols = 0;

    //...
    public void drawTiles(Graphics g) {
        //...
        while (rows < cb.rows && cols < cb.cols) {

问自己一个问题,下一个油漆通道会发生什么?
Swing中的绘制是破坏性的,也就是说,在每一个新的绘制过程中,您都需要从头开始完全重新绘制组件的状态。
paintComponent要做的事情之一是用组件的背景色填充Graphics上下文。
因此,在后续绘制过程中,rowscols已经是>=cb.rowscb.cols,因此代理将不绘制任何内容。
首先,删除static,它在这个上下文中对你没有任何帮助,可能会给你带来更多的问题。其次,rowscols不需要是示例级变量,它们唯一的功能是支持网格的绘制,所以你可以将它们改为局部变量。
比如说...

public class TileManager {

    ChessBoard cb;
    public int[] types = new int[10];
    private boolean c = true;
    String[] alpha = {"a", "b", "c", "d", "e", "f", "g", "h"};
    String[] num = {"8", "7", "6", "5", "4", "3", "2", "1"};

    TileManager(ChessBoard cb) {
        this.cb = cb;
    }

    public void drawTiles(Graphics g) {

        Graphics2D g2 = (Graphics2D) g;
        
        int rows = 0;
        int cols = 0;

        while (rows < cb.rows && cols < cb.cols) {

            if (c) {
                g.setColor(Color.white);
            }
            if (!c) {
                g.setColor(Color.black);
            }

            g2.setFont(new Font("Comic Sans", Font.BOLD, 20));
            g2.fillRect(cols * cb.tileSize, rows * cb.tileSize, cb.tileSize, cb.tileSize);
            g2.setColor(Color.green);
            g2.drawString(alpha[cols], 5 + cols * cb.tileSize, 20 + rows * cb.tileSize);
            g2.drawString(num[rows], 75 + cols * cb.tileSize, 85 + rows * cb.tileSize);

            c = !c;
            cols++;

            if (cols == 8) {

                c = !c;
                cols = 0;
                rows++;

            }

        }

    }

}

就我个人而言,我认为传递TileManager一个ChessBoard的示例是不好的做法,你向TileManager公开了更多的功能,然后它有任何管理的责任。
就代码本身而言,我看不出有任何理由这样做,但是如果您确实需要TileManager来从中提取信息,我会考虑编写一个定义契约的interface,或者,让ChessBoard设置TileManager的属性。(所以TileManager和告诉,谁曾经感兴趣,有些已经发生了)
我会建议更密切地关注Painting in AWT and Swing
至于"为什么"它在一个平台上工作而不在另一个平台上工作的问题,欢迎来到奇妙的世界,这就是不同平台的工作方式-但有些事情会触发Swing在初始绘制过程之后执行一个或多个绘制过程。
当我在MacOS上测试它时,它一直工作到我尝试重新调整窗口大小的那一刻。

相关问题