【问题标题】:Dynamic changing of layouts in swing秋千中布局的动态变化
【发布时间】:2018-01-12 20:07:22
【问题描述】:

我几乎可以肯定这个问题之前在这里被问过:Java Swing: How to change GUI dynamically,但我似乎对它的工作原理有一些基本的误解。

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

public class JTest extends JFrame
{
  public static void main(String[] args)
  {
    JTest t = new JTest();
  }

  Container pane;

  public JTest()
  {
    setSize(500,500);
    setTitle("JTest");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    pane = getContentPane();
    pane.setLayout(new GridLayout(1,2));
    JButton old = new JButton("old");
    old.addActionListener(new OldButton());
    pane.add(old);
    JScrollPane scroll = new JScrollPane(new JTextArea(50,20));
    pane.add(scroll);

    setVisible(true);
  }

  private class OldButton implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      pane.setLayout(new GridLayout(1,2));
      JButton old = new JButton("new");
      old.addActionListener(new NewButton());
      pane.add(old);
      JScrollPane scroll = new JScrollPane(new JTextArea(50,20));
      pane.add(scroll);
      pane.validate();
    }
  }

  private class NewButton implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {

      pane.setLayout(new GridLayout(1,2));
      JButton old = new JButton("old");
      old.addActionListener(new OldButton());
      pane.add(old);
      JScrollPane scroll = new JScrollPane(new JTextArea(50,20));
      pane.add(scroll);
      pane.validate();
    }
  }  
}

只要按下角落的按钮,这段代码就应该用新的布局替换现有的布局,但它只是将新的布局添加到框架中。谁能告诉我我做错了什么?

编辑:

添加一些信息。一张图供参考:

我正在滚动窗格中制作一组这样的组件。每当我按下“创建新字段”按钮时,我希望它在该滚动窗格中的集合中添加一个“字段”(字段名称后跟一个 textarea 等)。这意味着更改滚动窗格内区域的布局以包含新字段。

【问题讨论】:

  • 如果你想让你的按钮做的只是改变布局,那么你的 ActionListener 应该按照垃圾神在他的回答中建议的去做:改变容器的布局,然后告诉布局管理器重新布局它的组件.他建议您在容器上调用validate(),但最近已更改为revalidate(),仅此而已。你为什么不这样做?为什么你的 ActionListener 做其他事情?
  • 如果您需要更改显示的组件,请使用 CardLayout。如果你想改变按钮,那么要么改变它的文本,要么改变它的ActionListener,或者最重要的是改变它的Action。请确切地说明您希望发生什么。
  • @Hovercraft 我真正想做的是在框架上创建一个组件列表。当按下按钮时,我希望能够在框架中添加或删除不确定数量的组件。我很确定这需要替换或更改布局,但我尝试过的每一种方式都只会创建一个奇怪的重复布局。
  • 请更具体地列举“创建组件列表”的含义,因为细节很重要。考虑使用此信息编辑您的问题。

标签: java swing layout


【解决方案1】:

好的——所以看起来你想要做的(如果我错了,请纠正我)是向 JScrollPane 中显示的 JPanel 添加一个新组件。如果是这样,那么您不想更改或交换布局,当然也不想继续添加新的 JScrollPanes。而是考虑这样做:

  • 创建一个 JScrollPane 并添加到您的 GUI。不要重新添加,因为您只需要一个。
  • 将 JPanel 添加到 JScrollPane 的视口,该视口使用允许轻松添加多个组件的布局。可能是 GridLayout 或 BoxLayout,具体取决于您的需要。
  • 另外考虑不要将上面的JPanel直接添加到视口,而是添加到另一个JPanel,一个使用BorderLayout的JPanel,将第一个JPanel添加到BorderLayout-使用JPanel的BorderLayout.PAGE_START位置,然后添加this 到 JScrollPane 的视口。这样,第一个 JPanel 最初不会拉伸以填充视口。
  • 然后在按钮的 ActionListener 中,通过调用 .add(...) 将组件添加到第一个 JPanel,然后在第一个 JPanel 上调用 revalidate()repaint() 以布局新添加的组件并重新绘制 JPanel 及其内容。

【讨论】:

    【解决方案2】:

    好的,事实证明这根本不是布局问题。我没有意识到设置新布局不会导致以前布局的组件消失,您必须在添加新组件之前删除它们。这就是我得到重复的原因。

    不过,感谢您为我指明了正确的方向。

    【讨论】:

      猜你喜欢
      • 2023-02-13
      • 2013-01-27
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      相关资源
      最近更新 更多