所以我创造的中心,我想有那个开始在左下角和动作,动画风格,右下角的一组时,屏幕底部的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我不能让它出现,我想它。
很显然,我的思维过程是有缺陷的,所以任何帮助,将不胜感激。
您在使用线程的都是错误的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:
三种可能性:
最后,你将能够快速创建这样的动画(这是一个工具,我目前工作的,用于配置使用LibGDX游戏框架Android开发的Eclipse项目):
我做了这些库以缓解疼痛是UI动画(我爱UI设计:P)。 我释放了他们的开源(免费使用,许可的Apache-2),希望他们可以帮助一些人了。
如果你需要帮助,就为每个库专用的帮助论坛。
很简单,看看这个:
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);