在JLabel动画中不会调用paint()

时间:2013-08-22 13:11:04

标签: java swing animation jlabel

我想要一个冒泡的效果 - 一些图像从底部到上面冒泡。以下是完整的代码。问题是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();
        }

    }  

2 个答案:

答案 0 :(得分:4)

您的代码中存在许多问题,但未调用paint()的主要原因是因为您的Bubble组件的大小为0 x 0.这是因为您没有覆盖{ {1}}返回足够的值。此外,您的getPreferredSize()变量很快就会变为负数,这意味着您没有时间看动画。

现在,您应该考虑处理以下其他问题:

  • 覆盖ypos而不是paintComponent
  • 确保你永远不会在EDT上睡觉(这里不会发生,因为你很幸运)
  • 通过paint电话从EDT启动您的用户界面。
  • 为什么在SwingUtilities.invokeLater方法中创建另一个帖子对我来说仍然是一个谜(要么从一开始就对整个方法做,要么根本不做)
  • Bubbling在您的情况下会更合适
  • 遵循java命名约定(方法以小写字母开头)

以下是您的代码更新(但我没有根据上面的评论更改所有内容):

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

中的更多内容