0

我做了一个网格,你可以在其中放置标记。我的问题是,当我调整窗口大小时,这些标记有时会出现,有时不会出现。此外,当我遮挡窗口的一部分时,我会丢失该区域的标记。

代码非常简单:

import javax.swing.*;
import java.lang.Math;
import java.awt.*;
import java.awt.event.*;

enum markerColor {
    red, green, none
};

public class tictactoe extends JFrame {
    private class Plansza extends JPanel {
    private int x0,y0,gridSize,step;
    private Graphics graph;
    private markerColor[][] grid;
    public Plansza() {
        grid = new markerColor[29][29];
        for(int i = 0; i<29;i++) {
        for(int j = 0; j<29;j++) {
            grid[i][j] = markerColor.none;
            }
        }

        addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
            int x = e.getX(), y = e.getY();
            x-=x0; y-=y0;
            if(x>=gridSize || y>=gridSize) return;
            int X = x/step, Y = y/step;
            placeMarker(X,Y, markerColor.green);
            grid[X][Y] = markerColor.green;
            }
        });
    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        int width = getWidth();
        int height = getHeight();
        gridSize = Math.min(width,height);
        step = gridSize/29;
        gridSize = step*29;
        x0 = (width-gridSize)/2;
        y0 = (height-gridSize)/2;
        graph = getGraphics();

        g.setColor(Color.black);
        for(int i = 1, pointer=step; i<=28; i++, pointer+=step) {
        g.drawLine(x0+pointer,y0,x0+pointer,y0+gridSize);
        g.drawLine(x0,y0+pointer,x0+gridSize,y0+pointer);
        }

        for(int i = 0; i<29;i++) {
        for(int j = 0; j<29;j++) {
            if(grid[i][j] != markerColor.none) {
            placeMarker(i,j,grid[i][j]);
                }
            }
        }
        }
    public void placeMarker(int X, int Y, markerColor m) {
        int x = X*step+2*step/10, y = Y*step+2*step/10;
        switch(m) {
        case red:
        graph.setColor(Color.red);
        break;
        case green:
        graph.setColor(Color.green);
        break;
        }
        graph.fillOval(x0+x,y0+y, step*6/10, step*6/10);
    }
    }
    private Plansza plansza = new Plansza();
    public tictactoe() {
    add(plansza);
    }
    public static void main(String[] args) {
    tictactoe t = new tictactoe();
    t.setTitle("tictactoe");
    t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    t.setSize(500,500);
    t.setVisible(true);
    }
}

validate()在paintComponent中尝试过,但没有成功。我该如何改进呢?

4

1 回答 1

0

我试图用它制作一个 SSCCE,它工作正常

public class SSCCE extends JPanel {

    enum markerColor {
        red, green, none
    };

    markerColor grid [][];
    int gridSize = 29;
    int x0 = 0;
    int y0=0;
    int step = 1;
    Graphics graph;
    public SSCCE() {
        grid = new markerColor[29][29];
        for(int i = 0; i<29;i++)
            for(int j = 0; j<29;j++)
                grid[i][j] = markerColor.none;

        addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                int x = e.getX(), y = e.getY();
                x-=x0; y-=y0;

                int X = x/step, Y = y/step;

                //Changed here
                if(X>=gridSize || Y>=gridSize || X < 0 || Y < 0) return;

                placeMarker(X,Y, markerColor.green);
                grid[X][Y] = markerColor.green;

                //Call repaint in the mouse click 
                repaint();
            }
        });
    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        int width = getWidth();
        int height = getHeight();
        int gridSize = Math.min(width,height);
        step = gridSize/29;
        gridSize = step*29;
        x0 = (width-gridSize)/2;
        y0 = (height-gridSize)/2;
        graph = g;

        graph.setPaintMode();
        g.setColor(Color.black);
        for(int i = 1, pointer=step; i<=28; i++, pointer+=step) {
            g.drawLine(x0+pointer,y0,x0+pointer,y0+gridSize);
            g.drawLine(x0,y0+pointer,x0+gridSize,y0+pointer);
        }

        g.fillOval(10, 10, 40, 50);
        for(int i = 0; i<29;i++)
            for(int j = 0; j<29;j++)
                if(grid[i][j] != markerColor.none)
                    placeMarker(i,j,grid[i][j]);
    }
    public void placeMarker(int X, int Y, markerColor m) {
        int x = X*step+2*step/10, y = Y*step+2*step/10;
        switch(m) {
        case red:
            graph.setColor(Color.red);
            break;
        case green:
            graph.setColor(Color.green);
            break;
        default :
            graph.setColor(Color.blue);
        }
        graph.fillOval(x0+x,y0+y, step*6/10, step*6/10);

    }


    public static void main(String arg[]){
        JFrame frame = new JFrame();
        frame.add(new SSCCE(), BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

2件事你不应该做

  1. 不要检查鼠标单击以获取(x,y)组件,而是首先将您的 x,y 与您对齐grid(X,Y)
  2. 不要revalidate因为你没有改变面板的结构而只是添加了新绘制的组件更好地使用repaint
于 2012-05-25T11:03:24.583 回答