使用上方/下方的其他组件调整3列通用组件的布局

时间:2016-06-17 09:41:10

标签: java swing user-interface layout-manager null-layout-manager

我正在为课程作业构建一个简单的GUI,但我没有充分利用它。

所以这是我的目标:

我得到了这个(它缺少像按钮这样的元素):

所以问题是,如何将我的布局编码为更紧凑,就像在目标图片中一样?

以下代码:

public class Panel1 extends JPanel{

    private JButton cancel = new JButton("Cancel");

    private JTextArea xTwin = new JTextArea(10, 30);
    private JTextArea xCousin = new JTextArea(10, 30);
    private JTextArea xSexy = new JTextArea(10, 30);
    private JTextField getT = new JTextField(5);
    private JTextField getC= new JTextField(5);
    private JTextField getS = new JTextField(5);

    private JLabel cnstT = new JLabel("How many twin primes do you want?");
    private JLabel cnstC = new JLabel("How many cousin primes do you want?");
    private JLabel cnstS = new JLabel("How many sexy primes do you want?");
    private JLabel msgTwin = new JLabel("Area primes 'twin' created");
    private JLabel msgCousin = new JLabel("Area primes 'cousin' created");
    private JLabel msgSexy = new JLabel("Area primes 'sexy' created");  
    private JLabel msgGUI = new JLabel("GUI created");

    public Panel1(){
        xTwin.setEditable(false);
        xCousin.setEditable(false);
        xSexy.setEditable(false);

        this.setLayout(new GridLayout(3, 1));
        JPanel p1 = new JPanel();
        JPanel p2 = new JPanel();
        JPanel p3 = new JPanel();

        p1.setLayout(new FlowLayout());
        p2.setLayout(new FlowLayout());
        p3.setLayout(new FlowLayout());

        p1.add(cnstT); p1.add(getT); p1.add(cnstC); p1.add(getC);
        p1.add(cnstS); p1.add(getS);
        p2.add(xTwin); p2.add(xCousin); p2.add(xSexy);
        p3.add(msgTwin); p3.add(msgCousin); p3.add(msgSexy);

        add(p1); add(p2); add(p3);
    }

3 个答案:

答案 0 :(得分:3)

以下代码可以帮助您取得进展。

        public Panel1(){
            xTwin.setEditable(false);
            xCousin.setEditable(false);
            xSexy.setEditable(false);

            xTwin.setBorder(new LineBorder(Color.red));
            xCousin.setBorder(new LineBorder(Color.green));
            xSexy.setBorder(new LineBorder(Color.blue));

            this.setLayout(new BorderLayout());
            JPanel panel = new JPanel(new GridLayout(1, 3));
            JPanel buttonPane = new JPanel(new FlowLayout());
            buttonPane.add(cancel);
            this.add(buttonPane,BorderLayout.NORTH);
            this.add(panel,BorderLayout.CENTER);



            JPanel p1 = new JPanel();
            JPanel p2 = new JPanel();
            JPanel p3 = new JPanel();

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

            JPanel twinPanel = new JPanel(new FlowLayout()); 
            twinPanel.add(cnstT);
            twinPanel.add(getT);
            p1.add(twinPanel, BorderLayout.NORTH);
            p1.add(xTwin, BorderLayout.CENTER);
            p1.add(msgTwin, BorderLayout.SOUTH);

            JPanel cousinPanel = new JPanel(new FlowLayout()); 


            cousinPanel.add(cnstC);
            cousinPanel.add(getC);
            p2.add(cousinPanel, BorderLayout.NORTH);
            p2.add(xCousin, BorderLayout.CENTER);
            p2.add(msgCousin, BorderLayout.SOUTH);


            JPanel sexyPanel = new JPanel(new FlowLayout()); 
            sexyPanel.add(cnstS);
            sexyPanel.add(getS);
            p3.add(sexyPanel, BorderLayout.NORTH);
            p3.add(xSexy, BorderLayout.CENTER);
            p3.add(msgSexy, BorderLayout.SOUTH);
            panel.add(p1);
            panel.add(p2);
            panel.add(p3);
        }

这就是结果。(抱歉边框)

enter image description here

答案 1 :(得分:2)

由于面板仅在名称和功能上有所不同,因此请使用strategy pattern(见here)在运行时选择所需的行为。下面的示例说明了enum,其中每个实例都包含一个显示名称和一个取整数并返回一对或整数的函数:Function<Integer, Pair<Integer, Integer>>。使用的实际功能是占位符;您可以替换here所见的方法之一。

image

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.function.Function;
import javafx.util.Pair;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;

/**
 * @see https://stackoverflow.com/a/37885601/230513
 */
public class StrategyTest {

    private enum Kind {
        TWIN((new Function<Integer, Pair<Integer, Integer>>() {
            @Override
            public Pair<Integer, Integer> apply(Integer i) {
                return new Pair<>(i, i + 2);
            }
        })),
        COUSIN((new Function<Integer, Pair<Integer, Integer>>() {
            @Override
            public Pair<Integer, Integer> apply(Integer i) {
                return new Pair<>(i, i + 4);
            }
        })),
        SEXY((new Function<Integer, Pair<Integer, Integer>>() {
            @Override
            public Pair<Integer, Integer> apply(Integer i) {
                return new Pair<>(i, i + 6);
            }
        }));
        String dsiplayName;
        Function<Integer, Pair<Integer, Integer>> function;

        private Kind(Function<Integer, Pair<Integer, Integer>> function) {
            this.dsiplayName = name().toLowerCase();
            this.function = function;
        }
    }

    private JPanel createPanel(Kind kind) {
        JPanel panel = new JPanel(new BorderLayout());
        JSpinner spinner = new JSpinner();
        JPanel top = new JPanel();
        top.add(new JLabel("How many " + kind.dsiplayName + " primes?"));
        top.add(spinner);
        panel.add(top, BorderLayout.PAGE_START);
        JTextArea textArea = new JTextArea(16, 20);
        panel.add(new JScrollPane(textArea));
        panel.add(new JLabel("Area for " + kind.dsiplayName + " primes.",
            JLabel.CENTER), BorderLayout.PAGE_END);
        spinner.addChangeListener((ChangeEvent e) -> {
            int i = (int) spinner.getValue();
            Pair<Integer, Integer> p = kind.function.apply(i);
            textArea.append(p.getKey() + ":" + p.getValue() + "\n");
        });
        return panel;
    }

    private void display() {
        JFrame f = new JFrame("StrategyTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(1, 0, 5, 5));
        for (Kind kind : Kind.values()) {
            f.add(createPanel(kind));
        }
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new StrategyTest()::display);
    }
}

答案 2 :(得分:1)

您的问题位于以下代码行

this.setLayout(new GridLayout(3, 1));

GridLayout 旨在将GUI划分为相同大小的区域,这意味着嵌入式组件不具有其自然大小,例如被拉伸......

使用不同的Layoutmanager代替!有适合您需求的各种变体......

有关Layoutmanagers及其预期功能的更多信息,请访问this website