Почему метод setFize () JFrame неправильно устанавливает размер? - PullRequest
17 голосов
/ 06 июля 2011

Итак, я программировал на Java в течение семестра или около того, и у меня была эта проблема несколько раз, и я наконец-то нашел время спросить.

Если я сделаю JFrame, а затем установлю размер, например setSize(400,800). Рамка на самом деле не 800 pixels длинна. Из того, что я могу сказать, это на самом деле больше похоже на 770 (or maybe 769) pixels long. Кроме того, если вы установите очень низкий размер по вертикали (ниже 30), рамка даже не отобразится, только верхняя строка окна ОС и рамка не увеличатся, пока вы не достигнете значения более 30 (так setSize(400,0) выглядит так же, как setSize(400,20)). Почему это не трудно исправить, но это странно, и мне любопытно, почему это так?

Если вам нужна дополнительная информация о чем-либо, просто спросите, и я передам ее вам.

Ответы [ 6 ]

19 голосов
/ 06 июля 2011

JFrame SetSize () содержит область + граница.

Я думаю, вы должны установить размер ContentPane этого

jFrame.getContentPane().setSize(800,400);

Поэтому я бы посоветовал вам использовать JPanel, встроенный в JFrame, и вы опираетесь на этот JPanel. Это уменьшит вашу проблему.

JFrame jf = new JFrame();
JPanel jp = new JPanel();
jp.setPreferredSize(new Dimension(400,800));// changed it to preferredSize, Thanks!
jf.getContentPane().add( jp );// adding to content pane will work here. Please read the comment bellow.
jf.pack();

Я читаю это из Javadoc

Класс JFrame немного несовместим с Frame. Как все другие контейнеры верхнего уровня JFC / Swing, JFrame содержит JRootPane в качестве своего единственный ребенок . панель содержимого предоставляется под корневой панелью следует, как правило, содержит все компоненты, кроме меню отображается JFrame. Это отличается от корпуса AWT Frame. За Например, чтобы добавить ребенка в AWT кадр, который вы напишите:

frame.add(child);

Однако, используя JFrame, вам нужно добавить дочерний элемент к панели содержимого JFrame вместо:

frame.getContentPane().add(child);

13 голосов
/ 06 июля 2011

Вероятно, потому, что размер рамки включает в себя размер границы.

Рамка - это окно верхнего уровня с заголовком и рамкой.Размер рамки включает любую область, предназначенную для границы.Размеры области границы можно получить с помощью метода getInsets.Поскольку область границы включена в общий размер кадра, граница эффективно скрывает часть кадра, ограничивая область, доступную для визуализации и / или отображения подкомпонентов, прямоугольником, который имеет местоположение в верхнем левом углу (вставки.слева, insets.top) и имеет размер ширины - (insets.left + insets.right) по высоте - (insets.top + insets.bottom).

Источник: http://download.oracle.com/javase/tutorial/uiswing/components/frame.html

1 голос
/ 23 мая 2016

В OS X вам необходимо учитывать существующие декорации окон.Они добавляют 22 пикселя к высоте.Итак, на JFrame вы должны сообщить программе следующее:

frame.setSize(width, height + 22);
1 голос
/ 29 мая 2015

Существует множество веских причин для установки размера кадра. Один из них - запомнить последний размер, который пользователь установил, и восстановить эти настройки. У меня есть этот код, который, кажется, работает для меня:

package javatools.swing;
import java.util.prefs.*;
import java.awt.*;
import java.awt.event.*;

import javax.swing.JFrame;

public class FramePositionMemory {
    public static final String WIDTH_PREF = "-width";

    public static final String HEIGHT_PREF = "-height";

    public static final String XPOS_PREF = "-xpos";

    public static final String YPOS_PREF = "-ypos";
    String prefix;
    Window frame;
    Class<?> cls;

    public FramePositionMemory(String prefix, Window frame, Class<?> cls) {
        this.prefix = prefix;
        this.frame = frame;
        this.cls = cls;
    }

    public void loadPosition() {
        Preferences prefs = (Preferences)Preferences.userNodeForPackage(cls);
    //  Restore the most recent mainframe size and location
        int width = prefs.getInt(prefix + WIDTH_PREF, frame.getWidth());
        int height = prefs.getInt(prefix + HEIGHT_PREF, frame.getHeight());
        System.out.println("WID: " + width + " HEI: " + height);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int xpos = (screenSize.width - width) / 2;
        int ypos = (screenSize.height - height) / 2;
        xpos = prefs.getInt(prefix + XPOS_PREF, xpos);
        ypos = prefs.getInt(prefix + YPOS_PREF, ypos);
        frame.setPreferredSize(new Dimension(width, height));
        frame.setLocation(xpos, ypos);
        frame.pack();
    }

    public void storePosition() {
        Preferences prefs = (Preferences)Preferences.userNodeForPackage(cls);
        prefs.putInt(prefix + WIDTH_PREF, frame.getWidth());
        prefs.putInt(prefix + HEIGHT_PREF, frame.getHeight());
        Point loc = frame.getLocation();
        prefs.putInt(prefix + XPOS_PREF, (int)loc.getX());
        prefs.putInt(prefix + YPOS_PREF, (int)loc.getY());
        System.out.println("STORE: " + frame.getWidth() + " " + frame.getHeight() + " " + loc.getX() + " " + loc.getY());
    }
}
public class Main {
void main(String[] args) {
        JFrame frame = new Frame();
        // SET UP YOUR FRAME HERE.
        final FramePositionMemory fm = new FramePositionMemory("scannacs2", frame, Main.class);
        frame.setSize(400, 400); // default size in the absence of previous setting
        fm.loadPosition();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                fm.storePosition();
            }
        });
        frame.setVisible(true);
    }
}

}

0 голосов
/ 12 июля 2018

Верхняя граница рамки имеет размер 30. Вы можете написать код для печати координаты любой точки на рамке с помощью MouseInputAdapter. Вы найдете, когда курсор находится чуть ниже верхней границы рамки, координата y не являетсяноль, это близко к 30. Таким образом, если вы задаете размер кадра 300 * 300, размер, доступный для размещения компонентов на кадре, составляет всего 300 * 270. Поэтому, если вам нужен размер 300 * 300, укажите размер 300 * 330.рамы.

0 голосов
/ 16 февраля 2018

Я знаю, что этому вопросу более 6 лет, но ответ @Kyle не работает.

Использование этого

setSize(width - (getInsets().left + getInsets().right), height - (getInsets().top + getInsets().bottom));

Но это всегда работает в любом размере:

setSize(width + 14, height + 7);

Если вы не хотите, чтобы граница граничила, а хотите только белую область, здесь:

setSize(width + 16, height + 39);

Также это работает только в Windows 10, для пользователей MacOS, используйте ответ @ ben.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...