it-swarm.com.ru

Почему метод setFize () JFrame неправильно устанавливает размер?

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

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

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

16
convergedtarkus

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

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

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

12
Kyle

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 в качестве своего только ребенок. Предоставляется панель content На корневой панели следует, как правило, содержит все компоненты, не относящиеся к меню отображается JFrame. Это отличается от корпуса AWT Frame. За Например, чтобы добавить ребенка в AWT кадр вы бы написали:

frame.add(child);

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

frame.getContentPane().add(child);

19
Talha Ahmed Khan

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

frame.setSize(width, height + 22);
1
ben

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

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);
    }
}

}

1
user2709454

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

0
user8295702

Я знаю, что этому вопросу более 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.

0
user7485924