使用BoxLayout,如何使组件填充所有可用的水平宽度?

6
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.HeadlessException;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/**
 * @author dah01
 */
public class Main {
    private static int panelNumber = 1;
    public static final String fillerText = ""
            + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec "
            + "placerat aliquam magna, in faucibus ante pharetra porta. "
            + "Vestibulum ante ipsum primis in faucibus orci luctus et ultrices "
            + "posuere cubilia Curae; Quisque eu dui ligula. Donec consequat "
            + "fringilla enim eu tempus. Ut pharetra velit id sapien vehicula "
            + "scelerisque. Proin sit amet tellus enim, et gravida dui. Ut "
            + "laoreet tristique tincidunt. Integer pharetra pulvinar neque id "
            + "dignissim. Praesent gravida dapibus ornare. Aenean facilisis "
            + "consectetur tincidunt. Donec ante tellus, vehicula vitae "
            + "ultrices eget, scelerisque cursus turpis. Quisque volutpat odio "
            + "sed risus posuere adipiscing. In pharetra elit id risus ornare "
            + "ut bibendum orci luctus. In sollicitudin gravida neque quis "
            + "lobortis. Morbi id justo enim. Aliquam eget orci lorem.";
    public static void main(String[] args) {
        JPanel innerPanelOne = getPanel();

        //SECOND PANEL
        JPanel innerPanelTwo = getPanel();

        //MIDDLE PANEL
        JPanel middlePanel = new JPanel();
        middlePanel.setBackground(Color.RED);
        middlePanel.setLayout(new BoxLayout(middlePanel, BoxLayout.PAGE_AXIS));
        middlePanel.add(innerPanelOne);
        middlePanel.add(innerPanelTwo);

        //OUTER PANEL
        JPanel outerPanel = new JPanel();
        outerPanel.setBackground(Color.BLUE);
        outerPanel.add(middlePanel);

        createAndShowGUI(outerPanel);
    }

    private static void createAndShowGUI(JPanel outerPanel) throws HeadlessException {
        //FRAME
        JFrame frame = new JFrame();
        frame.setContentPane(outerPanel);
        frame.setSize(500, 500);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private static JPanel getPanel() {
        //TEXT AREA
        JTextArea t = new JTextArea(fillerText);
        t.setWrapStyleWord(true);
        t.setLineWrap(true);


        //Scroll
        JScrollPane scrollOne = new JScrollPane();
        scrollOne.setViewportView(t);

        //Label
        JLabel l = new JLabel("LABEL " +panelNumber++);
        //FIRST PANEL
        JPanel p = new JPanel();
        p.setLayout(new BorderLayout());
        p.setBackground(Color.GREEN);
        p.add(l,BorderLayout.NORTH);
        p.add(scrollOne,BorderLayout.SOUTH);

        t.setMaximumSize(new Dimension(1920,1080));
        p.setMaximumSize(new Dimension(1920,1080));
        l.setMaximumSize(new Dimension(1920,1080));
        return p;
    }
}

编辑:

package com.protocase.notes.views;

import com.protocase.notes.controller.NotesController;
import com.protocase.notes.model.Note;
import com.protocase.notes.model.User;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.BevelBorder;

/**
 * @author dah01
 */
public class NotesPanel extends JPanel {

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setSize(500, 500);
        Note note = new Note();
        User u = new User();
        note.setCreator(u);
        note.setLastEdited(u);
        note.setDateCreated(new Date());
        JPanel panel = new JPanel();
        panel.add(new NotesPanel(note, null));
        panel.add(new NotesPanel(note, null));
        panel.setBackground(Color.red);

        panel.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
        f.setContentPane(panel);
        f.setVisible(true);
    }
    // <editor-fold defaultstate="collapsed" desc="Attributes">
    private Note note;
    private NotesController controller;
    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Getters N' Setters">

    public NotesController getController() {
        return controller;
    }

    public void setController(NotesController controller) {
        this.controller = controller;
    }

    public Note getNote() {
        return note;
    }

    public void setNote(Note note) {
        this.note = note;
    }
    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Constructor">

    /**
     * Sets up a note panel that shows everything about the note.
     * @param note 
     */
    public NotesPanel(Note note, NotesController controller) {
        // -- Setup the layout manager.
        this.setBackground(new Color(199, 187, 192));
        this.setLayout(new GridBagLayout());
        this.setBorder(new BevelBorder(BevelBorder.RAISED));
        GridBagConstraints c = new GridBagConstraints();

        // -- Setup the creator section.
        JLabel creatorLabel = new JLabel("Note by " + note.getCreator() + " @ " + note.getDateCreated());
        creatorLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
        c.fill = GridBagConstraints.HORIZONTAL;

        c.gridy = 0;
        c.weightx = 1;
        c.weighty = 0.3;
        this.add(creatorLabel, c);

        // -- Setup the notes area.
        JTextArea notesContentsArea = new JTextArea(note.getContents());
        notesContentsArea.setEditable(false);
        notesContentsArea.setLineWrap(true);
        notesContentsArea.setWrapStyleWord(true);



        JScrollPane scrollPane = new JScrollPane(notesContentsArea);
        scrollPane.setAlignmentX(JScrollPane.LEFT_ALIGNMENT);


        c.gridy = 1;


        this.add(scrollPane, c);

        // -- Setup the edited by label.
        JLabel editorLabel = new JLabel(" -- Last edited by " + note.getLastEdited() + " at " + note.getDateModified());
        editorLabel.setAlignmentX(Component.LEFT_ALIGNMENT);


        c.gridy = 2;


        this.add(editorLabel, c);

        // -- Add everything to the view.

        this.setBackground(Color.yellow);
        //this.add(creatorLabel);
        //this.add(scrollPane);
        //this.add(editorLabel);
    }
    //</editor-fold>

    @Override
    public Dimension getPreferredSize() {
        Dimension d = super.getPreferredSize();
        d.width = this.getParent().getSize().width;
        return d;
    }

}
4个回答

11

如果容器想要强制其组件与其宽度匹配,除非你需要使用BoxLayout,否则有许多更好的替代方案。其中一个是标准的GridBagLayout。给定一个容器panel和三个组件abc,代码如下:

panel.setLayout(new GridBagLayout());
GridBagConstraints cons = new GridBagConstraints();
cons.fill = GridBagConstraints.HORIZONTAL;
cons.weightx = 1;
cons.gridx = 0;

panel.add(a, cons);
panel.add(b, cons);
panel.add(c, cons);

如果组件想要匹配其容器的宽度 - 这通常不是一个好主意,我会改为编写组件构造函数以接收对容器的引用,并重写 getPreferredSize 方法来基于传入的组件进行计算。但是,布局几乎总是由父容器负责。


3
由于BoxLayout是由组件的首选大小指导的,因此您可以使用以下方法:
JPanel middlePanel = new JPanel() {
   public Dimension getPreferredSize() {
       return outerPanel.getSize();
   };
};

获取父元素的尺寸。

1
嗯...没有深入研究,但通常是不行的:返回大小提示的方法的合同是返回_自己_计算的XXHint,独立于父级/内容。 - kleopatra
3
也许最理想的做法是使用另一个布局管理器来计算可用的最大尺寸。 - Reimeus

0
一个对我来说很好的解决方法是使用SpringLayout
只需使用Oracle的模板来帮助您使用此布局即可。
之后,您只需要添加组件(无需约束),并调用此代码:
SpringUtilities.makeCompactGrid(yourPanel, x, 1, 0, 0, 0, 0);
// x stands for rowCount. Zeros are margins.

0

BoxLayout使用方法文档中提到:

如果所有组件具有相同的X对齐方式,则所有组件将被设置为与其容器一样宽。

因此,在使用BoxLayout时,只需将所有组件设置为相同的X对齐方式即可:

        c1.setAlignmentX(Component.CENTER_ALIGNMENT)
        c2.setAlignmentX(Component.CENTER_ALIGNMENT)
        ...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接