Java Swing GridBagLayout 面板调整大小问题

标签 java swing animation resize tween

我正在为一个亲戚开发一个简单的小 Swing 应用程序,但我在实现动画时遇到了问题......

这是我的布局的描述:

我有一个主窗口(通过实例化、打包和显示 JFrame 创建)。 我已经告诉主窗口的内容面板使用 GridBagLayout 作为其布局。 我的网格是 2 格宽,3 格高。在第一列中,我有三个 JButton(A、B 和 C),每个占据一行垂直网格空间和一列水平网格空间。在第二列中,我有另一个 JPanel,它有一列宽,三行高。

第二个 JPanel 也设置为使用 GridBagLayout 作为其布局。在这种情况下,有两列和一行。左列有一个一列宽、一排高的 JPanel,其中包含 Button 1。右列仅包含一个 JButton(按钮 2),它也是一列宽,一行高。

这是我刚才描述的截图: Image of Layout

现在您了解了布局是什么,让我解释一下我一直在尝试做的事情:

我一直在尝试使用 Universal Tween Engine调整包含按钮 1 的 Jpanel 的大小。但是,在我的尝试中,结果是:

enter image description here

您可能会看到,包含 Button 1 的 JPanel 已成功调整大小!但是,Button 2 的大小和位置根本没有改变,事实上,Button 2 被包含 Button 1 的 JPanel 切断了!

这是一个问题,因为我预计调整包含 Button 1 的 JPanel 的大小会同时更改其包含的 GridBagLayout 的单元格大小。看来我在这件事上大错特错了。

所以这让我想到了我的问题......我需要做什么才能“更新”我的 GridBagLayout 以便调整其网格大小以适应包含 Button 1 的 Jpanel 的大小增加?我试过在我的 GridBaglayout 上调用 GridBagLayout.invalidatelayout(),我也试过在我的主窗口上调用 JFrame.getContentPane().invalidate()。两者似乎都没有任何效果。

这是我的项目的可编译源代码:

ImageManager.java:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import aurelienribon.tweenaccessors.swing.*;
import aurelienribon.utils.swing.*;
import aurelienribon.tweenengine.*;
import aurelienribon.tweenengine.equations.*;

public class ImageManager
{
    /**
     * @param args
     */

    public static JFrame mainwindow;
    public static TweenManager tweenManager;
    public static void main(String[] args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable() //For thread safety!
        {
            public void run()
            {
                InitGUI();
                InitTween();
            }
        });
    }


    private static void InitTween()
    {
        ((Window)mainwindow).addWindowListener(new WindowAdapter() {
            @Override public void windowOpened(WindowEvent e)
            {
                    new DrawingCanvas()
                    {
                            @Override protected void update(int elapsedMillis)
                            {
                                tweenManager.update(elapsedMillis);
                            }
                    }.start();
            }
        });
    }


    private static void InitGUI()
    {
        //Init the window and layout systems
        mainwindow = new JFrame("Imaffect");
        Container pane = mainwindow.getContentPane();
        pane.setLayout(new GridBagLayout());

            //Begin creating the UI!
            pane.add(new JButton("Button A"), new GridBagConstraints(0, 0, 1, 1, 0, 1, GridBagConstraints.PAGE_START, GridBagConstraints.VERTICAL, new Insets(0,0,0,0), 100, 0));
            pane.add(new JButton("Button B"), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.PAGE_START, GridBagConstraints.VERTICAL, new Insets(0,0,0,0), 100, 100));
            pane.add(new JButton("Button C"), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.PAGE_START, GridBagConstraints.VERTICAL, new Insets(0,0,0,0), 100, 20));

            pane.add(InitPreviewGUI(), new GridBagConstraints(1, 0, 1, 3, 1, 1, GridBagConstraints.PAGE_START, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));


        //Finalize the window
        mainwindow.pack();
        mainwindow.setVisible(true);
    }


    private static JPanel InitPreviewGUI()
    {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.add(InitSettingsGUI(), new GridBagConstraints(0, 0, 1, 1, 0, 1, GridBagConstraints.PAGE_START, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));
        panel.add(new JButton("Button 2"), new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.PAGE_START, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));


        return panel;
    }

    private static JPanel InitSettingsGUI()
    {
        JPanel panel = new JPanel();
            SetupSettingsTweens(panel);
            SetupSettingsContent(panel);
        return panel;
    }


    private static void SetupSettingsTweens(JPanel panel)
    {
        Tween.registerAccessor(Component.class, new ComponentAccessor());
        tweenManager = new TweenManager();
        Tween.to(panel, ComponentAccessor.WIDTH, 1000)
            .target(200)
            .ease(Cubic.INOUT)
            .repeatYoyo(-1, 200)
            .delay(500)
            .start(tweenManager);

    }

    private static void SetupSettingsContent(JPanel panel)
    {
        panel.add(new JButton("Button 1"));
    }
}

如果您想自己编译代码,您将需要以下三个资源:

  1. Universal Tween Engine library jar
  2. DrawingCanvas.java (包 aurelienribon.utils.swing)
  3. ComponentAccessor.java (包 aurelienribon.tweenaccessors.swing)

如果您想亲 body 验我的问题,无需复杂的项目设置,您可以下载 Eclipse Juno 项目,或可运行的 jar 文件:

如果您更愿意远离下载,这里是正在发生的事情的列表:

  1. 设置图形用户界面结构
  2. 设置补间要求(没什么特别的)
  3. 设置一个使用 SwingUtilities.invokeAndWait 的线程来调用一个名为 update() 的函数
  4. 每当调用 update() 时,它都会使用 Container.setSize() 为包含 Button 1 的 JPanel 上的大小更改设置动画。

非常感谢任何对此问题的帮助!谢谢 :)

附言如果这个问题有重复,我很抱歉。我在谷歌上搜索了很多,但我什至找不到与我的问题相关的任何内容。

最佳答案

我想在你的 update() 方法中说你应该更改 Button1 的首选大小并调用

container.revalidate();
container.repaint();

更改首选大小,revalidate() 更新布局,repaint() 反射(reflect)更改。

或者,您可以为 Button1 调用 setSize() 增加宽度,同时减少 Button2 的宽度,然后再次调用 repaint()(没有 revalidate( ) 因为重新验证会恢复原始布局)。

关于Java Swing GridBagLayout 面板调整大小问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15242692/

相关文章:

带阴影的 JavaFX 分层布局

java - 在 Eclipse 中获取 Google Wave 机器人编程的 javadoc

java - Spring boot服务从oracle数据库返回大数据集

java - 如何动态改变线条的颜色?

objective-c - 添加到图层后水平翻转 CCSprite

javascript - 非矩形、Canvas 或 SVG 形状内的背景动画?

java - 推荐的源代码管理目录结构?

java - JComboBox 中的问题

java - 为什么我的图像没有在 JPanel 上绘制?

javascript - 如何逐步绘制矢量路径? (拉斐尔.js)