Я делаю игру в java, и мне нужно выяснить, как изменить размер JFrame относительно максимального размера. После чтения Hovercraft, полного ответов Eel и игры с ним, я обновил код. Это должно быть минимальным, полное и поддающееся проверке пример:Как изменить размер JFrame относительно максимального размера
import java.awt.Dimension;
import javax.swing.*;
import java.awt.Toolkit;
import java.lang.reflect.InvocationTargetException;
public class MyFrameTest {
JFrame frame;
public static void main(String[] args) {
new MyFrameTest();
}
public MyFrameTest() {
System.out.println("screenSize: " + Toolkit.getDefaultToolkit().getScreenSize());
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
});
}
catch (Exception e) { System.out.println("invokeAndWait exception: "+e); }
set_size(300,300);
set_size(500,500);
set_size(0,0);
set_size(0,0);
set_size(500,500);
set_size(0,0);
set_size(0,0);
System.exit(0);
}
public void set_size(int width, int height) {
final Dimension d = new Dimension(width, height);
final int w = width;
final int h = height;
try { Thread.sleep(500); } catch (InterruptedException e) { }
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
if (w == 0 && h == 0) {
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
} else {
frame.setExtendedState(JFrame.NORMAL);
frame.setSize(d);
}
displaySize(frame, w, h);
}
});
} catch (Exception e) { System.out.println("invokeAndWait exception: "+e); }
}
public void displaySize(JFrame frame, int width, int height) {
Dimension df = frame.getSize();
Dimension dc = frame.getContentPane().getSize();
if (width == 0 && height == 0)
System.out.printf("Size maximized : Frame %4d,%-4d : Content %4d,%-4d\n",
df.width, df.height, dc.width, dc.height);
else
System.out.printf("Size %4d,%-4d : Frame %4d,%-4d : Content %4d,%-4d\n",
width, height, df.width, df.height, dc.width, dc.height);
}
}
Я разрабатываю на Linux, и это выход я получаю:
screenSize: java.awt.Dimension[width=1920,height=1080]
Size 300,300 : Frame 300,300 : Content 2,1
Size 500,500 : Frame 500,500 : Content 292,270
Size maximized : Frame 500,500 : Content 492,470
Size maximized : Frame 1928,1033 : Content 1920,1003
Size 500,500 : Frame 500,500 : Content 1920,1003
Size maximized : Frame 500,500 : Content 492,470
Size maximized : Frame 1928,1033 : Content 1920,1003
Когда я поставил его в не развернутом размера, размер фрейма правильный, но если я сделаю его максимально, то в первый раз, когда я проверю размер кадра, он не показывает разницы. Он отображается только во второй раз, когда я его установил и запросил.
Жутко, если установить его в два раза подряд, как этот
if (w == 0 && h == 0) {
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
} else {
тогда он никогда не обновляет размер кадра независимо от того, сколько раз я его назвал. Если я установил его три раза подряд, это сработает. Может быть, это переключение?
Даже более странный размер ContentPane отстает от размера фрейма, что означает, что он удваивает максимальный размер двумя попытками.
Во время игры с программой мне удалось получить одну комбинацию, которая вела себя случайным образом при последовательных прогонах, иногда она обновляется немедленно, а иногда и нет. Это заставляет меня думать, может быть, в EDT происходит процесс синхронизации потоков, возможно, это ленивое обновление, но добавление более длинного сна не помогает.
В Windows вывод:
screenSize: java.awt.Dimension[width=1600,height=900]
Size 300,300 : Frame 300,300 : Content 116,0
Size 500,500 : Frame 500,500 : Content 284,262
Size maximized : Frame 1616,854 : Content 484,462
Size maximized : Frame 1616,854 : Content 1600,816
Size 500,500 : Frame 500,500 : Content 1600,816
Size maximized : Frame 1616,854 : Content 484,462
Size maximized : Frame 1616,854 : Content 1600,816
Здесь размер JFrame правильно, но ContentPane все еще отстает от кадра.
Я попытался это, но теперь GETSIZE() возвращает -10 и GetPreferredSize возвращает 0 еще – mooncat39
@ mooncat39: смотри пример выше. Обратите внимание, что preferredSize не имеет никакого отношения к размеру рендеринга, и все это связано с добавленными компонентами и менеджерами макетов. –
Я тоже это пробовал, но получил тот же результат: 'After Rendering' ' Размер: java.awt.Dimension [width = -10, height = -30] ' – mooncat39