Java的动画的JLabel(Java Animate JLabel)

2019-06-18 06:57发布

所以我创造的中心,我想有那个开始在左下角和动作,动画风格,右下角的一组时,屏幕底部的JLabel的基本应用程序,以及静态图像。 要做到这一点,我创建了使用BorderLayout的一个JPanel的JFrame。 没有与一个ImageIcon一个JLabel添加到BorderLayout.CENTER和一个JPanel在BorderLayout.SOUTH。 我的代码,而草草写,远离漂亮,就是:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension; 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.BorderFactory;

public class GameWindow extends JPanel{

private static JLabel mainWindow, arrowLabel, arrowBox;
protected static JFrame frame;
protected static JPanel arrows;

public static int x = 600;

public GameWindow(){
    mainWindow = new JLabel("Center");
    arrowLabel = new JLabel("Moving");
    arrows = new JPanel();
    arrows.setSize(600, 100);
    arrows.setLayout(null);
    arrowBox = new JLabel("");
    arrowBox.setBounds(0, 0, 150, 100);
    arrowBox.setPreferredSize(new Dimension(150, 100));
    arrowBox.setBorder(BorderFactory.createLineBorder(Color.black));
    arrows.add(arrowBox);
    this.setSize(600,600);
    this.setLayout(new BorderLayout());
    this.add(mainWindow, BorderLayout.CENTER);
    this.add(arrows, BorderLayout.SOUTH);
}

public static void main(String[] args)
{
    GameWindow g = new GameWindow();
    frame = new JFrame("Sword Sword Revolution");
    frame.add(g);
    frame.setSize(600,600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    Timer t = new Timer(1000, new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {
            arrows.add(arrowLabel);
            arrowLabel.setBounds(x, 100, 100, 100);
            x-=50;
            arrows.repaint();
            frame.repaint();
        }

    });
    t.start();
}

}

在该中心的JLabel的ImageIcon的显示正常,并用边界空的JLabel出现在底部,但我不能用箭头图像第二个JLabel来显示在屏幕上。 最后,我会变成scheduleAtFixedRate连续移动的JLabel,但现在我甚至不能出现在屏幕上的图像。

我也明白,我将最有可能无法使用的FlowLayout这一点,据我了解它不允许你设置组件的位置。 我试着用空的布局,但随着空布局与边框空的JLabel不会出现。 我可以勉强做出来的边框顶部在框架的底部边缘,但即使setLocation我不能让它出现,我想它。

很显然,我的思维过程是有缺陷的,所以任何帮助,将不胜感激。

Answer 1:

您在使用线程的都是错误的Swing应用程序。 你不应该试图在后台线程中添加或删除组件,而是应该使用一个Swing计时器来做到这一点Swing事件线程上。

另外,你是什么意思:

我想有一个滚动的JLabel在屏幕的底部

请澄清你想达到的效果。

另外,关于,

我也明白,我将最有可能无法使用的FlowLayout这一点,据我了解它不允许你设置组件的位置。 我试着用空的布局,但随着空布局与边框空的JLabel不会出现。 我可以勉强做出来的边框顶部在框架的底部边缘,但即使setLocation我不能让它出现,我想它。

不,不要为这种情况使用空布局。 有更好的布局管理器,可以帮助你在一个更清洁更独立于平台的方式来构建应用程序。

编辑3
关于:

为了澄清,在屏幕的底部我想在最右下角的JLabel,然后在挥杆计时器,选择JLabel将逐步直到将屏幕向左移动。 如果我能得到setLocation工作,基本的前提是有一个变量x设置为600,然后每秒递减由x说50,然后在屏幕上的新位置重画的JLabel。 基本的动画。

我会在屏幕的底部的两侧牵着你的JLabel或通过覆盖其显示没有一个JLabel图像的目的创建一个JPanel paintComponent(...)方法。 如果你使用它作为一个容器,那么,它的布局应该是空的,但GUI的其余部分不应该使用空布局。 Swing的计时器会简单地改变JLabel的位置,然后调用repaint()它的JPanel /容器上。 如果你去了后一条道路,你会画在JPanel的形象paintComponent(...)使用方法g.drawImage(myImage, x, y)和你的计时器会改变x和/或y和调用repaint()上图纸的JPanel。

此外,您可能不希望在你的定时器添加一个JLabel而是简单地移动这已经显示在GUI中的JLabel。

另外,为了避免焦点问题,不使用KeyListener的捕获键盘输入,而是使用键绑定。 谷歌将引导您对这个结构有很大的教程。

编辑4
例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.EnumMap;

import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class AnimateExample extends JPanel {
   public static final String DUKE_IMG_PATH = 
         "https://duke.kenai.com/iconSized/duke.gif";
   private static final int PREF_W = 800;
   private static final int PREF_H = 800;
   private static final int TIMER_DELAY = 20;
   private static final String KEY_DOWN = "key down";
   private static final String KEY_RELEASE = "key release";
   public static final int TRANSLATE_SCALE = 3;
   private static final String BACKGROUND_STRING = "Use Arrow Keys to Move Image";
   private static final Font BG_STRING_FONT = new Font(Font.SANS_SERIF,
         Font.BOLD, 32);
   private EnumMap<Direction, Boolean> dirMap = 
         new EnumMap<AnimateExample.Direction, Boolean>(Direction.class);
   private BufferedImage image = null;
   private int imgX = 0;
   private int imgY = 0;
   private int bgStringX; 
   private int bgStringY; 

   public AnimateExample() {
      for (Direction dir : Direction.values()) {
         dirMap.put(dir, Boolean.FALSE);
      }
      try {
         URL imgUrl = new URL(DUKE_IMG_PATH);
         image = ImageIO.read(imgUrl);
      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }

      new Timer(TIMER_DELAY, new TimerListener()).start();

      // here we set up our key bindings
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();
      for (final Direction dir : Direction.values()) {

         // for the key down key stroke
         KeyStroke keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0,
               false);
         inputMap.put(keyStroke, dir.name() + KEY_DOWN);
         actionMap.put(dir.name() + KEY_DOWN, new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
               dirMap.put(dir, true);
            }
         });

         // for the key release key stroke
         keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0, true);
         inputMap.put(keyStroke, dir.name() + KEY_RELEASE);
         actionMap.put(dir.name() + KEY_RELEASE, new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
               dirMap.put(dir, false);
            }
         });
      }

      FontMetrics fontMetrics = getFontMetrics(BG_STRING_FONT);
      int w = fontMetrics.stringWidth(BACKGROUND_STRING);
      int h = fontMetrics.getHeight();

      bgStringX = (PREF_W - w) / 2;
      bgStringY = (PREF_H - h) / 2;
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g.setFont(BG_STRING_FONT);
      g.setColor(Color.LIGHT_GRAY);
      g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
            RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
      g.drawString(BACKGROUND_STRING, bgStringX, bgStringY);

      if (image != null) {
         g.drawImage(image, imgX, imgY, this);
      }
   }

   private class TimerListener implements ActionListener {
      public void actionPerformed(java.awt.event.ActionEvent e) {
         for (Direction dir : Direction.values()) {
            if (dirMap.get(dir)) {
               imgX += dir.getX() * TRANSLATE_SCALE;
               imgY += dir.getY() * TRANSLATE_SCALE;
            }
         }
         repaint();
      };
   }

   enum Direction {
      Up(KeyEvent.VK_UP, 0, -1), Down(KeyEvent.VK_DOWN, 0, 1), Left(
            KeyEvent.VK_LEFT, -1, 0), Right(KeyEvent.VK_RIGHT, 1, 0);

      private int keyCode;
      private int x;
      private int y;

      private Direction(int keyCode, int x, int y) {
         this.keyCode = keyCode;
         this.x = x;
         this.y = y;
      }

      public int getKeyCode() {
         return keyCode;
      }

      public int getX() {
         return x;
      }

      public int getY() {
         return y;
      }

   }

   private static void createAndShowGui() {
      AnimateExample mainPanel = new AnimateExample();

      JFrame frame = new JFrame("Animate Example");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

这将创造这个GUI:



Answer 2:

三种可能性:

  • 您可以使用像图书馆SlidingLayout来创建的代码非常几行这样的过渡。 您将无法调整的动画,但你的生活会更容易。

  • 您可以使用动画引擎像通用吐温引擎配置用手一切,就像你要调整动画(第LIB使用这一个引擎盖下)。 使用这种引擎能够绘制你想要什么:位置,颜色,字体大小,...

  • 您可以通过手代码一切拥抱地狱是动画界:)

最后,你将能够快速创建这样的动画(这是一个工具,我目前工作的,用于配置使用LibGDX游戏框架Android开发的Eclipse项目):

我做了这些库以缓解疼痛是UI动画(我爱UI设计:P)。 我释放了他们的开源(免费使用,许可的Apache-2),希望他们可以帮助一些人了。

如果你需要帮助,就为每个库专用的帮助论坛。



Answer 3:

很简单,看看这个:

javax.swing.JLabel lb = new javax.swing.JLabel();
Image image = Toolkit.getDefaultToolkit().createImage("Your animated GIF");
ImageIcon xIcon = new ImageIcon(image);
xIcon.setImageObserver(this);
lb.setIcon(xIcon);


文章来源: Java Animate JLabel