在JComboBox中使用动画GIF

我正在尝试在JComboBox中使用动画(GIF)图标。

由于DefaultListCellRenderer基于JLabel,因此在将它们放入ComboBoxModel时会直接支持ImageIcons。

但是,这不适用于动画GIF。

在下拉列表中,除非选中它们,否则它们根本不会显示(虽然GIF在常规JLabel中使用时可以正常工作)

填充combobox的代码很简单:

ImageIcon[] data = new ImageIcon[4]; data[0] = new ImageIcon("icon_one.gif"); data[1] = new ImageIcon("icon_two.gif"); data[2] = new ImageIcon("icon_three.gif"); data[3] = new ImageIcon("icon_four.gif"); ComboBoxModel model = new DefaultComboBoxModel(data); setModel(model); 

icon_one.gif是静态的,显示没有任何问题。 其他的都是动画的。 (图像正确加载,因为如果我将这些图标中的任何一个直接分配给JLabel,它们就显示得很好)

我还试图使用我自己的基于JPanel的ListCellRenderer(灵感来自这个问题的答案: Java动画GIF而不使用JLabel )。

这样做有点好但不理想。 只有在显示下拉列表时将鼠标移到它们上方才会显示图标。 所以我想这是一个修复问题,虽然我不知道在哪里

这是我的JPanel实现ListCellRenderer接口的部分。

 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { this.image = ((ImageIcon)value).getImage(); if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } revalidate(); repaint(); return this; } 

调用revalidate()和repaint()的灵感来自于查看JLabel.setIcon()的代码

paint()方法也是直截了当的:

 public void paintComponent(Graphics g) { super.paintComponent(g); if (image != null) { g.drawImage(image, 0, 0, this); } } 

有任何想法吗? 我真的不需要在下拉列表中对这些图标进行动画处理(虽然这样会很好),但我至少希望看到静态图像。

此示例的灵感来自AnimatedIconTableExample.java

 import java.awt.*; import java.awt.image.*; import java.net.*; import javax.swing.*; import javax.swing.plaf.basic.*; class MainPanel { public JComponent makeUI() { JComboBox combo = new JComboBox(); URL url1 = getClass().getResource("static.png"); URL url2 = getClass().getResource("animated.gif"); combo.setModel(new DefaultComboBoxModel(new Object[] { new ImageIcon(url1), makeImageIcon(url2, combo, 1) })); JPanel p = new JPanel(); p.add(combo); return p; } private static ImageIcon makeImageIcon( URL url, final JComboBox combo, final int row) { ImageIcon icon = new ImageIcon(url); icon.setImageObserver(new ImageObserver() { //http://www2.gol.com/users/tame/swing/examples/SwingExamples.html //AnimatedIconTableExample.java @Override public boolean imageUpdate( Image img, int infoflags, int x, int y, int w, int h) { if(combo.isShowing() && (infoflags & (FRAMEBITS|ALLBITS)) != 0) { if(combo.getSelectedIndex()==row) { combo.repaint(); } BasicComboPopup p = (BasicComboPopup) combo.getAccessibleContext().getAccessibleChild(0); JList list = p.getList(); if(list.isShowing()) { list.repaint(list.getCellBounds(row, row)); } } return (infoflags & (ALLBITS|ABORT)) == 0; }; }); return icon; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new MainPanel().makeUI()); f.setSize(320, 240); f.setLocationRelativeTo(null); f.setVisible(true); } }