-1

I've been trying to move, and display an image (e.g. heart rate image). Here is what I have so far. The image keeps moving to the left forvever; so far so good. But I need to embed this moving image inside another frame. I know my question seems very

import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class HeartBeat extends JPanel{

    public static void main(String[] args) throws Exception {
        new HeartBeat();    
    }

    public HeartBeat(){
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JPanel j = new JPanel();
                j.add(new HeartBeat2());
                frame.add(j);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
    class HeartBeat2 extends JPanel{
        BufferedImage bi;

        public HeartBeat2(){
        try {
            bi = ImageIO.read(new URL("https://i.stack.imgur.com/i8UJD.jpg"));
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        Runnable r = new Runnable() {
            @Override
            public void run() {
                final BufferedImage canvas = new BufferedImage(
                        bi.getWidth(), bi.getHeight(),
                        BufferedImage.TYPE_INT_RGB);
                final JLabel animationLabel = new JLabel(new ImageIcon(canvas));
                ActionListener animator = new ActionListener() {

                    int x = 0;

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        Graphics2D g = canvas.createGraphics();

                        // paint last part of image in left of canvas
                        g.drawImage(bi, x, 0, null);
                        // paint first part of image immediately to the right
                        g.drawImage(bi, x + bi.getWidth(), 0, null);

                        // reset x to prevent hitting integer overflow
                        if (x%bi.getWidth()==0) x = 0;

                        g.dispose();
                        animationLabel.repaint();
                        x--;
                    }
                };
                Timer timer = new Timer(40, animator);
                timer.start();
                JPanel j = new JPanel();
                JOptionPane.showMessageDialog(null, animationLabel);
                timer.stop();
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}}
Tina J
  • 4,983
  • 13
  • 59
  • 125
  • 1
    Okay, you have the `JPanel`, you can add it to what ever you like, not sure I see the problem... – MadProgrammer Oct 28 '14 at 22:59
  • 1
    `Here is my code.` You mean here is the code you copied from here: http://stackoverflow.com/questions/26519141/display-moving-image-in-java-swing/26519276#26519276. I also don't understand the question. You have a JLabel, so just add it to the frame. – camickr Oct 29 '14 at 00:14
  • I meant the code I have so far. Yes, basically I put inside my frame, and simply add the JLabel to the other jpanel. But for some reasons it does not show the moving image! – Tina J Oct 29 '14 at 02:14
  • Of course! Any label should simply be added to any jpanel. But for some reasons I dont see anything... – Tina J Oct 29 '14 at 02:19

1 Answers1

1

The problem with the code is

  1. The animationLabel is being added to the JOptionPane, but you never add it to the HeartBeat2

  2. The JOptionPane.showMessageDialog is a blocking (modal) call, so it blocks any code occurring after it (i.e. timer.stop()). But if you remove that JOptionPane (to try and add the label to the panel) the timer.stop() will automatically be called (The timer is controlling the image/animation). And if you just leave the JOptionPane there, the adding the label to panel won't work, as each component can only have one parent

So you need to

  1. First of all, completely strip out the Runnable. You don't need it.

  2. Take out the JOptionPane, and simply add(animationLabel) to the HeartBeat2

  3. Take out the timer.stop()


public HeartBeat2() {

    try {
        bi = ImageIO.read(new URL("https://i.stack.imgur.com/i8UJD.jpg"));
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    final BufferedImage canvas = new BufferedImage(
            bi.getWidth(), bi.getHeight(),
            BufferedImage.TYPE_INT_RGB);
    final JLabel animationLabel = new JLabel(new ImageIcon(canvas));
    add(animationLabel);

    ActionListener animator = new ActionListener() {

        int x = 0;

        @Override
        public void actionPerformed(ActionEvent e) {
            Graphics2D g = canvas.createGraphics();

            // paint last part of image in left of canvas
            g.drawImage(bi, x, 0, null);
            // paint first part of image immediately to the right
            g.drawImage(bi, x + bi.getWidth(), 0, null);

            // reset x to prevent hitting integer overflow
            if (x % bi.getWidth() == 0) {
                x = 0;
            }

            g.dispose();
            animationLabel.repaint();
            x--;
        }
    };

    Timer timer = new Timer(40, animator);
    timer.start();
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720