Java Swing window 大小与 AWT canvas 结果不匹配
Java Swing window size does not match AWT canvas result
我想在 JPanel 中绘制一个宽度为原始 window 的 80% 和高度为 80% 的矩形。
这是我的 driver class
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;
}
}
和矩形 canvas:
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);
}
}
这是结果,
我不能 post 图片所以这里是 link
https://i.imgur.com/6D1gEF7.png
如您所见,这显然没有居中,高度偏移了大约 30 像素,宽度偏移了大约 20 像素。我不知道这是怎么发生的,所以我的问题是,有人知道是什么原因造成的吗?
您可能想先快速阅读 this 以更好地理解为什么您当前的方法行不通(您期望的方式)。
我要做的第一件事是更改 GraphPanel
,使其定义为 preferredSize
,独立于 window。这样您就可以将控制权交给布局管理系统。
接下来,我将使用组件的实际物理尺寸作为您计算的基础
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);
}
}
然后我会更新你的 Window
class 所以它使用 pack
而不是 setSize
。考虑到框架装饰,这将 "pack" window 围绕内容。
public class Window extends JFrame {
public void settings() {
pack();
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
虽然,我质疑从 JFrame
延伸的意义,但我正在进入主题。
说到这一点,除非您打算制作需要您完全控制绘画子系统的高性能图形,否则我建议您从基于 Swing 的组件甚至 JavaFX 开始
我想在 JPanel 中绘制一个宽度为原始 window 的 80% 和高度为 80% 的矩形。
这是我的 driver class
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;
}
}
和矩形 canvas:
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);
}
}
这是结果, 我不能 post 图片所以这里是 link https://i.imgur.com/6D1gEF7.png
如您所见,这显然没有居中,高度偏移了大约 30 像素,宽度偏移了大约 20 像素。我不知道这是怎么发生的,所以我的问题是,有人知道是什么原因造成的吗?
您可能想先快速阅读 this 以更好地理解为什么您当前的方法行不通(您期望的方式)。
我要做的第一件事是更改 GraphPanel
,使其定义为 preferredSize
,独立于 window。这样您就可以将控制权交给布局管理系统。
接下来,我将使用组件的实际物理尺寸作为您计算的基础
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);
}
}
然后我会更新你的 Window
class 所以它使用 pack
而不是 setSize
。考虑到框架装饰,这将 "pack" window 围绕内容。
public class Window extends JFrame {
public void settings() {
pack();
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
虽然,我质疑从 JFrame
延伸的意义,但我正在进入主题。
说到这一点,除非您打算制作需要您完全控制绘画子系统的高性能图形,否则我建议您从基于 Swing 的组件甚至 JavaFX 开始