java-在Swing中对齐垂直和水平SequentialGroup
作者:互联网
我已经写了这段代码
package test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
public class MainFrame extends JFrame
{
private int levels;
private int slots;
private JLabel labelShowLevel;
private JFormattedTextField textShowLevel;
private JButton buttonShowLevel ;
private JLabel labelAddEntity ;
private JFormattedTextField textAddEntity ;
private JButton buttonAddEntity ;
private JComboBox cb;
private JLabel labelRemoveEntity ;
private JFormattedTextField textRemoveEntity ;
private JButton buttonRemoveEntity ;
private JLabel labelSearchEntity ;
private JFormattedTextField textSearchEntity ;
private JButton buttonSearchEntity ;
private JLabel labelEmptySlots ;
private JButton buttonEmptySlots ;
private JLabel levelDispaly;
private JLabel totalLevels;
public MainFrame(int levels, int slots)
{
this.levels = levels;
this.slots = slots;
getContentPane().add( CreatPanel(), BorderLayout.EAST);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setPreferredSize(new Dimension(1000,500));
this.revalidate();
this.repaint();
this.pack();
this.setVisible(true);
}
JPanel CreatPanel()
{
JPanel panel = new JPanel();
labelShowLevel = new JLabel("Display Level");
labelAddEntity = new JLabel("Enter new car/motorbike");
labelRemoveEntity = new JLabel("Exit car/motorbike");
labelSearchEntity = new JLabel("Find car/motorbike");
labelEmptySlots = new JLabel("Get total empty slots");
textShowLevel = new JFormattedTextField();
textAddEntity = new JFormattedTextField();
textRemoveEntity = new JFormattedTextField();
textSearchEntity = new JFormattedTextField();
textShowLevel.setPreferredSize(new Dimension(100, HEIGHT));
buttonShowLevel = new JButton("Show");
buttonAddEntity = new JButton("Enter");
buttonRemoveEntity= new JButton("Exit");
buttonSearchEntity = new JButton("Search");
buttonEmptySlots = new JButton("Find");
Font font = new Font("sans comic", Font.ITALIC, 18);
levelDispaly = new JLabel("Now Displaying Level 0");
levelDispaly.setFont(font);
totalLevels = new JLabel("Total Levels:"+ this.levels+" Total slots per level:"+this.slots);
String[] items = { "Car", "Motorbike" };
cb = new JComboBox(items);
cb.setSelectedItem(items[0]);
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
hGroup.addGroup(layout.createParallelGroup().
addComponent(labelShowLevel).addComponent(labelAddEntity).addComponent(labelRemoveEntity).addComponent(labelSearchEntity).addComponent(labelEmptySlots).addComponent(levelDispaly).addComponent(totalLevels));
hGroup.addGroup(layout.createParallelGroup().
addComponent(textShowLevel).addComponent(textAddEntity).addComponent(cb).addComponent(textRemoveEntity).addComponent(textSearchEntity));
hGroup.addGroup(layout.createParallelGroup().
addComponent(buttonShowLevel).addComponent(buttonAddEntity).addComponent(buttonRemoveEntity).addComponent(buttonSearchEntity).addComponent(buttonEmptySlots));
layout.setHorizontalGroup(hGroup);
layout.linkSize(SwingConstants.HORIZONTAL, buttonShowLevel, buttonAddEntity,buttonRemoveEntity,buttonSearchEntity,buttonEmptySlots);
// Create a sequential group for the vertical axis.
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(labelShowLevel).addComponent(textShowLevel).addComponent(buttonShowLevel));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(labelAddEntity).addComponent(textAddEntity));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(cb).addComponent(buttonAddEntity));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(labelRemoveEntity).addComponent(textRemoveEntity).addComponent(buttonRemoveEntity));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(labelSearchEntity).addComponent(textSearchEntity).addComponent(buttonSearchEntity));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(labelEmptySlots).addComponent(buttonEmptySlots));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(levelDispaly));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(totalLevels));
layout.setVerticalGroup(vGroup);
return panel;
}
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(new Runnable() {
public void run()
{
try
{
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
}
catch (Exception ex) {
ex.printStackTrace();
}
(new MainFrame(5,5)).setVisible(true);
}
});
}
}
结果是
我想要的是将最后两个标签(totalLevels和levelDispaly)居中,并使它们占据三列.我做了很多次尝试都失败了.
请注意,窗格的左侧为空,因为我已经删除了代码中不必要的部分,只是为了集中精力解决问题.
解决方法:
您接近了-您陷入了警告,仍然为GroupLayout开发了直觉.有些人永远不会离开这个困境:)
除了笑话,这是您的MCVE,但有一些更改:
public class MainFrame extends JFrame {
private int levels;
private int slots;
private JLabel labelShowLevel;
private JFormattedTextField textShowLevel;
private JButton buttonShowLevel;
private JLabel labelAddEntity;
private JFormattedTextField textAddEntity;
private JButton buttonAddEntity;
private JComboBox cb;
private JLabel labelRemoveEntity;
private JFormattedTextField textRemoveEntity;
private JButton buttonRemoveEntity;
private JLabel labelSearchEntity;
private JFormattedTextField textSearchEntity;
private JButton buttonSearchEntity;
private JLabel labelEmptySlots;
private JButton buttonEmptySlots;
private JLabel levelDispaly;
private JLabel totalLevels;
public MainFrame(int levels, int slots) {
this.levels = levels;
this.slots = slots;
getContentPane().add(CreatPanel());
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
JPanel CreatPanel() {
JPanel panel = new JPanel();
labelShowLevel = new JLabel("Display Level");
labelAddEntity = new JLabel("Enter new car/motorbike");
labelRemoveEntity = new JLabel("Exit car/motorbike");
labelSearchEntity = new JLabel("Find car/motorbike");
labelEmptySlots = new JLabel("Get total empty slots");
textShowLevel = new JFormattedTextField();
textAddEntity = new JFormattedTextField();
textRemoveEntity = new JFormattedTextField();
textSearchEntity = new JFormattedTextField();
textShowLevel.setPreferredSize(new Dimension(100, HEIGHT));
buttonShowLevel = new JButton("Show");
buttonAddEntity = new JButton("Enter");
buttonRemoveEntity = new JButton("Exit");
buttonSearchEntity = new JButton("Search");
buttonEmptySlots = new JButton("Find");
Font font = new Font("sans comic", Font.ITALIC, 18);
levelDispaly = new JLabel("Now Displaying Level 0");
levelDispaly.setFont(font);
totalLevels = new JLabel("Total Levels:"+ this.levels + " Total slots per level:"
+ this.slots);
String[] items = {"Car", "Motorbike"};
cb = new JComboBox(items);
cb.setSelectedItem(items[0]);
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
layout.linkSize(SwingConstants.HORIZONTAL, buttonShowLevel, buttonAddEntity, buttonRemoveEntity, buttonSearchEntity, buttonEmptySlots);
//@formatter:off
// Horizontal
GroupLayout.ParallelGroup hGroup = layout.createParallelGroup(Alignment.CENTER); // Will align the labels the way you wanted
hGroup.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(labelShowLevel)
.addComponent(labelAddEntity)
.addComponent(labelRemoveEntity)
.addComponent(labelSearchEntity)
.addComponent(labelEmptySlots))
.addGroup(layout.createParallelGroup()
.addComponent(textShowLevel)
.addComponent(textAddEntity)
.addComponent(cb)
.addComponent(textRemoveEntity)
.addComponent(textSearchEntity))
.addGroup(layout.createParallelGroup()
.addComponent(buttonShowLevel)
.addComponent(buttonAddEntity)
.addComponent(buttonRemoveEntity)
.addComponent(buttonSearchEntity)
.addComponent(buttonEmptySlots)));
hGroup.addComponent(levelDispaly);
hGroup.addComponent(totalLevels);
layout.setHorizontalGroup(hGroup);
// Vertical
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
vGroup.addGroup(layout.createParallelGroup()
.addComponent(labelShowLevel)
.addComponent(textShowLevel)
.addComponent(buttonShowLevel));
vGroup.addGroup(layout.createParallelGroup()
.addComponent(labelAddEntity)
.addComponent(textAddEntity));
vGroup.addGroup(layout.createParallelGroup()
.addComponent(cb)
.addComponent(buttonAddEntity));
vGroup.addGroup(layout.createParallelGroup()
.addComponent(labelRemoveEntity)
.addComponent(textRemoveEntity)
.addComponent(buttonRemoveEntity));
vGroup.addGroup(layout.createParallelGroup()
.addComponent(labelSearchEntity)
.addComponent(textSearchEntity)
.addComponent(buttonSearchEntity));
vGroup.addGroup(layout.createParallelGroup()
.addComponent(labelEmptySlots)
.addComponent(buttonEmptySlots));
vGroup.addGroup(layout.createParallelGroup()
.addComponent(levelDispaly));
vGroup.addGroup(layout.createParallelGroup()
.addComponent(totalLevels));
layout.setVerticalGroup(vGroup);
//@formatter:on
return panel;
}
public static void main(String args[]) {
EventQueue.invokeLater(() -> new MainFrame(5, 5));
}
}
您的问题出在横向小组中.您将标签限制为与左列对齐.作为一般的经验法则,如果希望某个方向上的组件不受限制(可以自由对齐),则需要在该方向的层次结构中添加另一个“级别”的组.
具体来说,从您的水平代码中删除2个标签后,剩下的是一个顺序组(在您的情况下为hGroup),其中有并行组.由于这两个标签不与这些组对齐,因此必须将它们添加到不是hGroup的顺序组中.这意味着,如果hGroup是顺序的,它将有一个“子”并行组,该组在其下将具有新的顺序组(代替hGroup)以及2个标签:
> hGroup(顺序)
> p(参数)
> s(Seq.)
> p1
> p2
> p3
>标签1
>标签2
(未显示p1-p3下的组件.)
但是,由于hGroup现在只有1个子级,因此您只需删除此冗余的顶层顺序组并将hGroup设为单个并行组即可.请记住,水平和垂直组都可以是顺序组或并行组之一.不要将两个方向都限制在顺序上,因为那样只会添加多余的组(仍然可以使用):
> hGroup(参数)
> s(Seq.)
> p1
> p2
> p3
>标签1
>标签2
以下是可以帮助您使用GroupLayout的常规思维模式.请注意,人们可以通过多种方式思考这些问题并提出其他解释.在使用Grouplayout一段时间后,这将变得完全直观.
选择正确的父组类型
如果您想知道您的垂直/水平组是顺序的还是平行的,只需查看“管理方向”即可. “管理方向”是您可以最终确定最高级别组件顺序的方向.
在您的情况下,让我们看一下垂直分组.从上到下查看时,您可以确定从上到下的组件(或其组)的顺序,但不能从左到右,因为最后两个标签相对于组件没有明确的从左到右的顺序其他组件-这2个标签由对齐方式确定.然后
垂直组&&垂直控制方向==顺序组
对于水平组,同样,您只能说出从上到下的顺序:
水平组&&垂直控制方向==平行组
如果没有单个“管理方向”,则可以选择其中一个.想象一个2×2的网格,有4个布局层次结构将得到相同的结果.
如果您输入有误,并且使用了错误的分组类型,则该分组将只有一个其他子组的子组.然后,您可以剪切该顶级组.
创建组层次结构
选择“管理方向”后,开始朝该方向前进,并按确定的顺序添加组件.如果顺序中有多个组件位于同一位置,则意味着您需要在另一个方向上添加组.
对于垂直(红色箭头)顺序组,请遵循以下示意图:
从上到下,订单的第1个位置(红色矩形)中包含3个组件.这意味着我们需要一个并行组来划分(分离)子层次结构(绿线)中的每个组件.这个过程一直持续到我们到达第一个标签为止,此时没有“竞争”组件,因此我们只需添加该组件(红色矩形)即可.第二个标签相同.这是垂直组的代码一对一.
对于水平(蓝色箭头)并行组,请观察类似的示意图:
从上到下,第一个位置有3个组件.这意味着我们需要添加一个顺序组.但是,这三个组件中的每个组件都与水平的其他组件共享其顺序位置.这意味着我们需要添加3个平行组(蓝色矩形)以对组件进行剖切.将这3个并行组添加到顺序组(绿色矩形)中.然后,我们到达第一个标签,然后添加该组件(绿色矩形).第二个标签相同.这是水平组的代码一对一.
对准
我建议您完全不用担心对齐问题,除非您以所需的方式获得了组层次结构.在您链接组件的情况下(例如您的情况),对齐不会发挥任何作用,因为组件已经填满了整个空间(请自己检查).设置完所有内容后,即可快速轻松地设置路线.
与布局无关的注释:
>无需在显示框架之前调用revalidate和重新绘制.
>调用setSize(…)是多余的,因为您稍后将调用包(应按要求进行).
>您将调用* setVisible(true)两次:一次inmain`,一次在构造函数中.其中之一根本什么都不做,只选一个.
>不要在textShowLevel上调用setPrefferedSize(…).我什至不确定您要传递给它什么(某些ImageObserver东西).您可以通过指定其包含的列数或覆盖其getPreferredSize()来设置其宽度.
>不要使用原始类型的JComboBox,您可能需要< String>.
>我没有将面板添加到BorderLayout.EAST中,因为在我的上下文中这没有意义.
标签:swing,layout-manager,grouplayout,java 来源: https://codeday.me/bug/20191027/1943997.html