重新定位JFrame的ContentPane

3

我试图在JFrame的内容面板内绘制网格,但是当我这样做时,一切都错了。网格开始太宽并且偏移(可能设置了窗口边框与内容面板重叠的位置),而且没有正确地绘制整个网格。当我使用frame.setUndecorated(true);时,一切都完美地工作。

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.*;

@SuppressWarnings("serial")
class Creator extends JFrame{

    JFrame frame;
    int[][] Grid = new int[18][27];
    public Creator(){
        frame = this;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        for(int i = 0; i < 18; i++) {
            for(int j = 0; j < 27; j++) {
                Grid[i][j] = 0;
            }
        }
        setSize(864, 544);

        getContentPane().addMouseListener(new MouseAdapter() {            
            @Override
            public void mouseClicked(MouseEvent e) {
                int yLocation = e.getX()/32;
                int xLocation = e.getY()/32;
                System.out.println(xLocation + " " + yLocation);

                if(e.getButton() == 1){
                    if(xLocation < 1 || yLocation < 1){
                        Grid[xLocation][yLocation] = 2;
                        System.out.println("Enemy Added");
                    }else if(xLocation > 16 || yLocation > 25){
                        Grid[xLocation][yLocation] = 2;
                        System.out.println("Enemy Added");
                    }else {
                        Grid[xLocation][yLocation] = 1;
                        System.out.println("Obstacle Added");
                    }
                }else {
                    Grid[xLocation][yLocation] = 0;
                    System.out.println("Item Removed");
                }
                frame.invalidate();
                frame.validate();
                frame.repaint();
            }
        });

    }

    public void paint(Graphics g) {
        g.clearRect(0, 0, 864, 544);
        Graphics2D g2 = (Graphics2D) g;
        for(int i =0; i < 18; i++) {
            for(int j =0; j < 27; j++) {
                if(Grid[i][j] != 0){
                    if( i < 1 || j < 1 || i > 26 || j > 17) {
                        g2.setColor(Color.RED);
                        g2.fillRect(j*32, i*32, 32, 32);
                    }else {
                        g2.setColor(Color.BLUE);
                        g2.fillRect(j*32, i*32, 32, 32);
                    }
                }
                //System.out.print(Grid[i][j]);
            }
            //System.out.println();
        }
        for(int i = 0; i < 27; i++) {
            Line2D lin = new Line2D.Float(i*32, 0, i*32, 544);
            g2.draw(lin);
        }
        for(int i = 0; i < 18; i++) {
            Line2D lin = new Line2D.Float(0, i*32, 864, i*32);
            g2.draw(lin);
        }

    }

    public static void main(String []args){
        Creator s=new Creator();
        s.setVisible(true);
    }
}
2个回答

3

不要设置框架的大小。

相反,创建一个JPanel或JComponent的子类,重写paintComponent()方法来绘制网格,重写getPreferredSize()方法返回应该具有的大小(864 x 544)。将此面板添加到您的框架中,并调用pack()以确保框架大小自动调整为显示其组件所需的首选大小。

编辑:示例:

public class GridPanel extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
        // paint the grid here
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(864, 544);
    }
}

在JFrame构造函数中:

GridPanel gridPanel = new GridPanel();
this.add(gridPanel);
this.pack();

你能给我一个例子吗?我对JFrames非常陌生。 - Chris
谢谢 :) 探索自己从未涉足的领域总是很有趣的。 - Chris
1
getPreferredSize() 应该返回 Dimension 类型而不是 void,对吗? - Chris

1

JB Nizet提供了一个非常好的解决方案。请按照以下方式更改您的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.*;

@SuppressWarnings("serial")
class Creator extends JPanel{


    static int[][] Grid = new int[18][27];
    public Creator(){        
        setSize(getPreferredSize());
    }

    public void paint(Graphics g) {
        g.clearRect(0, 0, getWidth(), getHeight());
        Graphics2D g2 = (Graphics2D) g;
        for(int i =0; i < 18; i++) {
            for(int j =0; j < 27; j++) {
                if(Grid[i][j] != 0){
                    if( i < 1 || j < 1 || i > 26 || j > 17) {
                        g2.setColor(Color.RED);
                        g2.fillRect(j*32, i*32, 32, 32);
                    }else {
                        g2.setColor(Color.BLUE);
                        g2.fillRect(j*32, i*32, 32, 32);
                    }
                }
                //System.out.print(Grid[i][j]);
            }
            //System.out.println();
        }
        for(int i = 0; i < 27; i++) {
            Line2D lin = new Line2D.Float(i*32, 0, i*32, getHeight());
            g2.draw(lin);
        }
        for(int i = 0; i < 18; i++) {
            Line2D lin = new Line2D.Float(0, i*32, getWidth(), i*32);
            g2.draw(lin);
        }

    }

    public static void main(String []args){
        JFrame frame=new JFrame();
        Creator s=new Creator();
        frame.setSize(864, 544); 
        frame.add(s);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().addMouseListener(new MouseAdapter() {            
            @Override
            public void mouseClicked(MouseEvent e) {
                int yLocation = e.getX()/32;
                int xLocation = e.getY()/32;
                System.out.println(xLocation + " " + yLocation);

                if(e.getButton() == 1){
                    if(xLocation < 1 || yLocation < 1){
                        Grid[xLocation][yLocation] = 2;
                        System.out.println("Enemy Added");
                    }else if(xLocation > 16 || yLocation > 25){
                        Grid[xLocation][yLocation] = 2;
                        System.out.println("Enemy Added");
                    }else {
                        Grid[xLocation][yLocation] = 1;
                        System.out.println("Obstacle Added");
                    }
                }else {
                    Grid[xLocation][yLocation] = 0;
                    System.out.println("Item Removed");
                }
//                frame.invalidate();
//                frame.validate();
//                frame.repaint();
            }
        });
//        s.setUndecorated(true);
    }
}

frame.setSize(864, 544); 这种写法既不够优化,也是不必要的。请仔细查看被接受的答案,以获得更好的方法。 - Andrew Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接