Java Animate JLabel

Поэтому я создаю базовое приложение, в котором я хочу иметь JLabel в нижней части экрана, который начинается в левом нижнем углу и перемещается, стиль анимации, в правый нижний угол за определенное время и статическое изображение в центре , Для этого я создал JFrame с JPanel, используя BorderLayout. Существует JLabel с ImageIcon, добавленным в 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(); } 

}

ImageIcon в центре JLabel выглядит отлично, а пустой JLabel с рамкой появляется внизу, но я не могу получить вторую JLabel с изображением стрелки, которое будет отображаться на экране. В конце концов я перейду на scheduleAtFixedRate, чтобы постоянно перемещать JLabel, но сейчас я даже не могу заставить изображение появляться на экране.

Я также понимаю, что я, скорее всего, не смогу использовать FlowLayout для этого, поскольку я понимаю, что он не позволяет вам устанавливать местоположение ваших компонентов. Я попытался использовать нулевой макет, но с нулевым макетом пустой JLabel с рамкой не появляется. Я едва могу разглядеть верхнюю границу границы в нижнем краю frameworks, но даже с setLocation я не могу заставить ее отображаться там, где я ее хочу.

Очевидно, что мой мыслительный процесс испорчен, поэтому любая помощь будет оценена.

Использование Swing-приложений для использования Swing-приложений неверно. Вы не должны пытаться добавлять или удалять компоненты в фоновом streamе, но вместо этого следует использовать таймер Swing для этого в streamе событий Swing.

Кроме того, что вы подразумеваете под:

Я хочу прокрутить JLabel в нижней части экрана

Просьба уточнить эффект, который вы пытаетесь достичь.

Кроме того,

Я также понимаю, что я, скорее всего, не смогу использовать FlowLayout для этого, поскольку я понимаю, что он не позволяет вам устанавливать местоположение ваших компонентов. Я попытался использовать нулевой макет, но с нулевым макетом пустой JLabel с рамкой не появляется. Я едва могу разглядеть верхнюю границу границы в нижнем краю frameworks, но даже с setLocation я не могу заставить ее отображаться там, где я ее хочу.

Нет, не используйте нулевой макет для этой ситуации. Есть намного лучшие менеджеры макетов, которые могут помочь вам создать ваше приложение в более чистом, более независимом от платформы образом.

Редактировать 3
Что касается:

Чтобы уточнить, внизу экрана я хочу JLabel в дальнем правом углу, затем в таймере поворота JLabel будет постепенно перемещаться влево, пока не покинет экран. Если бы я мог заставить setLocation работать, основная предпосылка заключалась бы в том, чтобы переменная x установлена ​​в 600, а затем каждый второй декремент x, скажем 50, а затем перерисовывал JLabel в новом месте на экране. Основная анимация.

Я бы создал JPanel для нижней части экрана для того, чтобы либо держать ваш JLabel, либо отображать изображение без JLabel, переопределив свой метод paintComponent(...) . Если вы используете его как контейнер, то да, его макет должен быть нулевым, но в остальной части графического интерфейса не должно использоваться нулевой макет. Таймер Swing просто изменил местоположение JLabel, а затем repaint() на его JPanel / container. Если вы g.drawImage(myImage, x, y) последний маршрут, вы нарисуете изображение в методе paintComponent(...) JPanel, используя g.drawImage(myImage, x, y) , и ваш таймер изменит x и / или y и переадресует вызов repaint() на рисунок JPanel.

Кроме того, вы, вероятно, не хотите добавлять JLabel в свой таймер, а просто перемещать JLabel, который уже отображается в графическом интерфейсе.

Кроме того, чтобы избежать проблем с фокусом, не используйте KeyListener для ввода ввода клавиш, а используйте Key Bindings. Google направит вас к большому учебнику по этой конструкции.

Редактировать 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 dirMap = new EnumMap(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(); } }); } } 

Что создаст этот графический интерфейс:

введите описание изображения здесь

Три возможности:

  • Вы можете использовать библиотеку типа SlidingLayout для создания такого перехода с очень небольшим количеством строк кода. Вы не сможете настроить анимацию, но ваша жизнь будет проще.

  • Вы можете использовать движок анимации, такой как Universal Tween Engine, чтобы настроить все вручную и настроить анимацию столько, сколько хотите (первый lib использует этот под капотом). Используя такой движок, вы можете анимировать то, что хотите: позиции, цвета, размер шрифта, …

  • Вы можете закодировать все вручную и охватить ад, который является миром анимации 🙂

В конце концов, вы сможете быстро создавать такие анимации (это инструмент, над которым я сейчас работаю, используемый для настройки проектов eclipse для Android-разработчиков с использованием игровой среды LibGDX):
введите описание изображения здесьвведите описание изображения здесь

Я сделал эти библиотеки для облегчения боли, которая является анимацией пользовательского интерфейса (я люблю дизайн пользовательского интерфейса: 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); 
  • Как измерить временной интервал в C?
  • Разница между std :: system_clock и std :: stable_clock?
  • C ++, получение миллисекундного времени на Linux - clock (), похоже, не работает должным образом
  • Как написать таймер в Objective-C?
  • System.Timers.Timer / Threading.Timer vs Thread with WhileLoop + Thread.Sleep для периодических задач
  • Использование System.Windows.Forms.Timer.Start () / Stop () по сравнению с Enabled = true / false
  • java: запустить функцию через определенное количество секунд
  • Счетчик jQuery для подсчета до целевого номера
  • Выполняется ли в System.Windows.Forms.Timer другой stream, чем пользовательский интерфейс?
  • Вычислить время выполнения метода
  • java.util.Timer: устарел ли он?
  • Interesting Posts

    Как сделать снимок экрана и поделиться им программно

    Как подключить / отключить Bluetooth и привязку к Snow Leopard

    Как отправить деньги на любую учетную запись PayPal

    Как проверить равные? (0 == i) или (i == 0)

    OpenWRT – как сделать начальный логин (ssh), если 192.168.1.1 не может быть маршрутизирован?

    Ссылка на компьютеры по их имени между ОС X и операционными системами Windows

    Два компьютера с объединенными ресурсами процессора и памяти?

    FirebaseListAdapter не подталкивает отдельные элементы для приложения для чата – Firebase-Ui 3.1

    Самый быстрый способ протестировать интернет-соединение

    Как получить текущий контекст активности переднего плана в android?

    Динамически регистрировать методы конструктора в AbstractFactory во время компиляции с использованием шаблонов C ++

    Какая функция scanf в c возвращается?

    Как перенести dataset в файл csv?

    Как добавить поддержку прокси для Jsoup (HTML-парсер)?

    Почему Java запрещает статические поля во внутренних classах?

    Давайте будем гением компьютера.