我想要一个冒泡的效果 - 一些图像从底部到上面冒泡。以下是完整的代码。问题是paint()永远不会被repaint()调用。我不擅长java awt或swing。有什么原因吗?
import java.awt.AlphaComposite;
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.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* The Bubble object for implementing some animations for each block of LOVE pieces
*/
class Bubble extends JLabel {
private static final long serialVersionUID = 1L;
boolean isBubbling = false;
int xpos;
int ypos;
float transparency;
String text = "+100";
GameSettings config;
AlphaComposite transparency05=AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
Bubble(int x, int y) {
isBubbling=false;
this.xpos = x;
this.ypos = y;
}
void Bubbling() {
isBubbling=true;
for(int i=1;i<=50; i+=4) {
System.out.println("Bubbling init");
ypos -= (int)(7.2*i);
transparency = transparency/2;
setFont(new Font("arial, helvetica",Font.BOLD|Font.ITALIC,i));
repaint();
try {Thread.sleep(15);} catch(Throwable e) {}
}
new Thread() {
public void run() {
for(int i=50;i>=0; i-=4) {
System.out.println("Bubbling run");
ypos -= (int)(7.2*i);
transparency = transparency/2;
setFont(new Font("arial, helvetica",Font.BOLD|Font.ITALIC,i));
repaint();
try {Thread.sleep(15);} catch(Throwable e) {}
}
isBubbling=false;
repaint();
}
}.start();
}
@Override
public void paint(Graphics g1) {
super.paint(g1);
System.out.println("Bubbling paint begin");
if(isBubbling) {
System.out.println("Bubbling paint");
Graphics2D g=(Graphics2D) g1;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
FontMetrics fm=g.getFontMetrics();
Rectangle r = getBounds();
int width=fm.stringWidth(text);
int height=fm.getHeight()*4/5;
int cx=g.getFont().getSize()/10;
int x=(r.width-width)/2;
int xx=fm.charWidth('i');
//g.setComposite(transparency05);
g.setComposite(AlphaComposite.SrcOver);
g.setColor(Color.red);
//g.drawString(text,xpos*config.pieceWidth,ypos*config.pieceHeight);
g.drawString(text,xpos,ypos);
//Image img=Tetris.getResource().getImage(config.imagePath+config.imagePrefix+"heart"+config.imagePostfix);
//g.drawImage(img,img.getWidth(null)+3,0,null);
//g.drawImage(img,xpos*config.pieceWidth,ypos*config.pieceHeight,null);
}
}
//for test
static public void main(String[] args) {
//Create and set up the window.
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JPanel newContentPane = new JPanel();
newContentPane.setOpaque(true); //content panes must be opaque
Bubble bub = new Bubble(50, 50);
newContentPane.add(bub);
frame.setContentPane(newContentPane);
frame.setPreferredSize(new Dimension(300, 300));
//Display the window.
frame.pack();
frame.setVisible(true);
bub.Bubbling();
}
}
答案 0 :(得分:4)
您的代码中存在许多问题,但未调用paint()
的主要原因是因为您的Bubble
组件的大小为0 x 0.这是因为您没有覆盖{ {1}}返回足够的值。此外,您的getPreferredSize()
变量很快就会变为负数,这意味着您没有时间看动画。
现在,您应该考虑处理以下其他问题:
ypos
而不是paintComponent
paint
电话从EDT启动您的用户界面。SwingUtilities.invokeLater
方法中创建另一个帖子对我来说仍然是一个谜(要么从一开始就对整个方法做,要么根本不做)Bubbling
在您的情况下会更合适以下是您的代码更新(但我没有根据上面的评论更改所有内容):
javax.swing.Timer
答案 1 :(得分:1)
问题是你的标签没有Dimension。您可以使用setPreferredSize()
public static final Dimension PREF_SIZE = new Dimension(70, 70);
//in main method or you can override `getPreferredSize()`
Bubble bub = new Bubble(50, 50);
bub.setPreferredSize(PREF_SIZE);
你正在睡觉The Event Dispatch Thread。必须在该线程中执行所有gui内容,而不是查看Swing Timers。
另外,对于swing组件,您应该覆盖paintComponent()
而不是paint()
。阅读article