Java Swing窗口大小与AWT画布结果不匹配

Java Swing窗口大小与AWT画布结果不匹配,java,swing,awt,Java,Swing,Awt,我想在JPanel中绘制一个宽度和高度分别为原始窗口80%和80%的矩形 这是我的驾驶课 public class driver { public static void main(String[] args) { System.out.println("test"); Window myWindow = new Window(); myWindow.add(new GraphPanel()); myWindow.setti

我想在JPanel中绘制一个宽度和高度分别为原始窗口80%和80%的矩形

这是我的驾驶课

public class driver {
    public static void main(String[] args) {
        System.out.println("test");
        Window myWindow = new Window();
        myWindow.add(new GraphPanel());
        myWindow.settings();
    }
}
这是我的JPanel:

import javax.swing.*;

public class Window extends JFrame {

    private static final int width = 1100;
    private static final int height = 600;

    public void settings(){
        setSize(width,height);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static int[] getWindowSize(){
        int[] output = new int[]{width, height};
        return output;
    }
}
矩形画布:

import java.awt.*;

public class GraphPanel extends Canvas {
    public void paint(Graphics g){
        setBackground(Color.WHITE);
        setForeground(Color.DARK_GRAY);

        int[] windowSize = Window.getWindowSize();

        //Not working as intented
        g.drawRect(windowSize[0]/10, windowSize[1]/10, 8*windowSize[0]/10, 8*windowSize[1]/10);
    }
}
这是结果, 我不能发布图片,所以这里有一个链接


如您所见,这显然没有居中,高度偏移约30像素,宽度偏移约20像素。我不知道这是怎么发生的,所以我的问题是,有人知道这可能是什么原因吗?

您可能希望从快速阅读开始,以更好地了解当前方法不起作用的原因(您期望的方式)

我要做的第一件事是更改
图形面板
,使其定义为
首选大小
,与窗口无关。通过这种方式,您可以将控制权交给布局管理系统

接下来,我将使用组件的实际物理大小作为计算的基础

int width = (int) (getWidth() * 0.8);
int height = (int) (getHeight() * 0.8);
我还建议将
setBackground
setBackground
移出
paint
方法。这将导致一个新的疼痛周期发生,并将把事情搞得一团糟

public class GraphPanel extends Canvas {

    private static final int PREF_WIDTH = 1100;
    private static final int PREF_HEIGHT = 600;

    public GraphPanel() {
        setBackground(Color.WHITE);
        setBackground(Color.DARK_GRAY);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(PREF_WIDTH, PREF_HEIGHT);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        int width = (int) (getWidth() * 0.8);
        int height = (int) (getHeight() * 0.8);

        int x = (getWidth() - width) / 2;
        int y = (getHeight() - height) / 2;

        //Not working as intented
        g.drawRect(x, y, width, height);
    }
}
然后我会更新您的
窗口
类,使其使用
pack
而不是
setSize
。这将“包装”窗口周围的内容,考虑到框架装饰

public class Window extends JFrame {

    public void settings() {
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
虽然我怀疑从
JFrame
扩展的意义,但我已经了解了这个主题


说到这里,除非您打算使用高性能图形,这需要您完全控制绘画子系统,否则我建议您从基于Swing的组件开始,甚至从JavaFX开始,您可能希望快速阅读,以更好地理解当前方法不起作用的原因(你期望的方式)

我要做的第一件事是更改您的
图形面板
,使其定义为
首选大小
,与窗口无关。这样您就可以将控制权交给布局管理系统

接下来,我将使用组件的实际物理大小作为计算的基础

int width = (int) (getWidth() * 0.8);
int height = (int) (getHeight() * 0.8);
我还建议将
setBackground
setBackground
移出
paint
方法。这将导致新的疼痛周期发生,并将事情搞得一团糟

public class GraphPanel extends Canvas {

    private static final int PREF_WIDTH = 1100;
    private static final int PREF_HEIGHT = 600;

    public GraphPanel() {
        setBackground(Color.WHITE);
        setBackground(Color.DARK_GRAY);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(PREF_WIDTH, PREF_HEIGHT);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        int width = (int) (getWidth() * 0.8);
        int height = (int) (getHeight() * 0.8);

        int x = (getWidth() - width) / 2;
        int y = (getHeight() - height) / 2;

        //Not working as intented
        g.drawRect(x, y, width, height);
    }
}
然后我会更新您的
窗口
类,使其使用
pack
而不是
setSize
。考虑到框架装饰,这将在内容周围“打包”窗口

public class Window extends JFrame {

    public void settings() {
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
虽然我怀疑从
JFrame
扩展的意义,但我已经了解了这个主题


说到这里,除非您打算使用高性能图形,而这需要您完全控制绘制子系统,否则我建议您从基于Swing的组件开始,甚至从JavaFX开始“绘制一个与原始窗口宽度和高度分别为80%和80%的矩形”为什么?或者更确切地说,为什么是窗口,而不是绘画区域?这对最终用户来说应该实现什么?我只是为了一些个人项目尝试swing,所以没有什么可以实现的,我假设“绘制一个宽度为原始窗口的80%,高度为80%的矩形”为什么?或者更确切地说,为什么是窗口,而不是绘画区域?这对最终用户来说应该实现什么?我只是为了一些个人项目尝试swing,所以我认为没有什么可以实现的