我将如何在 Java Swing 中创建响应式布局

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20105833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:11:25  来源:igfitidea点击:

How would I create a responsive layout in Java Swing

javaswingresponsive-design

提问by Jay Askren

I am displaying a list of key value pairs in a swing JPanel. The key is displayed in a JLabel and the Value is displayed in a JTextField. There is enough room on the panel to display 1 or 2 columns of the key value pairs depending on how big the parent JFrame is. I would like to display 2 columns of key value pairs unless the panel gets too small. Then I want to switch to one column. Is this possible in Swing without writing my own custom layout manager?

我在 Swing JPanel 中显示键值对列表。键显示在 JLabel 中,值显示在 JTextField 中。面板上有足够的空间来显示 1 或 2 列键值对,具体取决于父 JFrame 的大小。除非面板太小,否则我想显示 2 列键值对。然后我想切换到一列。如果不编写自己的自定义布局管理器,这在 Swing 中是否可行?

Putting each key value pair on it's own panel and adding the panels to a Flow Layout would do what I want to do except that labels would not be aligned with each other and text fields would not align with each other so it would look terrible. Is there a better way to do this?

将每个键值对放在它自己的面板上并将面板添加到 Flow Layout 会做我想做的事情,除了标签不会彼此对齐并且文本字段不会彼此对齐,所以它看起来很糟糕。有一个更好的方法吗?

Edit:

编辑:

Here is what it would look like. If the panel is big enough, show two columns. Otherwise show one column.

这就是它的样子。如果面板足够大,则显示两列。否则显示一列。

2 Columns:

2 列:

   Some Key _______________                Key 2 ________________ 
Another Key _______________      Yet Another Key ________________
      Key 5 _______________                Key 6 ________________

1 Column

1 列

       Some Key _______________                
          Key 2 _______________ 
    Another Key _______________      
Yet Another Key _______________
          Key 5 _______________                
          Key 6 ________________

回答by splungebob

You could use your FlowLayout idea and still make the labels/textfields lineup. Add a strut to each key/value panel that's the size of your longest label to force the textfield out to the right the same amount on each panel. Something like:

您可以使用 FlowLayout 的想法并仍然制作标签/文本字段阵容。向每个键/值面板添加一个与最长标签大小相同的支柱,以强制将每个面板上的文本字段向右移出相同的数量。就像是:

import java.awt.*;
import javax.swing.*;

public class Test implements Runnable
{
  private String[] keys = {"One", "Twoooooo", "Three", "Four",
                           "Five", "Six", "Seven", "Eight",
                           "Nine", "Ten", "Eleven", "Twelve"};
  private String[] values = {"Apple", "Boy", "Cat", "Denmark",
                             "Elephant", "Foo", "Hello", "Igloo",
                             "Jug", "Kangaroo", "Lip", "Now"};

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

  public void run()
  {
    JPanel panel = new JPanel(new FlowLayout());
    GridBagConstraints gbc;
    JTextField textField = null;
    int maxWidth = 0;
    JLabel[] labels = new JLabel[keys.length];

    for (int i = 0; i < keys.length; i++)
    {
      labels[i] = new JLabel(keys[i]);
      maxWidth = Math.max(labels[i].getPreferredSize().width, maxWidth);
    }

    JPanel[] panels = new JPanel[keys.length];

    for (int i = 0; i < keys.length; i++)
    {
      panels[i] = new JPanel(new GridBagLayout());

      gbc = new GridBagConstraints();
      gbc.gridx = 0;
      gbc.gridy = 0;
      gbc.anchor = GridBagConstraints.EAST;
      gbc.insets = new Insets(1,1,1,1);
      panels[i].add(Box.createHorizontalStrut(maxWidth), gbc);

      gbc.gridy = 1;
      panels[i].add(labels[i], gbc);

      textField = new JTextField(10);
      textField.setText(values[i]);
      gbc.gridx = 1;
      panels[i].add(textField, gbc);

      panel.add(panels[i]);
    }

    JFrame frame = new JFrame("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(panel);
    frame.setSize(240, 400);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}