java - 调整 Swing 窗口大小时如何避免闪烁?

标签 java swing dialog

我有一个对话框,其中的附加控件会导致对话框在出现时调整大小。有一天我可能会找到一种方法来制作动画,但现在我只满足于调整大小。问题是,它会闪烁。

我将问题简化为测试:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

/**
 * Shows flickering when resizing a dialog.
 */
public class FlickerTest extends FakeJDialog
{
    public FlickerTest()
    {
        super((Window) null, "Flicker Test");

        JButton button = new JButton("Bigger!");
        button.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent event)
            {
                Window window = SwingUtilities.getWindowAncestor((Component) event.getSource());
                window.setSize(window.getWidth(), window.getHeight() + 20);
            }
        });

        JPanel contentPane = new JPanel(new BorderLayout());
        contentPane.setOpaque(true);
        contentPane.add(button, BorderLayout.PAGE_START);

        JRootPane rootPane = new JRootPane();
        rootPane.setContentPane(contentPane);

        add(rootPane);

        setResizable(false);
        pack();
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) throws Exception
    {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new FlickerTest().setVisible(true);
            }
        });
    }
}

每次单击按钮时,窗口都会改变大小。在很长一段时间内,对话框底部变黑。通过录制我的屏幕,我能够得到一个演示它的屏幕截图:

enter image description here

我怎样才能避免这种情况?

进一步调查:

Dialog 的以下子类表现出与 JDialog 相同的闪烁:

import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Window;

import javax.swing.JLayeredPane;
import javax.swing.JRootPane;
import javax.swing.RootPaneContainer;

/**
 * Minimal subclass of Dialog required to cause the flickering.
 * If you comment out "implements RootPaneContainer", the flickering goes away.
 */
public class FakeJDialog extends Dialog implements RootPaneContainer
{
    public FakeJDialog(Window owner, String title)
    {
        super(owner, title, Dialog.ModalityType.MODELESS);
    }

    public JRootPane getRootPane()
    {
        throw new UnsupportedOperationException();
    }

    public Container getContentPane()
    {
        throw new UnsupportedOperationException();
    }

    public void setContentPane(Container contentPane)
    {
        throw new UnsupportedOperationException();
    }

    public JLayeredPane getLayeredPane()
    {
        throw new UnsupportedOperationException();
    }

    public void setLayeredPane(JLayeredPane layeredPane)
    {
        throw new UnsupportedOperationException();
    }

    public Component getGlassPane()
    {
        throw new UnsupportedOperationException();
    }

    public void setGlassPane(Component glassPane)
    {
        throw new UnsupportedOperationException();
    }
}

我觉得这很有趣,因为仅仅注释掉 implements RootPaneContainer 就足以完全改变行为。 Swing 或 AWT 中的某些东西显然正在寻找此接口(interface)并特殊处理这些组件。所以这表明 JDialog 的子类都无法避免这个问题。

最佳答案

我认为JDialog 没有办法解决这个问题。但是,java.awt.Dialog 没有这个问题。

关于java - 调整 Swing 窗口大小时如何避免闪烁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13618211/

相关文章:

android - 如何将 "Loading . . ."对话框添加到 Android 应用程序

java - JSON 解析为 Java - Android 应用程序

java - 上下文路径中的应用程序/无法启动 - Tomcat 8

java - 我没有收到任何错误,但数字不会添加到 JTextField

java - 如何为我的数独游戏制作 GUI? ( Swing )

android - 空指针异常 EditText - Android

java - 当我可以通过引用子类访问所有方法时,为什么还要引用基类?

java - 为什么 JAXB 继承在静态类中不起作用

Java jTable changeSelection 然后突出显示新的选定行

google-apps-script - 谷歌应用程序脚本: a select drop down list in google sheet