简体   繁体   English

Swing java动画仅在未从侦听器调用时才起作用

[英]Swing java animation only works when not called from listener

I am trying to create an function with an animation in java(swing). 我试图在java(swing)中创建一个带动画的函数。 I want to create a "stack" of cards and then be able to draw one card from the stack using a method. 我想创建一个“堆栈”的卡,然后能够使用一种方法从堆栈中绘制一张卡。 The card i draw should then be "fliped" to reveal the front side. 我绘制的卡应该“翻转”以显示正面。

This is working fine unless when I am trying to draw a new card using listeners. 这是正常工作,除非我试图使用听众绘制一张新卡。

I start the program by building the stack then drawing one card. 我通过构建堆栈然后绘制一张卡来启动程序。 Then I have a button that draws a new card(actionlistener). 然后我有一个绘制新卡片的按钮(actionlistener)。 The animation does not show however i can see that the stack decreases by one card. 动画没有显示,但我可以看到堆栈减少了一张卡。 I have tried to create a gif to show the problem. 我试图创建一个gif来显示问题。

Gif file showing the problem http://people.dsv.su.se/~chra4852/gif.gif 显示问题的Gif文件http://people.dsv.su.se/~chra4852/gif.gif

My best guess would be that it has something to do with threads or the EDT? 我最好的猜测是它与线程或EDT有关?

Here is the code(I have removed the use of the Scalr class since its not important) : 这是代码(我已经删除了Scalr类的使用,因为它不重要):

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;
// import org.imgscalr.Scalr; Removed for Stackoverflow

public class Test extends JFrame{

public static JPanel cardPanel = new JPanel();
public static JLayeredPane layerPane = new JLayeredPane();
private final CardFlipp cardFlipp;


Test() {
    cardFlipp = new CardFlipp();
    this.setLayout(new BorderLayout());
    layerPane.setPreferredSize(new Dimension(700, 300));
    add(cardPanel, BorderLayout.CENTER);
    JButton newJButton = new JButton("New card");
    newJButton.addActionListener(new drawNewCardListener());
    add(newJButton, BorderLayout.SOUTH);
    setSize(800,400);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
    Point pos = new Point(10,30);
    cardFlipp.createCardFlipp(30, pos, layerPane, cardPanel);
    System.out.println("Now running on thread " + Thread.currentThread());
    try {
        Thread.sleep(3000);
    } catch (InterruptedException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
    cardFlipp.displayCard("http://imgi.se/image.php?di=IYW9");
}

public static void main(String[] args){
    new Test();
}

    class drawNewCardListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent ae) {
        System.out.println("Now running on thread " + Thread.currentThread());
        cardFlipp.displayCard("http://imgi.se/image.php?di=IYW9");
    }
    }
}


class CardFlipp extends JPanel{

private Point origin;
private BufferedImage icon;
private JLayeredPane lPane;
private JPanel jPanel;
private int lastCardDisplayedId = 0;

public void createCardFlipp(int amount, Point pos, JLayeredPane lPaneRef, JPanel jPanelRef) {
    origin = pos;
    setIcon("http://imgi.se/image.php?di=HPCJ");
    lPane = lPaneRef;
    jPanel = jPanelRef;
    for(int i = amount; i > 0; i--) {
        origin.x += 3;
        lPane.add(new Card(origin, icon, i), new Integer(amount-i));
        jPanel.add(lPane);
        lPane.revalidate();
        lPane.repaint();
        try {
            Thread.sleep(80);
        } catch (InterruptedException ex) {
            Logger.getLogger(CardFlipp.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

public void displayCard(String fileUrl) {
    Card c = (Card) lPane.getComponent(0);
    if(lastCardDisplayedId == 0) {
        origin = new Point(c.getBounds().x + 370, c.getBounds().y);
    }
    int cardId = c.getId();
    setIcon(fileUrl);
    c.flippCardRight(lastCardDisplayedId);
    lPane.remove(c);
    if(lastCardDisplayedId != 0) {
        for(int i = 0; i < lPane.getComponentCount(); i++) {
            c = (Card) lPane.getComponent(i);
            if(c.getId() == lastCardDisplayedId) {
                lPane.remove(c);
                break;
            }
        }
    }
    lPane.repaint();
    lPane.add(new Card(origin, icon, cardId), new Integer(0));
    jPanel.add(lPane);
    lastCardDisplayedId = cardId;
}

private void setIcon(String urlPath) {
    try {
        URL url = new URL(urlPath);
        icon = ImageIO.read(url);
    } catch (IOException e) {
        System.err.println(e);
        System.exit(-1);
        icon = null;
    }
}
}

class Card extends JComponent {

private BufferedImage buffImg;
private ImageIcon iconImg;
private final int id;

public Card(Point origin, BufferedImage img, int count) {
    buffImg = img;
    iconImg = new ImageIcon(buffImg);
    setBounds(origin.x,origin.y,iconImg.getIconWidth(),iconImg.getIconHeight());
    this.id = count;
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(iconImg.getImage(), 0, 0, this);
}

public void flippCardRight(int count) {
    int x = count * 3;
    int newPosX = getBounds().x + iconImg.getIconWidth() + 20;

    while(getBounds().x < newPosX + x) {
        setBounds(getBounds().x+5,getBounds().y,iconImg.getIconWidth(),iconImg.getIconHeight());
        wait10MiliSec();
    }

    // Removed to not need the scalr class
    //int minimize = 10;
    //while(iconImg.getIconWidth() > minimize) {
        //buffImg = Scalr.resize(buffImg, Scalr.Method.SPEED, Scalr.Mode.FIT_EXACT, //iconImg.getIconWidth()-minimize, iconImg.getIconHeight(), Scalr.OP_ANTIALIAS);
        //iconImg = new ImageIcon(buffImg);
        //setBounds(getBounds().x+minimize-1,getBounds().y,iconImg.getIconWidth(),iconImg.getIconHeight());
        //wait10MiliSec();
    //}
}

private void wait10MiliSec() {
    try {
        Thread.sleep(10);
    } catch (InterruptedException ex) {
        Logger.getLogger(Card.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public int getId() {
    return this.id;
}

public int getImgWidth() {
    return iconImg.getIconWidth();
}
}

Question = What can be done so that the animation is shown regardless if its called from the listener? 问题=可以做什么,以便无论是否从侦听器调用动画都会显示动画?

using timer would be the solution for you:) Example of a similar problem that guy had a similar problem, you can read the answers he received. 使用计时器将是你的解决方案:) 类似问题的例子 ,家伙有类似的问题,你可以阅读他收到的答案。 good luck 祝好运

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM