将多个对象放置在borderlayout的区域中

问题描述 投票:0回答:3

我想在 BorderLayout 的一个区域中放置多个元素。根据各个网站的建议,我对 3 个区域使用了 3 个独立的面板,并在每个面板的不同区域中放置了 2 个元素。然而我没有得到想要的结果。这是我的代码:

public class Trial extends JFrame{
JPanel p1,p2,p3;
JLabel l1,l2,l3,l4,l5,l6;

Trial(){
    p1=new JPanel();
    p2=new JPanel();
    p3=new JPanel();
    l1=new JLabel("Hello");
    l2=new JLabel("Hi");
    l3=new JLabel("Welcome");
    l4=new JLabel("Bye");
    l5=new JLabel("Visit again");
    l6=new JLabel("Thanks");
    p1.add(l1,BorderLayout.NORTH);
    p1.add(l2,BorderLayout.CENTER);
    p2.add(l3,BorderLayout.CENTER);
    p2.add(l4,BorderLayout.SOUTH);
    p3.add(l5,BorderLayout.NORTH);
    p3.add(l6,BorderLayout.SOUTH);
    add(p1,BorderLayout.NORTH);
    add(p2,BorderLayout.CENTER);
    add(p3,BorderLayout.SOUTH);
}
public static void main(String[] args){
    Trial t=new Trial();
    t.setSize(500,500);
    t.setVisible(true);
}
}

有人可以建议我如何纠正吗?

java swing layout-manager
3个回答
2
投票

https://web.archive.org/web/20220120234825/http://java-sl.com/tip_multiple_floatable_toolbars.html

对于具有多个可浮动工具栏的示例,实现了多边框布局。

import javax.swing.*;
import java.awt.Dimension;
import java.awt.*;
import java.util.Vector;
 
public class MultiFloatableToolbar extends JFrame {

    public MultiFloatableToolbar() {
        super("Multiple float toolbars example");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setPreferredSize(new Dimension(360,270));
        getContentPane().setLayout(new MultiBorderLayout(0, 0));
        getContentPane().add(createToolbar(),BorderLayout.NORTH);
        getContentPane().add(createToolbar(),BorderLayout.NORTH);
        getContentPane().add(new JLabel("Center area"),BorderLayout.CENTER);
    }
 
    protected JToolBar createToolbar() {
        JToolBar res= new JToolBar();
        JButton btn1 = new JButton("1");
        JButton btn2 = new JButton("2");
        
        res.add(btn1);
        res.add(btn2);
        
        return res;
    }

 
    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MultiFloatableToolbar frame=new MultiFloatableToolbar();
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }
}
/**
 * Extends BorderLayout with multiple components in the northList, southList, eastList, westList
 * and centerList. Layout is used for correct working multiple toolbars.
 *
 * @author    Stanislav Lapitsky
 * @version   1.0
 */
class MultiBorderLayout extends BorderLayout { 
    /**
     * list of the northList region components
     */
    Vector northList = new Vector();
 
    /**
     * list of the southList region components
     */
    Vector southList = new Vector();
 
    /**
     * list of the westList region components
     */
    Vector westList = new Vector();
 
    /**
     * list of the eastList region components
     */
    Vector eastList = new Vector();
 
    /**
     * list of the centerList region components
     */
    Vector centerList = new Vector();
 
    /**
     * Constructs default layout instance.
     */
    public MultiBorderLayout() {
        super();
    }
 
    /**
     * Constructs new layout instance with defined parameters.
     *
     * @param hgap  the horizontal gap.
     * @param vgap  the vertical gap.
     */
    public MultiBorderLayout(int hgap, int vgap) {
        super(hgap, vgap);
    }
 
    /**
     * Adds the specified component to the layout, using the specified
     * constraint object. For border layouts, the constraint must be one of the
     * following constants: <code>NORTH</code>, <code>SOUTH</code>, <code>EAST</code>
     * , <code>WEST</code>, or <code>CENTER</code>. <p>
     *
     * Most applications do not call this method directly. This method is called
     * when a component is added to a container using the <code>Container.add</code>
     * method with the same argument types.
     *
     * @param name         The feature to be added to the LayoutComponent
     *      attribute.
     * @param comp         the component to be added.
     */
 
    //the method is deprecated but it's necessary to override it because current class extends
    //BorderLayout to provide multiple components (toolbars)
    public void addLayoutComponent(String name, Component comp) {

        synchronized (comp.getTreeLock()) {
            /*
             *  Special case:  treat null the same as "Center".
             */
            if (name == null) {
                name = "Center";
            }
 
            /*
             *  Assign the component to one of the known regions of the layout.
             */
            if ("Center".equals(name)) {
                centerList.add(comp);
            } else if ("North".equals(name)) {
                northList.insertElementAt(comp, 0);
            } else if ("South".equals(name)) {
                southList.add(comp);
            } else if ("East".equals(name)) {
                eastList.add(comp);
            } else if ("West".equals(name)) {
                westList.add(comp);
            } else {
                throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
            }

        }
    }
 
    /**
     * Removes the specified component from this border layout. This method is
     * called when a container calls its <code>remove</code> or <code>removeAll</code>
     * methods. Most applications do not call this method directly.
     *
     * @param comp  the component to be removed.
     */
    public void removeLayoutComponent(Component comp) {
        synchronized (comp.getTreeLock()) {

            southList.remove(comp);
            northList.remove(comp);
            centerList.remove(comp);
            westList.remove(comp);
            eastList.remove(comp);
        }
    }
 
    /**
     * Determines the minimum size of the <code>target</code> container using
     * this layout manager. <p>
     *
     * This method is called when a container calls its <code>getMinimumSize</code>
     * method. Most applications do not call this method directly.
     *
     * @param target  the container in which to do the layout.
     * @return        the minimum dimensions needed to lay out the subcomponents
     *      of the specified container.
     */
    public Dimension minimumLayoutSize(Container target) {
        synchronized (target.getTreeLock()) {
            Dimension dim = new Dimension(0, 0);
 
            Component c;
 
            if (eastList.size() > 0) {
                for (int i = 0; i < eastList.size(); i++) {
                    c = (Component) eastList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getMinimumSize();
                    dim.width += d.width + this.getHgap();
                    dim.height = Math.max(d.height, dim.height);
                }
            }
            if (westList.size() > 0) {
                for (int i = 0; i < westList.size(); i++) {
                    c = (Component) westList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getMinimumSize();
                    dim.width += d.width + this.getHgap();
                    dim.height = Math.max(d.height, dim.height);
                }
            }
            if (centerList.size() > 0) {
                for (int i = 0; i < centerList.size(); i++) {
                    c = (Component) centerList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getMinimumSize();
                    dim.width += d.width;
                    dim.height = Math.max(d.height, dim.height);
                }
            }
            if (northList.size() > 0) {
                for (int i = 0; i < northList.size(); i++) {
                    c = (Component) northList.get(i);
                    if (!c.isVisible()) {

                        continue;
                    }
                    Dimension d = c.getMinimumSize();
                    dim.width = Math.max(d.width, dim.width);
                    dim.height += d.height + this.getVgap();
                }
            }
            if (southList.size() > 0) {
                for (int i = 0; i < southList.size(); i++) {
                    c = (Component) southList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getMinimumSize();
                    dim.width = Math.max(d.width, dim.width);
                    dim.height += d.height + this.getVgap();
                }
            }
 
            Insets insets = target.getInsets();
            dim.width += insets.left + insets.right;
            dim.height += insets.top + insets.bottom;
 
            return dim;
        }

    }
 
    /**
     * Determines the preferred size of the <code>target</code> container using
     * this layout manager, based on the components in the container. <p>
     *
     * Most applications do not call this method directly. This method is called
     * when a container calls its <code>getPreferredSize</code> method.
     *
     * @param target  the container in which to do the layout.
     * @return        the preferred dimensions to lay out the subcomponents of
     *      the specified container.
     */
    public Dimension prefferedLayoutSize(Container target) {
        synchronized (target.getTreeLock()) {
            Dimension dim = new Dimension(0, 0);
 
            Component c;
 
            if (eastList.size() > 0) {
                for (int i = 0; i < eastList.size(); i++) {
                    c = (Component) eastList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    dim.width += d.width + this.getHgap();
                    dim.height = Math.max(d.height, dim.height);
                }
            }

            if (westList.size() > 0) {
                for (int i = 0; i < westList.size(); i++) {
                    c = (Component) westList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    dim.width += d.width + this.getHgap();
                    dim.height = Math.max(d.height, dim.height);
                }
            }

            if (centerList.size() > 0) {
                for (int i = 0; i < centerList.size(); i++) {
                    c = (Component) centerList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    dim.width += d.width;
                    dim.height = Math.max(d.height, dim.height);
                }
            }

            if (northList.size() > 0) {
                for (int i = 0; i < northList.size(); i++) {
                    c = (Component) northList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    dim.width = Math.max(d.width, dim.width);
                    dim.height += d.height + this.getVgap();
                }
            }

            if (southList.size() > 0) {
                for (int i = 0; i < southList.size(); i++) {
                    c = (Component) southList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    dim.width = Math.max(d.width, dim.width);
                    dim.height += d.height + this.getVgap();
                }
            }
 
            Insets insets = target.getInsets();
            dim.width += insets.left + insets.right;
            dim.height += insets.top + insets.bottom;
 
            return dim;
        }
    }
 
    /**
     * Lays out the container argument using this border layout. <p>
     *
     * This method actually reshapes the components in the specified container
     * in order to satisfy the constraints of this <code>BorderLayout</code>
     * object. The <code>NORTH</code> and <code>SOUTH</code> components, if any,
     * are placed at the top and bottom of the container, respectively. The
     * <code>WEST</code> and <code>EAST</code> components are then placed on the
     * left and right, respectively. Finally, the <code>CENTER</code> object is
     * placed in any remaining space in the middle. <p>
     *
     * Most applications do not call this method directly. This method is called
     * when a container calls its <code>doLayout</code> method.
     *
     * @param target  the container in which to do the layout.
     */
    public void layoutContainer(Container target) {
        synchronized (target.getTreeLock()) {
            Insets insets = target.getInsets();
            int top = insets.top;
            int bottom = target.getHeight() - insets.bottom;
            int left = insets.left;
            int right = target.getWidth() - insets.right;
 
            Component c;
 
            if (northList.size() > 0) {
                for (int i = 0; i < northList.size(); i++) {
                    c = (Component) northList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    c.setSize(right - left, d.height);
                    c.setBounds(left, top, right - left, c.getHeight());
                    top += d.height;
                }
            }

            if (southList.size() > 0) {
                for (int i = 0; i < southList.size(); i++) {
                    c = (Component) southList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    c.setSize(right - left, d.height);
                    c.setBounds(left, bottom - d.height, right - left, c.getHeight());
                    bottom -= d.height;
                }
            }

            if (eastList.size() > 0) {
                for (int i = 0; i < eastList.size(); i++) {
                    c = (Component) eastList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    c.setSize(d.width, bottom - top);
                    c.setBounds(right - d.width, top, c.getWidth(), bottom - top);
                    right -= d.width;
                }
            }

            if (westList.size() > 0) {
                for (int i = 0; i < westList.size(); i++) {
                    c = (Component) westList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    Dimension d = c.getPreferredSize();
                    c.setSize(d.width, bottom - top);
                    c.setBounds(left, top, c.getWidth(), bottom - top);
                    left += d.width;
                }
            }

            if (centerList.size() > 0) {
                for (int i = 0; i < centerList.size(); i++) {
                    c = (Component) centerList.get(i);
                    if (!c.isVisible()) {
                        continue;
                    }
                    c.setBounds(left, top, right - left, bottom - top);
                }
            }

        }
    }
}

0
投票

JPanel的默认布局是FlowLayout。 您应该为每个面板设置布局,例如 p1.setLayout(new BorderLayout());

这是代码,希望对你有帮助。

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.*;

public class Trial extends JFrame {
    JPanel p1, p2, p3;
    JLabel l1, l2, l3, l4, l5, l6;

    Trial() {
        p1 = new JPanel();
        p1.setLayout(new BorderLayout());
        p1.setBackground(Color.gray);
        p2 = new JPanel();
        p2.setLayout(new BorderLayout());
        p2.setBackground(Color.yellow);
        p3 = new JPanel();
        p3.setLayout(new BorderLayout());
        p3.setBackground(Color.pink);
        l1 = new JLabel("Hello");
        l2 = new JLabel("Hi");
        l3 = new JLabel("Welcome");
        l4 = new JLabel("Bye");
        l5 = new JLabel("Visit again");
        l6 = new JLabel("Thanks");
        p1.add(l1, BorderLayout.NORTH);
        p1.add(l2, BorderLayout.CENTER);
        p2.add(l3, BorderLayout.CENTER);
        p2.add(l4, BorderLayout.SOUTH);
        p3.add(l5, BorderLayout.NORTH);
        p3.add(l6, BorderLayout.SOUTH);
        add(p1, BorderLayout.NORTH);
        add(p2, BorderLayout.CENTER);
        add(p3, BorderLayout.SOUTH);
    }

    public static void main(String[] args) {
        Trial t = new Trial();
        t.setSize(500, 500);
        t.setVisible(true);
    }
}

效果如下:

enter image description here


0
投票

向 JFrame 添加基础面板。

然后将所有面板添加到基础面板。

我已将所有面板添加到基础面板的南部分。

还提供了颜色供您理解 -

public class Trial extends JFrame{
JPanel p,p1,p2,p3;
JLabel l1,l2,l3,l4,l5,l6;

Trial(){
    p=new JPanel();
    p1=new JPanel();
    p2=new JPanel();
    p3=new JPanel();

    p.setLayout(new BorderLayout());
    p1.setLayout(new BorderLayout());
    p2.setLayout(new BorderLayout());
    p3.setLayout(new BorderLayout());

    p.setBackground(Color.orange);
    p1.setBackground(Color.yellow);
    p2.setBackground(Color.red);
    p3.setBackground(Color.LIGHT_GRAY);

    l1=new JLabel("Hello");
    l2=new JLabel("Hi");
    l3=new JLabel("Welcome");
    l4=new JLabel("Bye");
    l5=new JLabel("Visit again");
    l6=new JLabel("Thanks");
    p1.add(l1,BorderLayout.WEST);
    p1.add(l2,BorderLayout.CENTER);
    p2.add(l3,BorderLayout.EAST);
    p2.add(l4,BorderLayout.SOUTH);
    p3.add(l5,BorderLayout.NORTH);
    p3.add(l6,BorderLayout.SOUTH);

    p.add(p1,BorderLayout.NORTH);
    p.add(p2,BorderLayout.CENTER);
    p.add(p3,BorderLayout.SOUTH);

    add(p,BorderLayout.SOUTH);
}
public static void main(String[] args){
    Trial t=new Trial();
    t.setSize(500,500);
    t.setVisible(true);
}
}

现在您可以看到多个组件放置在边框布局的一个区域(南边)上。

© www.soinside.com 2019 - 2024. All rights reserved.