动画构造函数在Java GUI

时间:2017-12-12 20:59:49

标签: java swing timer jframe paintcomponent

你好我是Java GUI的新手我做了一个second.java,如下所示:

package theproject;
import java.awt.event.*;
import java.awt.*;

import javax.swing.*;

public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay=50, totalFrames=8, currentFreames=1;

public second()
{
  imageArray= new ImageIcon[totalFrames];
  System.out.println(imageArray.length);
  for(int i=0; i<imageArray.length;i++)
  {
      imageArray[i]=new ImageIcon(i+1+".png");
      System.out.println(i+1);

  }
  animator= new Timer(delay, this);
  animator.start();

   }

  public void paintComponent(Graphics g )
  {
  super.paintComponent(g);
   if(currentFreames<8)
   {

  imageArray[currentFreames].paintIcon(this, g, 0, 0);
  currentFreames++;
  System.out.println(currentFreames);
}
else{
    currentFreames=0;
}
  }

@Override
public void actionPerformed(ActionEvent arg0) {

    repaint();
}

 }

并且Gui调用构造函数第二个并且输出没有显示。你能指导一下我该怎么做,下面给出了gui:

   package theproject;

 import java.awt.EventQueue;

 import javax.swing.JFrame;
 import javax.swing.JButton;
 import java.awt.BorderLayout;
 import java.awt.event.ActionListener;
 import java.awt.event.ActionEvent;
 import javax.swing.SwingConstants;
 import javax.swing.JTextField;

  public class Sav {

private JFrame frame;
private JTextField textField;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Sav window = new Sav();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public Sav() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    textField = new JTextField();
    textField.setBounds(10, 0, 261, 20);
    frame.getContentPane().add(textField);
    textField.setColumns(10);

    JButton btnNewButton = new JButton("Submit");
    btnNewButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
        second s= new second();
         frame.add(s);
        }
    });
    btnNewButton.setBounds(273, -1, 89, 23);
    frame.getContentPane().add(btnNewButton);

}
}

gui必须基本上调用构造函数,并在屏幕上显示动画如果有人我做错了或者必须要做的事情请告诉我。

1 个答案:

答案 0 :(得分:1)

首先,不要在paintComponent方法中更新状态,可以在任何时候出于多种原因进行绘制,大多数情况下没有您的交互。绘画应该简单描绘当前的状态。在你的ActionListener中,你应该推进框架并决定应该发生什么(比如重置帧值)

其次,您实际上从未向任何事物添加second,因此永远不会显示它。

第三,您不能覆盖getPreferredSize中的second,因此布局管理员将不知道该组件的大小应该是什么,只是被分配0x0,它与隐形一样好,没有区别

第四,您正在使用null布局。这将使你的生活变得难以置信。 Swing已经围绕布局管理器的使用进行了设计和优化,他们在决定如何最好地处理不同渲染系统/管道中字体度量的差异方面做了重要的工作,我高度建议您花时间学习如何使用它们

第五,paintComponent没有业务public,没有人应该直接调用

实施例

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;

public class Sav {

    private JFrame frame;
    private JTextField textField;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Sav window = new Sav();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Sav() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;

        textField = new JTextField(20);
        frame.getContentPane().add(textField, gbc);

        JButton btnNewButton = new JButton("Submit");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                second s = new second();
                frame.add(s, gbc);
                frame.getContentPane().revalidate();
                frame.pack();
                frame.setLocationRelativeTo(null);
            }
        });
        frame.getContentPane().add(btnNewButton, gbc);

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public class second extends JPanel implements ActionListener {

        private Timer animator;
        private ImageIcon imageArray[];
        private int delay = 50, totalFrames = 8, currentFreames = 1;

        public second() {
            imageArray = new ImageIcon[totalFrames];
            for (int i = 0; i < imageArray.length; i++) {
                imageArray[i] = new ImageIcon(getImage(i));

            }
            animator = new Timer(delay, this);
            animator.start();

        }

        protected Image getImage(int index) {
            BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            FontMetrics fm = g2d.getFontMetrics();
            g2d.dispose();
            String text = Integer.toString(index);
            int height = fm.getHeight();
            int width = fm.stringWidth(text);

            img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            g2d = img.createGraphics();
            g2d.setColor(getForeground());
            g2d.drawString(text, 0, fm.getAscent());
            g2d.dispose();
            return img;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(imageArray[0].getIconWidth(), imageArray[1].getIconHeight());
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            imageArray[currentFreames].paintIcon(this, g, 0, 0);
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            currentFreames++;
            if (currentFreames >= imageArray.length) {
                currentFreames = 0;
            }
            repaint();
        }

    }
}
  

您的代码也无效。它会增加图像集的值但不显示图像

对我来说效果很好......

Example

如果由于某种原因无法加载图像,

imageArray[i]=new ImageIcon(i+1+".png");将不会生成任何错误(并且它会在后台线程中加载图像,这只是另一个问题)。

相反,我建议改为使用ImageIO.read,如果由于某种原因无法读取图片,则会抛出IOException,这会更加有用。有关详细信息,请参阅Reading/Loading an Image