当失去键盘焦点时,Swing组件自动调整大小

3
我在GUI布局中遇到了两个问题。我使用JTabbedPane来容纳两个JPanels,每个面板都有一些按钮和文本区域,并且每个面板都使用GridBagLayout进行布局。 在其中一个面板中,我有一个JScrollPane,它使用JTextArea。当我向这个文本区域添加任何内容并且然后单击GUI以使其失去焦点,或者如果我更改选项卡,则所有文本字段和文本的大小都会变为尽可能小。
为了进一步说明我的问题,这里是当我向文本区域添加内容后单击GUI之前和之后的图片:
这是我用来将JTextArea添加到面板中的代码:
table = new JTextArea();
    table.setEditable(false);
    JScrollPane sp = new JScrollPane(table);
    sp.setSize(40, 10);
    c.insets = new Insets(10,10,10,10);
    c.gridx = 1;
    c.gridwidth = 4;
    c.gridy = 7;
    c.gridheight = 7;
    this.add(sp, c);

这是我用来将文本区域添加到面板中的代码:

title = new JTextField(10);
    author = new JTextField(10);
    dueDate = new JTextField(10);
    setDate = new JTextField(10);
    setWeighting = new JTextField(10);

    c.gridx = 2;
    c.gridy = 1;
    this.add(title, c);//add title field
    c.gridx = 2;
    c.gridy = 2;
    this.add(author, c);//add author field
    c.gridx = 2;
    c.gridy = 3;
    this.add(dueDate, c);//add dueDate field
    c.gridx = 2;
    c.gridy = 4;
    this.add(setDate, c);//add setDate field
    c.gridx = 2;
    c.gridy = 5;
    this.add(setWeighting, c);//add set Weighting field

能够看到一些可编译和可运行的代码会很有帮助。不需要整个程序,只需要足够的代码来重现问题,而不会让我们被大量无关的代码淹没。 - Hovercraft Full Of Eels
1
我没有看到你在GridBagComponents的weightx或weighty字段中设置任何地方。如果将它们设置为1.0会发生什么?如果这不起作用,请考虑发布一个可编译的可运行小程序来演示问题,即SSCCE - Hovercraft Full Of Eels
当我这样做时,似乎什么都没有改变,调整大小的行为仍然发生。 - lilroo
此外,您的gridx和gridy值应该从0开始,而不是1。 - Hovercraft Full Of Eels
2
http://madbean.com/anim/totallygridbag/ - Jens Schauder
2个回答

3
我可以部分复现您的问题,步骤如下:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Foo002 {

   private static final int ROWS = 5;

   private static void createAndShowGui() {
      JPanel assignmentsPanel = new JPanel(new GridBagLayout());
      final JTextArea textarea = new JTextArea(ROWS, 20);

      GridBagConstraints c = new GridBagConstraints();
      int insetGap = 2;
      c.insets = new Insets(insetGap, insetGap, insetGap, insetGap);
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridwidth = 1;
      c.gridheight = 1;
      c.weightx = 1.0;
      c.weighty = 1.0;
      String[] labels = { "title", "author", "date due", "date set",
            "set weighting" };
      int row = 0;
      for (int i = 0; i < labels.length; i++) {
         JLabel label = new JLabel(labels[i], SwingConstants.CENTER);
         c.gridx = 0;
         c.gridy = i;
         assignmentsPanel.add(label, c);
         c.gridx = 1;
         JTextField textfield = new JTextField(10);
         assignmentsPanel.add(textfield, c);

         label.setPreferredSize(textfield.getPreferredSize());
         row++;
      }
      c.gridx = 0;
      c.gridy = row;
      c.fill = GridBagConstraints.HORIZONTAL;
      Action myAction = new AbstractAction("Fill Area") {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 10; i++) {
               sb.append("foo bar bif baz spam\n");
            }
            textarea.setText(sb.toString());
         }
      };
      assignmentsPanel.add(new JButton(myAction), c);
      c.gridx = 1;
      assignmentsPanel.add(new JButton("Button 2"), c);
      row++;

      c.gridx = 0;
      c.gridy = row;
      c.gridwidth = 2;
      c.gridheight = ROWS;

      JScrollPane scrollpane = new JScrollPane(textarea);

      assignmentsPanel.add(scrollpane, c);

      JTabbedPane tabbedPanel = new JTabbedPane();
      tabbedPanel.add("Assignments", assignmentsPanel);
      tabbedPanel.add("Modules", new JPanel());

      JOptionPane.showMessageDialog(null, tabbedPanel, "Foo",
            JOptionPane.PLAIN_MESSAGE);

   }

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

在向JTextArea添加文本之前和之后,它看起来像:
enter image description here enter image description here 点击选项卡后:
enter image description here 但是可以通过为JScrollPane添加垂直滚动条来修复它。
  // JScrollPane scrollpane = new JScrollPane(textarea);
  JScrollPane scrollpane = new JScrollPane(textarea,
        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

运行后效果如下:
enter image description here

在 Mac OS 上也表现良好:

enter image description here


刚刚尝试了一下,问题仍然存在 :/ 不过还是谢谢你 :) - lilroo
4
请通过发布一个类似我刚才上面发布的 sscce 来证明你的问题。这将让我们准确地了解你的问题所在。 - Hovercraft Full Of Eels

1

您可以尝试避免使用Gridbag,而是使用嵌套的JPanels。我已经为您创建了一个简短的示例:

public class LilrooPanel extends JPanel
{
    private static final int GAP = 5;

    public static void main(String[] args){
        JFrame main = new JFrame("Dims");
        JTabbedPane tabbed = new JTabbedPane(); 
        JPanel myPanel = new LilrooPanel();
        tabbed.add("Assignments", myPanel);
        tabbed.add("Modules", new JPanel());
        main.setContentPane(tabbed);
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main.setSize(400, 400);
        main.setLocationRelativeTo(null);
        main.setVisible(true);
    }

    public LilrooPanel(){
        super(new BorderLayout(0, GAP));
        setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
        Box north = new Box(BoxLayout.Y_AXIS);

        north.add(new BorderPanel("Assignment Title", new JTextField()));
        north.add(Box.createRigidArea(new Dimension(0, GAP)));
        north.add(new BorderPanel("Author", new JTextField()));
        north.add(Box.createRigidArea(new Dimension(0, GAP)));
        north.add(new BorderPanel("Date Due", new JTextField()));
        north.add(Box.createRigidArea(new Dimension(0, GAP)));
        north.add(new BorderPanel("Date Set", new JTextField()));
        north.add(Box.createRigidArea(new Dimension(0, GAP)));
        north.add(new BorderPanel("Set Weighting", new JTextField()));
        north.add(Box.createRigidArea(new Dimension(0, GAP)));

        JPanel buttonsPanel = new JPanel();
        buttonsPanel.add(new JButton("Add Assignment"));
        buttonsPanel.add(new JButton("Remove Assignment"));
        north.add(buttonsPanel);

        add(north, BorderLayout.NORTH);

        add(new JScrollPane(new JTable(new Object[][]{}, new Object[]{"ModTitle", "ModId", "Assignments"})));
    }

    private static class BorderPanel extends JPanel
    {
        private static final Dimension LABELS_WIDTH = new Dimension(100, 0);

        public BorderPanel(String label, JComponent right){
            super(new BorderLayout(GAP, 0));
            JLabel jLabel = new JLabel(label);
            jLabel.setPreferredSize(LABELS_WIDTH);
            add(jLabel, BorderLayout.WEST);
            add(right);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接