2012-03-04 3 views
2

Я пытаюсь использовать анимированные (GIF) значки в JComboBox.Использование анимированного GIF в JComboBox

Поскольку DefaultListCellRenderer основан на JLabel, ImageIcons поддерживаются непосредственно при вставке их в ComboBoxModel.

Однако это не работает с анимированными GIF.

В раскрывающемся списке они не показывают на всех, если они не будут выбраны (ГИФС работает при использовании в обычном JLabel, хотя)

Код для заполнения выпадающего прямо вперед:

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 непосредственно они отображаются нормально)

Я также попытались использовать свой собственный ListCellRenderer на основе JPanel (вдохновленный ответ на этот вопрос : Java animated GIF without using a 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; 
} 

Вызов перепроверить() и перекрасить() был вдохновлен, глядя на код JLabel.setIcon()

краска() метод является прямым, а также:

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

Любые идеи? Мне действительно не нужны эти значки, которые будут анимированы в раскрывающемся списке (хотя это было бы неплохо), но мне бы хотелось увидеть статические изображения.

+0

на аналогичный вопрос См http://stackoverflow.com/questions/575782/how-to-display-animation-in-a-jtable-cell. –

ответ

2

Этот пример был вдохновлен 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); 
    } 
} 
+0

Спасибо, отлично работает. –

+0

+1 хороший, где рождается '(infoflags & (FRAMEBITS | ALLBITS))' – mKorbel

+0

@mKorbel ссылка от: src/java/awt/Component.java # imageUpdate (...) – aterai

Смежные вопросы