Java 调整3列通用组件的布局,其他组件位于上方/下方
我正在为课程作业构建一个简单的GUI,但我并没有从中得到最大的收获 这就是我的目标: 我得到了这个(它缺少一些元素,比如按钮): 所以问题是,我如何将我的布局编码得更紧凑,就像在目标图片中一样 代码如下: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);
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);
}
}