动画Swing效果可显示全分辨率图像

时间:2009-12-14 23:39:41

标签: java swing animation

我有一个包含大量图像缩略图的编辑器。我想双击图像以使用模态未修饰的对话框显示全分辨率图像。理想情况下,这将是动画,以显示图像在屏幕中心放大到全分辨率,然后任何点击都会使图像消失,或者缩小或消失。

我并不关心建立一个确切的行为,我只想要一些光滑的东西。我已经找到了大量的JavaScript示例,但有没有为Swing构建的内容?

2 个答案:

答案 0 :(得分:1)

这段代码或多或少地起作用了...... 我设置对话框位置的方式仍有问题......

希望它有所帮助。

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.reflect.InvocationTargetException;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class OpenImageZooming {

 private static final int NB_STEPS = 30;

 private static final long OPENING_TOTAL_DURATION = 3000;

 public static void main(String[] args) {
  OpenImageZooming me = new OpenImageZooming();
  me.openImage(args[0]);
 }

 private JFrame frame;
 private JDialog dialog;
 private JPanelZooming panelZooming;

 private void openImage(final String imagePath) {
  SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    frame = new JFrame();
    frame.setTitle("Open image with zoom");
    JPanel p = new JPanel(new BorderLayout());
    p.add(new JLabel("click on button to display image"), BorderLayout.CENTER);
    JButton button = new JButton("Display!");
    frame.setContentPane(p);
    button.addActionListener(new ActionListener() {

     public void actionPerformed(ActionEvent e) {
      Thread t = new Thread() {

       @Override
       public void run() {
        displayImaggeWithProgressiveZoom(imagePath);
       }

      };
      t.start();

     }

    });
    p.add(button, BorderLayout.SOUTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300, 100);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
   }
  });
 }

 protected void displayImaggeWithProgressiveZoom(String imagePath) {
  try {
   final BufferedImage image = ImageIO.read(new File(imagePath));

   for (int i = 0; i < NB_STEPS; i++) {
    displayDialog(i, NB_STEPS, image);

    Thread.sleep(OPENING_TOTAL_DURATION / NB_STEPS);
   }

  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

 private void displayDialog(final int i, final int nbSteps, final BufferedImage image) {

  try {
   SwingUtilities.invokeAndWait(new Runnable() {
    public void run() {
     if (dialog == null) {
      dialog = new JDialog(frame);
      dialog.setUndecorated(true);
      dialog.setModal(false);
      panelZooming = new JPanelZooming(image);
      dialog.setContentPane(panelZooming);
      dialog.setSize(0, 0);
      dialog.setLocationRelativeTo(frame);
      dialog.setVisible(true);

     }
     int w = (i + 1) * image.getWidth() / nbSteps;
     int h = (i + 1) * image.getHeight() / nbSteps;

     panelZooming.setScale((double) (i + 1) / nbSteps);
     dialog.setSize(w, h);
     dialog.setLocationRelativeTo(null);
    }
   });
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

 @SuppressWarnings("serial")
 public static class JPanelZooming extends JPanel {

  private BufferedImage image;

  private double scale = 1.0d;

  public JPanelZooming(BufferedImage image) {
   this.image = image;
  }

  @Override
  protected void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2 = (Graphics2D) g;
   AffineTransform at = g2.getTransform();
   AffineTransform oldTransform = (AffineTransform) at.clone();
   at.scale(scale, scale);
   g2.setTransform(at);
   g2.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
   g2.setTransform(oldTransform);

  }

  public void setScale(double scale) {
   this.scale = scale;
  }

 }
}

答案 1 :(得分:0)

您可以创建一个自定义控件,以所需的比例显示图像。

1)使用ImageIO.read(file)从您想要的图像文件创建BufferedImage(您也可以从InputStream创建它)

2)扩展JComponent或Canvas类并重载paint函数以使用Graphics.DrawImage()绘制动画图像,并根据窗口打开的时间设置宽度和高度。设置一个计时器或使用另一个线程重复让组件重绘自己,无论你想要多长时间播放动画。

我对自定义模态对话框没有做太多(我经常发现它们很烦人),但你可以使用JDialog和你的组件。