JFrame 最大化时调整 JPanel 的大小
Resizing JPanel when JFrame is maximized
好的,下面的代码显示了程序首次运行时 JFrame 中的 JPanel。如果 window 通过拖动框架的一侧或角来调整大小,则 JPanel 会自行调整大小并保持显示器的纵横比。
注意: JPanel 仅在分辨率为 1920x1080 的显示器上设置为保持在 window 的范围内。在任何其他显示器尺寸上,JPanel 可能会被切断。请参阅我在 updatePanelSize() 方法中的 setPreferredSize() 上方的评论。
public class Frame extends JFrame {
Panel panel = new Panel();
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Frame();
}
});
}
// Setup the window, add the panel, and initialize a "window" listener.
public Frame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1280, 720);
setLocationRelativeTo(null);
setVisible(true);
setTitle("Frame");
setLayout(new GridBagLayout());
add(panel);
initListeners();
}
public void initListeners() {
/** When the window is resized, the panel size is updated. */
addComponentListener(new ComponentListener() {
@Override
public void componentResized(ComponentEvent e) {
panel.updatePanelSize();
}
@Override
public void componentHidden(ComponentEvent evt) {}
@Override
public void componentShown(ComponentEvent evt) {}
@Override
public void componentMoved(ComponentEvent evt) {}
});
}
}
public class Panel extends JPanel {
public Panel() {
setBackground(new Color(100, 0, 0));
setPreferredSize(new Dimension(1052, 592));
}
// Resizes the JPanel while maintaining the same aspect ratio
// of the monitor.
public void updatePanelSize() {
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
float monitorWidth = gd.getDisplayMode().getWidth();
float monitorHeight = gd.getDisplayMode().getHeight();
// Aspect ratio of the monitor in decimal form.
float monitorRatio = monitorWidth / monitorHeight;
JComponent parent = (JComponent) getParent();
float width = parent.getWidth();
float height = parent.getHeight();
width = Math.min(width, height * monitorRatio);
height = width / monitorRatio;
// I am subtracting the width and height by their respected aspect ratio
// coefficients (1920x1080 -> 16:9 (width:height)) and multiplying them
// by some scale (in this case 10) to add a "padding" to the JPanel.
// The ratio coefficients and scale will need to be edited based upon the
// resolution of your monitor.
setPreferredSize(new Dimension((int)width - (16 * 10), (int)height - (9 * 10)));
System.out.println("PanelRes: " + ((int)width - (16 * 10)) + "x" + ((int)height - (9 * 10)));
System.out.println("PanelRatio: " + getWidth() / getHeight());
}
}
我遇到的问题是,如果我通过双击 window 工具栏(或 window 顶部的任何正确术语)最大化 window或者通过单击最大化按钮,JPanel 不会像它应该的那样重新调整大小。当 window 最大化但 JPanel 未调整大小时,将调用覆盖的 componentResized() 方法。任何解决此问题的帮助都会很棒。
调整大小时,面板立即接受 updatePanelSize()
中的新首选尺寸,但 maximize/restore 面板显然忽略了新的首选尺寸。
我添加了对 revalidate()
的调用,以强制面板在未应用新的首选尺寸的情况下进行更新。
public void updatePanelSize() {
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice();
float monitorWidth = gd.getDisplayMode().getWidth();
float monitorHeight = gd.getDisplayMode().getHeight();
// Aspect ratio of the monitor in decimal form.
float monitorRatio = monitorWidth / monitorHeight;
JComponent parent = (JComponent) getParent();
float width = parent.getWidth();
float height = parent.getHeight();
width = Math.min(width, height * monitorRatio);
height = width / monitorRatio;
// I am subtracting the width and height by their respective aspect ratio...
int paddedWidth = (int) width - (16 * 10);
int paddedHeight = (int) height - (9 * 10);
setPreferredSize(new Dimension(paddedWidth, paddedHeight));
int resultWidth = getWidth();
int resultHeight = getHeight();
if (paddedWidth != resultWidth && paddedHeight != resultHeight) {
revalidate(); // preferred dimensions not applied, so force them
}
System.out.println("PreferredSize: " + paddedWidth + "x" + paddedHeight);
System.out.println("PanelRes: " + resultWidth + "x" + resultHeight);
System.out.println("PanelRatio: " + (float)resultWidth / resultHeight);
}
好的,下面的代码显示了程序首次运行时 JFrame 中的 JPanel。如果 window 通过拖动框架的一侧或角来调整大小,则 JPanel 会自行调整大小并保持显示器的纵横比。
注意: JPanel 仅在分辨率为 1920x1080 的显示器上设置为保持在 window 的范围内。在任何其他显示器尺寸上,JPanel 可能会被切断。请参阅我在 updatePanelSize() 方法中的 setPreferredSize() 上方的评论。
public class Frame extends JFrame {
Panel panel = new Panel();
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Frame();
}
});
}
// Setup the window, add the panel, and initialize a "window" listener.
public Frame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1280, 720);
setLocationRelativeTo(null);
setVisible(true);
setTitle("Frame");
setLayout(new GridBagLayout());
add(panel);
initListeners();
}
public void initListeners() {
/** When the window is resized, the panel size is updated. */
addComponentListener(new ComponentListener() {
@Override
public void componentResized(ComponentEvent e) {
panel.updatePanelSize();
}
@Override
public void componentHidden(ComponentEvent evt) {}
@Override
public void componentShown(ComponentEvent evt) {}
@Override
public void componentMoved(ComponentEvent evt) {}
});
}
}
public class Panel extends JPanel {
public Panel() {
setBackground(new Color(100, 0, 0));
setPreferredSize(new Dimension(1052, 592));
}
// Resizes the JPanel while maintaining the same aspect ratio
// of the monitor.
public void updatePanelSize() {
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
float monitorWidth = gd.getDisplayMode().getWidth();
float monitorHeight = gd.getDisplayMode().getHeight();
// Aspect ratio of the monitor in decimal form.
float monitorRatio = monitorWidth / monitorHeight;
JComponent parent = (JComponent) getParent();
float width = parent.getWidth();
float height = parent.getHeight();
width = Math.min(width, height * monitorRatio);
height = width / monitorRatio;
// I am subtracting the width and height by their respected aspect ratio
// coefficients (1920x1080 -> 16:9 (width:height)) and multiplying them
// by some scale (in this case 10) to add a "padding" to the JPanel.
// The ratio coefficients and scale will need to be edited based upon the
// resolution of your monitor.
setPreferredSize(new Dimension((int)width - (16 * 10), (int)height - (9 * 10)));
System.out.println("PanelRes: " + ((int)width - (16 * 10)) + "x" + ((int)height - (9 * 10)));
System.out.println("PanelRatio: " + getWidth() / getHeight());
}
}
我遇到的问题是,如果我通过双击 window 工具栏(或 window 顶部的任何正确术语)最大化 window或者通过单击最大化按钮,JPanel 不会像它应该的那样重新调整大小。当 window 最大化但 JPanel 未调整大小时,将调用覆盖的 componentResized() 方法。任何解决此问题的帮助都会很棒。
调整大小时,面板立即接受 updatePanelSize()
中的新首选尺寸,但 maximize/restore 面板显然忽略了新的首选尺寸。
我添加了对 revalidate()
的调用,以强制面板在未应用新的首选尺寸的情况下进行更新。
public void updatePanelSize() {
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice();
float monitorWidth = gd.getDisplayMode().getWidth();
float monitorHeight = gd.getDisplayMode().getHeight();
// Aspect ratio of the monitor in decimal form.
float monitorRatio = monitorWidth / monitorHeight;
JComponent parent = (JComponent) getParent();
float width = parent.getWidth();
float height = parent.getHeight();
width = Math.min(width, height * monitorRatio);
height = width / monitorRatio;
// I am subtracting the width and height by their respective aspect ratio...
int paddedWidth = (int) width - (16 * 10);
int paddedHeight = (int) height - (9 * 10);
setPreferredSize(new Dimension(paddedWidth, paddedHeight));
int resultWidth = getWidth();
int resultHeight = getHeight();
if (paddedWidth != resultWidth && paddedHeight != resultHeight) {
revalidate(); // preferred dimensions not applied, so force them
}
System.out.println("PreferredSize: " + paddedWidth + "x" + paddedHeight);
System.out.println("PanelRes: " + resultWidth + "x" + resultHeight);
System.out.println("PanelRatio: " + (float)resultWidth / resultHeight);
}