调整 3 列通用组件与其他组件的布局 above/below

Adjust layout for 3 columns of common components with other components above/below

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

所以这是我的 objective:

我得到了这个(它缺少一些元素,比如按钮):

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

代码如下:

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);
    }

下面的代码应该可以帮助你进步。

        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);
        }

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

您的问题出在以下代码行

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

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

改用其他 Layoutmanager!有多种变体适合您的需求...

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

由于面板仅在名称和功能上有所不同,因此请使用 strategy pattern, seen , to select the desired behavior at runtime. The example below illustrates an enum, each instance of which holds a display name and a function that takes an integer and returns a pair or integers: Function<Integer, Pair<Integer, Integer>>. The actual functions used are placeholders; you can substitute one of the approaches seen here

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 
 */
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);
    }
}