3

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

    }  
4

2 回答 2

4

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

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

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

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

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
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";

    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--;
            transparency = transparency / 2;
            setFont(new Font("Arial", Font.BOLD | Font.ITALIC, i));
            repaint();
            try {
                Thread.sleep(50);
            } catch (Throwable e) {
            }
        }

        new Thread() {
            @Override
            public void run() {
                for (int i = 50; i >= 0; i -= 4) {
                    System.out.println("Bubbling run");
                    ypos--;
                    transparency = transparency / 2;
                    setFont(new Font("Arial", Font.BOLD | Font.ITALIC, i));
                    repaint();
                    try {
                        Thread.sleep(50);
                    } catch (Throwable e) {
                    }
                }
                isBubbling = false;
                repaint();
            }
        }.start();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(180, 50);
    }

    @Override
    protected void paintComponent(Graphics g1) {
        super.paintComponent(g1);

        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);
            System.err.println(xpos + " " + ypos);
            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(new FlowLayout());
        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();
    }

}
于 2013-08-22T13:46:31.330 回答
1

问题是您的标签没有维度。你可以设置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);

你正在睡觉事件调度线程。所有 gui 的东西都必须在那个线程中执行,而不是看一下Swing Timers

此外,您应该覆盖paintComponent()而不是paint()摆动组件。在本文中阅读更多内容

于 2013-08-22T13:14:09.787 回答