你说得对,ImageIO的是不是一种选择,为支持保证是GIF唯一的动画格式。
你说你不想制作一个动画线程,但是一个JavaFX动画对象怎么样,比如Timeline?
public JComponent createAnimationComponent(List<BufferedImage> images,
List<Long> durations) {
Objects.requireNonNull(images, "Image list cannot be null");
Objects.requireNonNull(durations, "Duration list cannot be null");
if (new ArrayList<Object>(images).contains(null)) {
throw new IllegalArgumentException("Null image not permitted");
}
if (new ArrayList<Object>(durations).contains(null)) {
throw new IllegalArgumentException("Null duration not permitted");
}
int count = images.size();
if (count != durations.size()) {
throw new IllegalArgumentException(
"Lists must have the same number of elements");
}
ImageView view = new ImageView();
ObjectProperty<Image> imageProperty = view.imageProperty();
Rectangle imageSize = new Rectangle();
KeyFrame[] frames = new KeyFrame[count];
long time = 0;
for (int i = 0; i < count; i++) {
Duration duration = Duration.millis(time);
time += durations.get(i);
BufferedImage bufImg = images.get(i);
imageSize.add(bufImg.getWidth(), bufImg.getHeight());
Image image = SwingFXUtils.toFXImage(bufImg, null);
KeyValue imageValue = new KeyValue(imageProperty, image,
Interpolator.DISCRETE);
frames[i] = new KeyFrame(duration, imageValue);
}
Timeline timeline = new Timeline(frames);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
JFXPanel panel = new JFXPanel();
panel.setScene(new Scene(new Group(view)));
panel.setPreferredSize(imageSize.getSize());
return panel;
}
(我不知道为什么有必要明确地设置JFXPanel的首选大小,但它是。可能是一个错误。)
注意像所有的JavaFX代码,它必须运行,在JavaFX应用程序线程中。如果你使用的是Swing应用程序,你可以这样做:
public JComponent createAnimationComponentFromAWTThread(
final List<BufferedImage> images,
final List<Long> durations)
throws InterruptedException {
final JComponent[] componentHolder = { null };
Platform.runLater(new Runnable() {
@Override
public void run() {
synchronized (componentHolder) {
componentHolder[0] =
createAnimationComponent(images, durations);
componentHolder.notifyAll();
}
}
});
synchronized (componentHolder) {
while (componentHolder[0] == null) {
componentHolder.wait();
}
return componentHolder[0];
}
}
但这还不够。您首先必须通过调用Application.launch来初始化JavaFX,无论是使用显式方法调用还是通过将Application子类指定为主类来隐式地调用。
来源
2015-09-06 01:03:02
VGR
我不会使用JLabel。我会使用paintComponent方法直接在JPanel上绘制图像。你的图像有多大? –
图像大小可以是任何图标到监视器分辨率(不大)。我实际上并不需要JLabel(我将不得不重写一个当前使用JLabel的应用程序)。但主要是,我要求JLabel兼容性是一种简单的方法:一个“(Toolkit)映像”,其中包含所有帧。 –
使用不同尺寸的图片,动画更加刺激。您希望每个图像显示多长时间? –