追加のコントロールが表示されたときにダイアログのサイズを変更するダイアログがあります。いつの日かアニメーション化する方法が見つかるかもしれませんが、今のところサイズを変更するだけで満足しています。問題は、ちらつきです。
問題をテストに減らしました:
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);
}
});
}
}
ボタンをクリックするたびに、ウィンドウのサイズが変わります。かなりの時間、ダイアログの下部が黒くなります。画面を記録することで、それを示すスクリーンショットを取得できました。
どうすればこれを回避できますか?
さらなる調査:
次の 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 の何かが明らかにこのインターフェースを探し、それらのコンポーネントを特別に扱います。したがって、これは、JDialog のサブクラスが問題を回避しないことを示唆しています。