5 votes

Java Swing difficultés de redimensionnement de BorderLayout

Je veux avoir mon écran divisé en deux donc j'ai utilisé un BorderLayout avec des sections East et West. J'ai eu des problèmes de redimensionnement et ici j'ai finalement découvert que la largeur n'est pas modifiée dans les panneaux East et West et la hauteur n'est pas modifiée dans les panneaux Nord et Sud, et les deux sont modifiés dans le panneau Central.

Cependant, je veux que la largeur et la hauteur soient modifiées lors du redimensionnement, et avoir deux panneaux côte à côte. J'ai essayé différents niveaux d'imbrication pour essayer de le faire fonctionner mais je ne pense pas que cela fonctionnera avec BorderLayout.

Il semble que cela devrait être facile pour le gestionnaire de disposition par défaut, mais peut-être que je devrais essayer un agencement différent (par ex. BoxLayout) pour obtenir ce que je veux.

Voici aussi un code qui reproduit le problème dont je parle (essayez de redimensionner la fenêtre):

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main extends JFrame {

    public static void main(String[] args) {
        JFrame window = new Main();
        window.setVisible(true);
    }

    public Main() {
        JButton east = new JButton("East");
        JButton west = new JButton("West");

        JPanel content = new JPanel();
        content.setLayout(new BorderLayout());

        content.add(east, BorderLayout.EAST);
        content.add(west, BorderLayout.WEST);

        setContentPane(content);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }

}

Édit: Je ne veux pas que les deux côtés soient égaux, un ratio d'environ 2:1 est ce que je veux.

8voto

nIcE cOw Points 16890

Ce que vous pouvez utiliser dans votre cas est GridLayout, ici deux JButtons se redimensionneront à mesure que le JFrame se redimensionne.

import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame window = new Main();
                window.setVisible(true);
            }
        });        
    }

    public Main() {
        JButton east = new JButton("Est");
        JButton west = new JButton("Ouest");

        JPanel content = new JPanel();
        content.setLayout(new GridLayout(1, 2));

        content.add(east);
        content.add(west);

        setContentPane(content);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }

}

De plus, il est toujours préférable d'exécuter votre code lié à l'interface graphique à partir de l'EDT - Event Dispatch Thread, et non de le faire depuis le Thread Principal. Consultez Concurrence dans Swing, pour plus d'informations sur le sujet.

DERNIÈRE ÉDITION : Comme demandé dans les commentaires

Utilisez GridBagLayout pour spécifier la taille que vous souhaitez donner

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame window = new Main();
                window.setVisible(true);
            }
        });        
    }

    public Main() {
        JPanel east = new JPanel();
        east.setOpaque(true);
        east.setBackground(Color.WHITE);
        JPanel west = new JPanel();
        west.setOpaque(true);
        west.setBackground(Color.BLUE);

        JPanel content = new JPanel();
        content.setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 0.3;
        gbc.weighty = 1.0;
        gbc.gridx = 0;
        gbc.gridy = 0;

        content.add(east, gbc);
        gbc.weightx = 0.7;
        gbc.gridx = 1;
        content.add(west, gbc);

        setContentPane(content);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }

}

8voto

Branislav Lazic Points 4665

Pourquoi ne pas essayer avec JSplitPane :

import javax.swing.*;
import java.awt.*;

public class AppDemo {

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            JButton eastButton = new JButton("Est");
            JButton westButton = new JButton("Ouest");
            JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, eastButton, westButton);

            JPanel content = new JPanel();
            content.setLayout(new BorderLayout());
            content.add(splitPane, BorderLayout.CENTER);

            frame.setContentPane(content);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.setPreferredSize(new Dimension(500, 400));
            frame.pack();
            frame.setVisible(true);
        });

    }
}

Vous obtiendrez ceci :

description de l'image

1voto

David Faitelson Points 211

Si vous souhaitez conserver votre BorderLayout, vous pouvez utiliser quelque chose comme l'objet suivant :

public class ResizablePanel extends JPanel {

  public ResizablePanel(JComponent body) {

    setLayout(new BorderLayout());
    JButton resize = new JButton();
    resize.setPreferredSize(new Dimension(Integer.MAX_VALUE, 4));
    resize.addMouseMotionListener(new MouseAdapter() {
        public void mouseDragged(MouseEvent e) {
            Dimension preferredSize = ResizablePanel.this.getPreferredSize();
            ResizablePanel.this.setPreferredSize(new Dimension(preferredSize.width, preferredSize.height-e.getY()));
            ResizablePanel.this.revalidate();
        }
    });             
    add(resize, BorderLayout.PAGE_START);
    add(body, BorderLayout.CENTER);
  }
}

Enveloppez maintenant la partie que vous souhaitez redimensionner avec une instance de ResizablePanel et vous pourrez redimensionner en faisant glisser le bouton fin.

Notez que ce code est pour redimensionner la hauteur d'un panneau que vous placez en bas (PAGE_END) d'un border layout, mais il devrait être assez simple de le modifier pour redimensionner la largeur.

0voto

RobB Points 29

Désolé de répondre à un ancien message. Ma solution consiste toujours à utiliser BorderLayout mais à ajouter la ligne suivante après que le composant ait été redimensionné

getLayout().layoutContainer(this);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X