web-dev-qa-db-fra.com

Pourquoi la méthode setSize () JFrame ne définit-elle pas la taille correctement?

Donc, je programme en Java depuis environ un semestre, et j’ai eu ce problème à quelques reprises et j’ai finalement réussi à demander.

Si je crée une JFrame et que je définis ensuite la taille, comme setSize(400,800) par exemple. Le cadre n'est pas réellement 800 pixels long. D'après ce que je peux dire, cela ressemble en réalité davantage à 770 (or maybe 769) pixels long. De plus, si vous définissez une taille verticale très basse (inférieure à 30), le cadre n'apparaît même pas, seule la barre de la fenêtre supérieure du système d'exploitation et le cadre ne s'agrandissant que lorsque vous passez à une valeur supérieure à 30 (donc setSize(400,0) ressemble à setSize(400,20)). Pourquoi est-ce, ce n'est pas difficile à réparer mais c'est bizarre et je suis curieux de savoir pourquoi?

Si vous avez besoin de plus d’informations sur quelque chose, il suffit de demander et je vous le ferai parvenir. 

16
convergedtarkus

C'est probablement parce que la taille d'un cadre inclut la taille de la bordure.

Un cadre est une fenêtre de niveau supérieur avec un titre et une bordure. La taille du cadre inclut toute zone désignée pour la bordure. Les dimensions de la zone de bordure peuvent être obtenues à l'aide de la méthode getInsets. Étant donné que la zone de bordure est incluse dans la taille globale du cadre, la bordure obscurcit effectivement une partie du cadre, contraignant la zone disponible pour le rendu et/ou l’affichage des sous-composants au rectangle ayant un emplacement en haut à gauche de left, insets.top), et a une taille de largeur - (insets.left + insets.right) par hauteur - (insets.top + insets.bottom). 

Source: http://download.Oracle.com/javase/tutorial/uiswing/components/frame.html

12
Kyle

JFrame SetSize () contient la zone + bordure.

Je pense que vous devez définir la taille de ContentPane de cette

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

Je vous conseillerais donc d’utiliser JPanel intégré dans un cadre JFrame et de vous appuyer sur ce fichier JPanel. Cela minimiserait votre problème.

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

Je lis ceci de Javadoc

La classe JFrame est légèrement incompatible avec Frame. Comme tous les autres conteneurs de niveau supérieur JFC/Swing, un JFrame contient un JRootPane comme son seul enfant . Le volet de contenu fourni par le volet racine doit, en règle générale, contenir tous les composants autres que de menu affichés par le paramètre JFrame. Ceci est différent du cas AWT Frame. Par exemple, pour ajouter un enfant à un cadre AWT, écrivez:

frame.add(child);

Toutefois, si vous utilisez JFrame, vous devez ajouter l'enfant au volet de contenu de JFrame:

frame.getContentPane().add(child);

19
Talha Ahmed Khan

Sous OS X, vous devez prendre en compte les décorations de fenêtre existantes. Ils ajoutent 22 pixels à la hauteur. Donc, sur un JFrame, vous devez dire ceci au programme:

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

Il y a beaucoup de bonnes raisons pour définir la taille d'un cadre. La première consiste à mémoriser la dernière taille définie par l'utilisateur et à restaurer ces paramètres. J'ai ce code qui semble fonctionner pour moi:

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

La bordure supérieure du cadre est de taille 30.Vous pouvez écrire du code pour imprimer la coordonnée de n’importe quel point du cadre à l’aide de MouseInputAdapter.Vous trouverez que lorsque le curseur est juste en dessous du bord supérieur du cadre, la coordonnée y n’est pas nulle, sa près de 30.Si vous donnez la taille au cadre 300 * 300, la taille disponible pour placer les composants sur le cadre n’est que de 300 * 270. Ainsi, si vous devez avoir la taille 300 * 300, donnez une taille de 300 * 330 pour le cadre. .

0
user8295702

Je sais que cette question concerne les plus de 6 ans, mais la réponse de @Kyle ne fonctionne pas.

En utilisant cette

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

Mais cela fonctionne toujours dans n'importe quelle taille:

setSize(width + 14, height + 7);

Si vous ne voulez pas que la bordure se limite, et que vous ne vouliez que la zone blanche, ici:

setSize(width + 16, height + 39);

De plus, cela ne fonctionne que sous Windows 10; pour les utilisateurs de MacOS, utilisez la réponse de @ ben.

0
user7485924