Java 调整3列通用组件的布局,其他组件位于上方/下方

Java 调整3列通用组件的布局,其他组件位于上方/下方,java,swing,user-interface,layout-manager,null-layout-manager,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);

我正在为课程作业构建一个简单的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);
    }

下面的代码应该可以帮助您取得进展

        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!有几种型号适合您的需要


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

,因为面板仅在名称和功能上不同,请使用,seen,在运行时选择所需的行为。下面的示例演示了一个
枚举
,该枚举的每个实例都包含一个显示名称和一个函数,该函数接受一个整数并返回一对或多个整数:
函数
。实际使用的函数是占位符;您可以替换所看到的方法之一

导入java.awt.BorderLayout;
导入java.awt.EventQueue;
导入java.awt.GridLayout;
导入java.util.function.function;
导入javafx.util.Pair;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.JSpinner;
导入javax.swing.JTextArea;
导入javax.swing.event.ChangeEvent;
/**
*@见https://stackoverflow.com/a/37885601/230513
*/
公开课策略测试{
私有枚举类{
双((新功能(){
@凌驾
公共对应用(整数i){
返回新对(i,i+2);
}
})),
表((新函数(){
@凌驾
公共对应用(整数i){
返回新对(i,i+4);
}
})),
性感((新功能(){
@凌驾
公共对应用(整数i){
返回新对(i,i+6);
}
}));
字符串dsiplayName;
功能;
私人种类(功能){
this.dsiplayName=name().toLowerCase();
这个函数=函数;
}
}
私有JPanel createPanel(种类){
JPanel panel=newjpanel(newborderlayout());
JSpinner spinner=新的JSpinner();
JPanel top=新的JPanel();
添加(新的JLabel(“多少”+kind.dsiplayName+“素数?”);
添加(微调器);
面板。添加(顶部,边框布局。页面开始);
JTextArea textArea=新的JTextArea(16,20);
添加(新的JScrollPane(textArea));
panel.add(新的JLabel(“用于”+kind.dsiplayName+“primes”的区域),
JLabel.居中),边框布局。第页_尾);
spinner.addChangeListener((ChangeEvent e)->{
int i=(int)spinner.getValue();
对p=种类.功能.应用(i);
textArea.append(p.getKey()+”:“+p.getValue()+”\n”);
});
返回面板;
}
专用void display(){
JFrame f=新JFrame(“策略测试”);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f、 setLayout(新的GridLayout(1,0,5,5));
for(种类:种类.值()){
f、 添加(createPanel(种类));
}
f、 包装();
f、 setLocationRelativeTo(空);
f、 setVisible(真);
}
公共静态void main(字符串[]args){
invokeLater(new StrategyTest()::display);
}
}

对于中间的3个面板,您可以创建一个工厂方法,该方法接受<代码>字符串(RANDs类型)和其他潜在的东西,如<代码> SpnNeNeNBER模型< /C> >并返回一个面板。将这3个面板放在一行
GridLayout
。将该面板置于
边框布局的中心。将一个面板添加到
页面_START
,其中包含按钮的
流程布局
。为创建的
GUI
消息在
页面的末尾添加
JLabel
。要获得更多帮助,请发表一篇关于您在实施该方法方面的最佳尝试的报告。@AndrewThompson是正确的;下面结合了工厂模式和策略模式。非常感谢您的代码!对于如何使用不同的Java布局,这是一个非常有用的指南。我当然对使用GridLayout和BorderLayout迷惑不解。是的,我对Java布局如何分发组件没有一个清晰的概念。谢谢!哇@trashgood,这是一个非常容易使用和简单的布局配置比典型的一个。即使我还不了解软件设计模式,看到它的应用也是非常有趣的@弗拉门基诺:当你继续你的研究时,当被要求比较两种(或更多)算法时,记住这个模式。
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);
    }
}