简体   繁体   English

Java GUI布局建议

[英]java GUI layout suggestion

public class AFS {
    public JPanel afs(final Fields input){
        JPanel titlePanel = new JPanel();

        //Title fields
        JLabel afs = new JLabel("Statement", Label.LEFT);

        Label mm = new Label("month ", Label.LEFT);
        Label my = new Label("Year ", Label.LEFT);

        //first line
        titlePanel.add(afs);
        titlePanel.add(mm);
        titlePanel.add(input.MENTRY);
        titlePanel.add(my);
        titlePanel.add(input.YENTRY);
        titlePanel.setPreferredSize(null);

        //Left Panels
        JPanel sb = new JPanel();
        JPanel entry = new JPanel();
        entry.setLayout(new BoxLayout(entry, BoxLayout.Y_AXIS));
        entry.setAlignmentX(Component.LEFT_ALIGNMENT);
        entry.add(new Label("Service "));
        entry.add(input.s);
        entry.add(new Label("Amount "));
        entry.add(input.a);
        entry.add(new Label("Counter "));
        entry.add(input.o);
        entry.add(new Label("Division "));
        entry.add(input.d);

        sb.add(entry);


        JPanel holderPanel = new JPanel();
        holderPanel.setLayout(new BoxLayout(holderPanel, BoxLayout.Y_AXIS));
        holderPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
        holderPanel.add(titlePanel);
        holderPanel.add(sb);

        JButton start = new JButton("Save Current");
        start.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                ScriptAction action = new ScriptAction();
                action.saveAll(input,1);
            }
        });
        holderPanel.add(start); 
        return holderPanel;
    }

I have a short version of what looks like above code. 我有上面代码的简短版本。 The current layout looks like this: 当前布局如下: 在此处输入图片说明

But I want the layout look like (paint edited). 但是我希望布局看起来像(绘画编辑)。

在此处输入图片说明

I have tried swap using gridLayout for the entry and it will display 2 rows but gridlayout will still align everything in the center (include the title and the header). 我尝试使用gridLayout交换条目,它将显示2行,但gridlayout仍将所有内容对齐在中心(包括标题和标题)。 Furthermore the button span would be across the entire bottom section. 此外,按钮跨度将跨越整个底部。 I was wondering if there are any suggested way to do this? 我想知道是否有建议的方法可以做到这一点?

You would need to use a combination of layout managers to achieve the desired output: 您将需要结合使用布局管理器来获得所需的输出:

在此处输入图片说明 在此处输入图片说明 Before resize / After resize 调整之前/调整之后

In this case there are 3 main parts: 在这种情况下,有3个主要部分:

  • Top pane (Uses Box to align some text on the left and some on the right) 顶部窗格(使用“ Box ”在左侧和右侧对齐一些文本)
  • Middle pane (Uses GridBagLayout to position the components as in the image, maybe GridLayout with proper insets might work as well) 中间窗格(使用GridBagLayout将组件放置在图像中,也许带有适当插图的GridLayout也可以工作)
  • Bottom pane (Uses default JPanel 's layout: FlowLayout ) 底部窗格(使用默认的JPanel布局: FlowLayout

The top pane uses 2 JPanel s as well, the first one for the label Statement alone and other with FlowLayout aligned to the right for the other 4 components, as per this answer BoxLayout does not respect the preferred size of our JTextField s. 顶部窗格也使用2个JPanel ,第一个窗格单独用于标签Statement ,其他窗格的FlowLayout与其他4个组件的右边对齐,因为此答案 BoxLayout不遵守JTextField的首选大小。 So a workaround is to wrap them inside another JPanel and then wrap that JPanel along with the Statement label. 因此,一种解决方法是将它们包装在另一个JPanel ,然后将该JPanelStatement标签一起包装。

A similar problem arises with the middle pane, which needs to use 2 JPanel s: One for the fields wrapped inside another bigger one which holds it and the JButton at the bottom ( Save Current ). 中间窗格也会出现类似的问题,该窗格需要使用2个JPanel :一个用于包裹在另一个较大的字段中的字段,另一个较大的字段将其保留,而JButton放在底部( Save Current )。 We could achieve a similar output by adding the JButton with a gridx = 2 and gridy = 2 with the counter and division label and fields on gridx = 3 and gridx = 4 respectively (instead of 2 & 3 ) but we would then need to add gbc.insets to add insets to the top and bottom with high values as well... It's up to you which one to use :) 我们可以通过添加带有gridx = 2gridy = 2以及counterdivision标签以及分别在gridx = 3gridx = 4上的字段(而不是2 & 3 )的JButton来获得类似的输出,但是我们需要添加gbc.insets也可以在顶部和底部添加具有高值的插图...取决于您使用哪个:)

The code that produces the above outputs is the following: 产生以上输出的代码如下:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class FormSample {
    private JFrame frame;
    private JPanel topRightPane;
    private JPanel centerPane;
    private JPanel centerWithButtonPane;
    private JPanel buttonsPane;

    private JTextField monthField;
    private JTextField yearField;

    private JTextField serviceField;
    private JTextField amountField;
    private JTextField counterField;
    private JTextField divisionField;

    private static final int LEFT_MARGIN = 50; //Increase / Decrease to add extra space between components
    private static final int RIGHT_MARGIN = LEFT_MARGIN;

    //Change insets accordingly to add extra space between components (top, left, bottom, right)
    private static final Insets leftInsets = new Insets(0, LEFT_MARGIN, 0, 0);
    private static final Insets rightInsets = new Insets(0, 0, 0, RIGHT_MARGIN);
    private static final Insets defaultInsets = new Insets(0, 0, 0, 0);

    private JButton saveCurrentButton;
    private JButton saveAllButton;
    private JButton resetButton;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new FormSample()::createAndShowGui);
    }

    private void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());

        monthField = new JTextField(10);
        yearField = new JTextField(10);

        serviceField = new JTextField(10);
        amountField = new JTextField(10);
        counterField = new JTextField(10);
        divisionField = new JTextField(10);

        saveCurrentButton = new JButton("Save Current");
        saveAllButton = new JButton("Save all");
        resetButton = new JButton("Reset");

        buttonsPane = new JPanel();

        topRightPane = new JPanel();
        topRightPane.setLayout(new FlowLayout(FlowLayout.RIGHT));

        topRightPane.add(new JLabel("Month"));
        topRightPane.add(monthField);
        topRightPane.add(new JLabel("Year"));
        topRightPane.add(yearField);

        centerWithButtonPane = new JPanel();
        centerWithButtonPane.setLayout(new BoxLayout(centerWithButtonPane, BoxLayout.PAGE_AXIS));

        Box box = Box.createHorizontalBox();
        box.add(new JLabel("Statement"));
        box.add(Box.createHorizontalGlue());
        box.add(topRightPane);

        centerPane = new JPanel();
        centerPane.setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = defaultInsets;
        centerPane.add(new JLabel("Service"), gbc);

        gbc.gridx = 1;
        gbc.insets = rightInsets;
        centerPane.add(serviceField, gbc);

        gbc.gridx = 2;
        gbc.insets = leftInsets;
        centerPane.add(new JLabel("Counter"), gbc);

        gbc.gridx = 3;
        gbc.insets = defaultInsets;
        centerPane.add(counterField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.insets = defaultInsets;
        centerPane.add(new JLabel("Amount"), gbc);

        gbc.gridx = 1;
        gbc.insets = rightInsets;
        centerPane.add(amountField, gbc);

        gbc.gridx = 2;
        gbc.insets = leftInsets;
        centerPane.add(new JLabel("Division"), gbc);

        gbc.gridx = 3;
        gbc.insets = defaultInsets;
        centerPane.add(divisionField, gbc);

        saveCurrentButton.setAlignmentX(Component.CENTER_ALIGNMENT); //Force centered alignment for our JButton
        centerWithButtonPane.add(centerPane);
        centerWithButtonPane.add(saveCurrentButton);

        buttonsPane.add(saveAllButton);
        buttonsPane.add(resetButton);

        frame.add(box, BorderLayout.NORTH);
        frame.add(centerWithButtonPane, BorderLayout.CENTER);
        frame.add(buttonsPane, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Also please follow the advices given by @SergiyMedvynskyy about not mixing AWT and Swing components (ie JTextField with TextField ) and only use Swing components as AWT ones are buggy. 另外,请遵循@SergiyMedvynskyy给出的关于不混合AWT和Swing组件(即JTextFieldTextField )的建议,并且仅使用Swing组件,因为AWT有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM