问题描述
我正在尝试在JComboBox中使用动画(GIF)图标。
I'm trying to use animated (GIF) icons in a JComboBox.
由于DefaultListCellRenderer基于JLabel,因此将ImageIcons放入其中时直接受支持。 ComboBoxModel。
As the DefaultListCellRenderer is based on JLabel, ImageIcons are directly supported when putting them into the the ComboBoxModel.
但是,这不适用于动画GIF。
However this does not work with animated GIFs.
在下拉菜单中,它们不显示在除非选择了所有选项,否则所有选项都可以使用(尽管在常规JLabel中使用GIF还是可以的)
In the dropdown they are not show at all unless they are selected (the GIFs do work when used in a regular JLabel though)
填充组合框的代码很简单:
The code to populate the combobox is straight forward:
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,它们都将显示得很好)
icon_one.gif is the static one and is shown without any problems. The others are animated. (The images are loaded correctly because if I assign any of those icons to a JLabel directly they are displayed just fine)
我也试图使用基于JPanel的我自己的ListCellRenderer(受此问题的答案启发:)。
I also tried to use my own ListCellRenderer based on a JPanel (inspired by the answer to this question: Java animated GIF without using a JLabel).
效果更好,但也不理想。仅当在显示下拉菜单时将鼠标移到图标上时,才会显示图标。因此,我猜这是一个重新出现的问题,尽管我不知道在哪里
That works a bit better but not ideal either. The icons are only shown if I move the mouse over them while the dropdown is shown. So I guess it's a repaiting issue, although I don't know where
这是我的JPanel中实现ListCellRenderer接口的部分。
This is the part from my JPanel that implements the ListCellRenderer interface.
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()的代码
The call to revalidate() and repaint() was inspired by looking at the code of JLabel.setIcon()
paint()方法也很简单:
The paint() method is straight forward as well:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image != null)
{
g.drawImage(image, 0, 0, this);
}
}
有什么想法吗?我真的不需要这些图标在下拉菜单中进行动画处理(尽管那会很好),但我至少希望看到静态图像。
Any ideas? I don't really need those icons to be animated in the dropdown (although that would be nice) but I would at least like to see the static images.
推荐答案
此示例的灵感来自
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);
}
}
这篇关于在JComboBox中使用动画GIF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!