JDK-4908277 : Animated GIF does not play inside JTable, customized TableCellRenderer
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.3.1,1.4.1,1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2003-08-18
  • Updated: 2003-08-19
  • Resolved: 2003-08-19
Description

Name: jk109818			Date: 08/18/2003


FULL PRODUCT VERSION :
C:\Documents and Settings\ebelin>java -version
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

FULL OS VERSION :
C:\Documents and Settings\ebelin>ver
Microsoft Windows XP [������������������������������������ 5.1.2600]
--(it's localized, Russian version)

EXTRA RELEVANT SYSTEM CONFIGURATION :
Nothing else seems to be relevant: bug was verified on number of other WIndows XP platforms, including US version.

A DESCRIPTION OF THE PROBLEM :
Animated GIF can be played in various Swing component just as regular image... but not inside the JTable component.

In fact, the code I'm attaching below does exactly this: it plays the image outside JTable in a JLabel component and inside JTable, using three different CellRenderers.  The problem is that none of the renderers play the image.  The only effect I was able to achive is:

if you resize the JFrame, then the next frame of animated GIF is shown.  Just start the application, wait till image is played in the top component and try to resize the frame many times.  You will see changes in second and third columns.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Use the source code supplied (you have to find an animated GIF though---there's no way to attach binaries to this form) and see animated GIF fail to play inside of JTable

2. Try to write your own TableCellRenderer to play animated GIFs.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Animated GIF should play inside JTable just as it is played in a regular Swing component.
ACTUAL -
Animated GIF is not played when rendered inside of the JTable.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
No error messages reported by the system.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class TableAnimDemo {

	public static void main(String[] args) {
		JFrame f = new JFrame("Table Animation Problem Demo");
		f.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				super.windowClosing(e);
				System.exit(0);
			}
		});
		Box box = Box.createVerticalBox();
		f.getContentPane().add(box);

		Icon icon = new ImageIcon("goodbad.gif");
		System.out.println(
			"Icon loaded.  Width: "
				+ icon.getIconWidth()
				+ "px, height: "
				+ icon.getIconHeight()
				+ "px.");

		JPanel panel = new JPanel();
		box.add(panel);

		JLabel label = new JLabel();
		label.setText("Animation Outside Table:");
		label.setIcon(icon);
		panel.add(label);

		Object[][] data = { { icon, icon, icon }
		};
		Object[] names =
			{ "Default Renderer", "Subclassed Renderer", "JLable Renderer" };
		JTable table = new JTable(data, names);
		box.add(table);
		setupColumns(table);

		f.pack();
		f.show();
	}

	private static void setupColumns(JTable table) {
		TableColumnModel columnModel = table.getColumnModel();
		TableColumn column = null;

		column = columnModel.getColumn(1);
		column.setCellRenderer(new DefaultTableCellRenderer() {
			public Component getTableCellRendererComponent(
				JTable table,
				Object value,
				boolean isSelected,
				boolean hasFocus,
				int row,
				int column) {

				super.getTableCellRendererComponent(
					table,
					value,
					isSelected,
					hasFocus,
					row,
					column);
				if (value instanceof Icon)
					setIcon((Icon) value);
				return this;
			}

		});

		column = columnModel.getColumn(2);
		column.setCellRenderer(new DefaultTableCellRenderer() {
			public Component getTableCellRendererComponent(
				JTable table,
				Object value,
				boolean isSelected,
				boolean hasFocus,
				int row,
				int column) {
				super.getTableCellRendererComponent(
					table,
					value,
					isSelected,
					hasFocus,
					row,
					column);
				if (value instanceof Icon)
					return new JLabel((Icon) value);
				else
					return this;
			}

		});
	}

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
None found.
(Incident Review ID: 186695) 
======================================================================

Comments
EVALUATION The renderer component is used as a ruber stamp, it only exists in the containment hierarchy at the time it is painted after that it is removed. An animated icon works by calling the imageUpdate method when a new frame is available, the receiver (JLabel in this case) will then invoke repaint to show the new frame. When a label is used as a renderer in a table when imageUpdate is invoked the parent is invalid and the repaint does nothing. If you want to display an updating widget in a renderer based component you will need to invoke repaint on the table. ###@###.### 2003-08-19
2003-08-19