如何让我的Buffered Image类在我的GUI中显示?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何让我的Buffered Image类在我的GUI中显示?相关的知识,希望对你有一定的参考价值。
我有一个程序,使用定时器切换图像进行动画。当程序在其最后一个图像上时,我使用一个类来创建该图像的缓冲图像,其上有文本。当显示动画的最后一个图像时,我想将显示的图像更改为缓冲图像。我无法让它发挥作用。代码就像粗体部分不在那里一样。如果我删除它上面的行,它会显示带有文本的图像,而不显示任何其他内容。我应该对我的代码进行哪些编辑来修复此问题?
执行动画的类
**import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.*;
import java.io.*;
import java.io.File;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.*;
import javax.swing.*;
import javax.imageio.ImageIO;
/**
* Write a description of class Reveal here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class Reveal extends JPanel
{
private JPanel panel = new JPanel(); //a panel to house the label
private JLabel label = new JLabel(); //a label to house the image
private String[] image = {"Jack in the Box 1.png","Jack in the Box 2.png","Jack in the Box 3.png","Jack in the Box 4.png","Jack in the Box 5.png","Jack in the Box 6.png","Jack in the Box 7.png"}; //an array to hold the frames of the animation
private ImageIcon[] icon = new ImageIcon[7]; //an array of icons to be the images
private JFrame f;
private TextOverlay TO;
private Timer timer;
private Timer timer2;
int x = 0;
int y = 4;
int counter = 0;
/**
* Constructor for objects of class Reveal
*/
public Reveal(String name, int number)
{
TO = new TextOverlay("Jack in the Box 7.png", name, number);
for (int h = 0; h < 7; h++){
icon[h] = new ImageIcon(image[h]);
icon[h].getImage();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
//Sets the size of the window
f.setSize(800,850);
panel = new JPanel();
label = new JLabel();
label.setIcon( icon[x] );
panel.add(label);
setVisible(true);
f.add(panel);
display(name, number);
**f.add(TO);**
}
public void display(String name, int number){
timer = new Timer(150, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (counter > 27){
timer.stop();
timer2.start(); //starts the second half of the animation
}else{
if (x != 3){
x++;
}else{
x = 0;
}
label.setIcon( icon[x] );
counter++;
} //ends if-else
} //ends action method
}); //ends timer
timer2 = new Timer(250, new ActionListener(){
public void actionPerformed(ActionEvent e){
if (y > 6) {
timer2.stop();
}else{
label.setIcon( icon[y] );
y++;
} //ends if-else
} //ends action method
}); //ends timer2
timer.start();
}
}
**
将文本放在图像上的类
import java.io.*;
import java.awt.*;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
/**
* @see https://stackoverflow.com/questions/2658663
*/
public class TextOverlay extends JPanel {
private BufferedImage image;
private String name;
private String fileX;
private int number;
public TextOverlay(String f, String s, int n) {
name = s;
number = n;
fileX = f;
try {
image = ImageIO.read(new File(fileX));
} catch (IOException e) {
e.printStackTrace();
}
image = process(image, name, number);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
private BufferedImage process(BufferedImage old, String name, int number) {
int w = old.getWidth();
int h = old.getHeight();
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(old, 0, 0, w, h, this);
g2d.setPaint(Color.black);
g2d.setFont(new Font("Franklin Gothic Demi Cond", Font.PLAIN, 30));
String s1 = name;
String s2 = Integer.toString(number);;
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString(s1, 40, 90);
g2d.drawString(s2, 40, 140);
g2d.dispose();
return img;
}
}
所以,你似乎对Swing如何工作有误解,你可能会发现How to Use Swing Timers和Concurrency in Swing的一些帮助。
基本上,当你start
一个Timer
时,它不会在此时阻止,直到计时器结束(即使它确实如此,你的工作方式也不会像你想要的那样)。而是创建一个新线程,并在指定的时间段后,在Event Dispatching Thread上发出一个请求以执行提供的Runnable
。
这意味着当你做某事......
f.add(panel);
display(name, number);
f.add(TO);
你实际上是在qazxsw poi之上添加了qazxsw poi组件(因为框架使用的是TO
,而JLabel
位置是默认位置。
相反,在第二个计时器完成后,您需要删除标签并添加BorderLayout
组件...
CENTRE
Runnable Example...
TO
A "slightly" different approach...
动画实际上是一个非常复杂的主题,不容易实现。
这就是为什么当遇到这些问题时,我更愿意看看已经实施的库来帮助解决这些问题。我建议你看看:
timer2 = new Timer(250, new ActionListener() { public void actionPerformed(ActionEvent e) { if (y > 6) { timer2.stop(); Container parent = label.getParent(); parent.remove(label); parent.add(TO); parent.revalidate(); } else { label.setIcon(icon[y]); y++; } //ends if-else } //ends action method }); //ends timer2
import java.awt.event.*; import java.awt.Graphics; import java.awt.Color; import java.awt.Font; import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; import javax.swing.border.LineBorder; public class Reveal extends JPanel { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } new Reveal("Test", 5); } }); } private JPanel panel = new JPanel(); //a panel to house the label private JLabel label = new JLabel(); //a label to house the image private ImageIcon[] icon = new ImageIcon[7]; //an array of icons to be the images private JFrame f; private TextOverlay TO; private Timer timer; private Timer timer2; int x = 0; int y = 4; int counter = 0; /** * Constructor for objects of class Reveal */ public Reveal(String name, int number) { TO = new TextOverlay("Jack in the Box 7.png", name, number); for (int h = 0; h < 7; h++) { icon[h] = new ImageIcon(makeImage(h)); icon[h].getImage(); } JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); //Sets the size of the window f.setSize(800, 850); panel = new JPanel(new GridBagLayout()); label = new JLabel(); label.setIcon(icon[x]); label.setBorder(new LineBorder(Color.RED)); panel.add(label); f.add(panel); display(name, number); // f.add(TO); setVisible(true); } public void display(String name, int number) { timer = new Timer(150, new ActionListener() { public void actionPerformed(ActionEvent e) { if (counter > 27) { timer.stop(); timer2.start(); //starts the second half of the animation } else { if (x != 3) { x++; } else { x = 0; } label.setIcon(icon[x]); counter++; } //ends if-else } //ends action method }); //ends timer timer2 = new Timer(250, new ActionListener() { public void actionPerformed(ActionEvent e) { if (y > 6) { timer2.stop(); Container parent = label.getParent(); parent.remove(label); parent.add(TO); parent.revalidate(); } else { label.setIcon(icon[y]); y++; } //ends if-else } //ends action method }); //ends timer2 timer.start(); } protected BufferedImage makeImage(int h) { BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = img.createGraphics(); FontMetrics fm = g2d.getFontMetrics(); String text = Integer.toString(h); int x = (100 - fm.stringWidth(text)) / 2; int y = ((100 - fm.getHeight()) / 2) + fm.getAscent(); g2d.setColor(Color.BLUE); g2d.fillRect(0, 0, 100, 100); g2d.setColor(Color.BLACK); g2d.drawString(text, x, y); g2d.dispose(); return img; } public class TextOverlay extends JPanel { private BufferedImage image; private String name; private String fileX; private int number; public TextOverlay(String f, String s, int n) { name = s; number = n; fileX = f; image = makeImage(n); image = process(image, name, number); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(image, 0, 0, this); } @Override public Dimension getPreferredSize() { return new Dimension(100, 100); } private BufferedImage process(BufferedImage old, String name, int number) { int w = old.getWidth(); int h = old.getHeight(); BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = img.createGraphics(); g2d.drawImage(old, 0, 0, w, h, this); g2d.setPaint(Color.black); g2d.setFont(new Font("Franklin Gothic Demi Cond", Font.PLAIN, 30)); String s1 = name; String s2 = Integer.toString(number);; FontMetrics fm = g2d.getFontMetrics(); g2d.drawString(s1, 40, 90); g2d.drawString(s2, 40, 140); g2d.dispose(); return img; } } }
- The Timing Framework
作为一些起点。
虽然我更喜欢使用库,但有时它不可能,或者库不符合我的整体需求......而且我喜欢涉猎......这是一种爱好。
基于我从你的代码中可以理解的东西,你试图从快速动画开始,然后慢下来直到你到达最后一帧。在动画理论中,这通常被称为缓和,更具体地说,“缓慢/缓和”。
以下借鉴了我一直在玩的一堆片段(设计一个更可重复使用的库),它将在4秒内基本上(随机)显示图像,动画放慢速度,最后呈现“幸运” “号码
nb gif动画实际上非常慢,你需要运行它才能看到差异
universal-tween-engine
以上是关于如何让我的Buffered Image类在我的GUI中显示?的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 AFNetworkReachabilityManager 类在我的 OS X 项目中获取网络可达性
如何让我的 user.address 州和国家/地区字段正确包含在我的视图中?