使用布局管理器

时间:2014-09-28 01:13:39

标签: java swing jpanel layout-manager

我正在尝试使用FlowLayout制作厨房显示系统,我试图想办法在第一行已满时在第二行添加另一个面板。 GUI的宽度将根据用户偏好而改变。当更宽时,它应该显示每行更多的组件。

enter image description here

2 个答案:

答案 0 :(得分:2)

您可以使用FlowLayout。从教程How to Use FlowLayout

  

FlowLayout类将组件放在一行中,大小按其首选大小排列。如果容器中的水平空间太小而无法将所有组件放在一行中,则FlowLayout类将使用多行。如果容器比一行组件所需的宽,则默认情况下,该行在容器内水平居中。

编辑如果您希望布局在行数太多时垂直滚动,则可以使用禁用水平滚动的JScrollPane。你可以用:

来做到这一点
js.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

(其中js是包含JScrollPane面板的FlowLayout

编辑2 嗯,以上情况还不够。您还需要在将跟踪JScrollPane宽度的JScrollPane上设置视口视图。这是一个执行此操作的类(取自here):

static class MyPanel extends JPanel implements Scrollable{

    @Override
    public Dimension getPreferredScrollableViewportSize() {

        return this.getPreferredSize();
    }

    @Override
    public int getScrollableUnitIncrement(Rectangle visibleRect,
            int orientation, int direction) {
        return 50;
    }

    @Override
    public int getScrollableBlockIncrement(Rectangle visibleRect,
            int orientation, int direction) {
        return 80;
    }

    /*
     * (non-Javadoc)
     * @see javax.swing.Scrollable#getScrollableTracksViewportWidth()
     */
    @Override
    public boolean getScrollableTracksViewportWidth() {
        return true;
    }

    @Override
    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

}

您可以通过将当前FlowLayout布局添加到MyPanel的实例(而不是直接添加到JScrollPane)然后调用

来使用此功能
js.setViewportView(myPanelInstance);

答案 1 :(得分:2)

方法 - WrapLayout

的可变宽度

GridLayout解决方案假设GUI每行需要 6个组件。

根据需要填充宽度的cols,&然后根据需要在尽可能多的行中显示组件,请查看 WrapLayout

enter image description here enter image description here

方法 - JList

的可变宽度

这里也可以使用JList,因为它似乎所有组件都由一个(GUI)对象组成。

enter image description here enter image description here

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.*;

public class ListComponents {

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                String[] listData = {
                    "Component 1", "Component 2", "Component 3",};
                final DefaultListModel<String> model
                        = new DefaultListModel<String>();
                for (String datum : listData) {
                    model.addElement(datum);
                }
                JList list = new JList(model);
                list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
                list.setVisibleRowCount(-1);
                list.setCellRenderer(new ObjectCellRenderer());

                Action addAction = new AbstractAction("Add New") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        model.addElement("New Component");
                    }
                };
                JButton addNew = new JButton(addAction);

                JPanel ui = new JPanel(new BorderLayout(3, 3));
                ui.setBorder(new EmptyBorder(4, 4, 4, 4));
                ui.add(new JScrollPane(list), BorderLayout.CENTER);

                ui.add(addNew, BorderLayout.PAGE_START);

                JFrame f = new JFrame("Component List");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setContentPane(ui);
                f.pack();
                f.setLocationByPlatform(true);
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }

}

class ObjectCellRenderer extends DefaultListCellRenderer {

    Border border = new EmptyBorder(20, 5, 20, 5);

    public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus) {
        JLabel label = (JLabel) super.getListCellRendererComponent(
                list, value, index, isSelected, cellHasFocus);
        label.setBorder(border);
        return label;
    }
}

方法 - 使用GridLayout

修正宽度

使用GridLayout,当我们知道时,无论宽度如何,我们总是希望每行都有固定的数字。

JPanel mainPanel = new JPanel(new GridLayout(0,6));

请参阅new GridLayout(rows,cols)

  

创建具有指定行数和列数的网格布局。布局中的所有组件都具有相同的大小。

     

行和列中的一个,但不是两个都可以为零,,这意味着任意数量的对象都可以放在一行或一列中。

有关使用GridLayout(0,2)作为添加另一个标签

下方标签的示例,请参阅this code