Skip to main content

font flicker on transition ...

4 replies [Last post]
Joined: 2007-11-25

I'm not sure is this a Timing Framework, Animated Transitions or general Java2D problem ...

I'm using animatedtransitions library to make transition fade effect between panel change. But, if I use 6u10+, JLabel's (or other text component) text flicker on transition. This happens if the component is not opaque and the parent panel's background is filled using AlphaComposite.SRC_OVER < 1.0.

How to fix this ?

Try code bellow to see.


<br />
public class TransitionProblemPanel extends JPanel {</p>
<p>	private JPanel content;<br />
	private JPanel panelOne;<br />
	private JPanel panelTwo;</p>
<p>	private enum ScreenType {<br />
<p>	private ScreenType currentScreen;<br />
	private ScreenTransition screenTransition;</p>
<p>	private Animator animator;</p>
<p>	public TransitionProblemPanel() {<br />
		setLayout(new BorderLayout());<br />
<p>		content = new JPanel();<br />
		content.setLayout(new BorderLayout());<br />
<p>		initViews();</p>
<p>		content.add(panelOne);</p>
<p>		add(content, BorderLayout.CENTER);</p>
<p>		initEffects();<br />
<p>	public void showPanelOne() {<br />
		startTransition(ScreenType.PANELONE);<br />
<p>	public void showPanelTwo() {<br />
		startTransition(ScreenType.PANELTWO);<br />
<p>	private void initViews() {<br />
		panelOne = new JPanel();<br />
		panelOne.setOpaque(false);<br />
		panelOne.setLayout(new FlowLayout(FlowLayout.LEFT));</p>
<p>		panelTwo = new JPanel();<br />
		panelTwo.setOpaque(false);<br />
		panelTwo.setLayout(new FlowLayout(FlowLayout.RIGHT));</p>
<p>		RoundPanel roundPanelOne = new RoundPanel();<br />
		JTextArea textArea = new JTextArea("Some text is here and it flickers on transition");<br />
		textArea.setOpaque(false);<br />
		textArea.setPreferredSize(new Dimension(100, 200));<br />
		textArea.setLineWrap(true);<br />
		textArea.setFont(textArea.getFont().deriveFont(14f));<br />
<p>		RoundPanel roundPanelTwo = new RoundPanel();<br />
		JLabel label = new JLabel("Text text text text");<br />
		label.setOpaque(false);<br />
<p>		panelOne.add(roundPanelOne);<br />
		panelTwo.add(roundPanelTwo);<br />
<p>	private void initEffects() {<br />
		currentScreen = ScreenType.PANELONE;<br />
		animator = new Animator(500);<br />
		animator.setAcceleration(.2f);<br />
		animator.setDeceleration(.4f);<br />
		screenTransition = new ScreenTransition(content, new ContentTransitionTarget(), animator);</p>
<p>		CompositeEffect effects = new CompositeEffect();<br />
		effects.addEffect(new FadeIn());<br />
		effects.addEffect(new FadeOut());<br />
		EffectsManager.setEffect(content, effects, EffectsManager.TransitionType.CHANGING);<br />
<p>	private void startTransition(ScreenType newScreen) {<br />
		if (newScreen != currentScreen) {<br />
			currentScreen = newScreen;<br />
			screenTransition.start();<br />
		}<br />
<p>	private class ContentTransitionTarget implements TransitionTarget {<br />
		public void setupNextScreen() {<br />
			content.removeAll();<br />
			switch (currentScreen) {<br />
				case PANELONE:<br />
					content.add(panelOne, BorderLayout.CENTER);<br />
					break;<br />
				case PANELTWO:<br />
					content.add(panelTwo, BorderLayout.CENTER);<br />
					break;<br />
				default:<br />
					break;<br />
			}<br />
		}<br />
<p>	private class RoundPanel extends JPanel {</p>
<p>		private float alpha = 0.4f;</p>
<p>		public RoundPanel() {<br />
			super();<br />
			init();<br />
<p>		private void init() {<br />
			setOpaque(false);<br />
<p>		public float getAlpha() {<br />
			return alpha;<br />
<p>		public void setAlpha(float alpha) {<br />
			this.alpha = alpha;<br />
<p>		@Override<br />
		protected void paintComponent(Graphics g) {<br />
			Graphics2D g2d = (Graphics2D) g.create();<br />
			g2d.setColor(getBackground());<br />
			g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));<br />
			g2d.fillRoundRect(1, 1, getWidth() - 1, getHeight() - 1, 10, 10);<br />
<p>			super.paintComponent(g);<br />
		}<br />
	}<br />
}<br />

<br />
public class TransitionProblemFrame extends JFrame {</p>
<p>	private TransitionProblemPanel transitionPanel;<br />
	private JPanel panelButtons;</p>
<p>	public TransitionProblemFrame() {<br />
		transitionPanel = new TransitionProblemPanel();</p>
<p>		panelButtons = new JPanel();<br />
		JButton buttonOne = new JButton("Panel One");<br />
		buttonOne.addActionListener(new ActionListener() {<br />
			@Override<br />
			public void actionPerformed(ActionEvent e) {<br />
				transitionPanel.showPanelOne();<br />
			}<br />
		});<br />
		JButton buttonTwo = new JButton("Panel two");<br />
		buttonTwo.addActionListener(new ActionListener() {<br />
			@Override<br />
			public void actionPerformed(ActionEvent e) {<br />
				transitionPanel.showPanelTwo();<br />
			}<br />
		});<br />
		panelButtons.setLayout(new FlowLayout(FlowLayout.CENTER));<br />
		panelButtons.setBackground(Color.lightGray);<br />
		panelButtons.add(buttonOne);<br />
<p>		((JPanel)getContentPane()).setBackground(new Color(100, 200, 254));</p>
<p>		add(transitionPanel, BorderLayout.CENTER);<br />
		add(panelButtons, BorderLayout.SOUTH);</p>
<p>		setSize(500, 300);<br />
		setLocationRelativeTo(null);<br />
		setDefaultCloseOperation(EXIT_ON_CLOSE);<br />
		setVisible(true);<br />
<p>	public static void main(String[] args) {<br />
		SwingUtilities.invokeLater(new Runnable() {<br />
			@Override<br />
			public void run() {<br />
				try {<br />
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());<br />
				}<br />
				catch (Exception e) {}</p>
<p>				new TransitionProblemFrame();<br />
			}<br />
		});<br />
	}<br />
}<br />

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Joined: 2007-11-25

Ok, since it's so hard to try this, then go to , watch in full screen, 2:28, look at the text during the transition from one view to another and you will see.

Joined: 2007-11-25

Did anyone at least try this ?

Joined: 2004-11-17

As you might have noticed, the developers of these two projects have since moved to other platforms (Chet to Flex and Romain to Android). This may explain lack of response from their side.

To your question - if you're running under 6u10 on Vista, then you might be running into the switch from native to bundled font rasterizer. The native font rasterizer (which makes rendering of Segoe UI font consistent with the OS) only works on opaque surfaces (SrcOver with alpha=1.0). Once the surface is non-opaque, Java2D will use the bundled rasterizer which is inferior in rendering Segoe UI.

I have run into this issue in Substance in skins that use translucent colors for disabled controls. In this case, i create the opaque color by complementing the translucent FG color with the parent BG color to be fully opaque. This may not work well on non-uniform background, but at least the native font rasterizer is used.

Impressive video, by the way.


Joined: 2007-11-25

Yes I know that Chet and Romain left Sun, and Chet stoped developing AnimatedTransitions, but I hoped that someone from the Java2D team might answer ...
I'm using 6u12, and yes this started happening since 6u10 so that must be problem, like you said, with font rasterizer and non opaque background. I will try the solution you used but in my case background is in most cases an image. I should also look in source code of animatedtransitions.
Maybe Sun will fix this one day ...