本文介绍了更新JLabel中包含的图像 - 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前无法开始工作的应用程序部分是能够滚动并一次显示一个图像列表。我从用户那里得到一个目录,绕过该目录中的所有文件,然后加载一个只有jpegs和png的数组。接下来,我想用第一个图像更新JLabel,并提供上一个和下一个按钮来滚动并依次显示每个图像。当我尝试显示第二个图像时,它没有得到更新...这是我到目前为止所得到的:

The part of the application that I am currently having trouble getting to work is being able to scroll through and display a list of images, one at a time. I'm getting a directory from the user, spooling through all of the files in that directory, and then loading an array of just the jpegs and pngs. Next, I want to update a JLabel with the first image, and provide previous and next buttons to scroll through and display each image in turn. When I try to display the second image, it doesn't get updated... Here's what I've got so far:

public class CreateGallery
{
    private JLabel swingImage;

我用来更新图片的方法:

The method that I'm using to update the image:

protected void updateImage(String name)
{
    BufferedImage image = null;
    Image scaledImage = null;
    JLabel tempImage;

    try
    {
        image = ImageIO.read(new File(name));
    } catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // getScaledImage returns an Image that's been resized proportionally to my thumbnail constraints
    scaledImage = getScaledImage(image, THUMB_SIZE_X, THUMB_SIZE_Y);
    tempImage = new JLabel(new ImageIcon(scaledImage));
    swingImage = tempImage;
}

然后在我的createAndShowGUI方法中放置swingImage ...

Then in my createAndShowGUI method that puts the swingImage on...

private void createAndShowGUI()
{
    //Create and set up the window.
    final JFrame frame = new JFrame();

    // Miscellaneous code in here - removed for brevity

    //  Create the Image Thumbnail swingImage and start up with a default image
    swingImage = new JLabel();
    String rootPath = new java.io.File("").getAbsolutePath();
    updateImage(rootPath + "/images/default.jpg");

    // Miscellaneous code in here - removed for brevity

    rightPane.add(swingImage, BorderLayout.PAGE_START);
    frame.add(rightPane, BorderLayout.LINE_END);



public static void main(String[] args)
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            UIManager.put("swing.boldMetal", Boolean.FALSE);
            new CreateGalleryXML().createAndShowGUI();
        }
    });
}

如果你已经走到这一步,第一张图片是我的default.jpg ,一旦我获得目录并识别该目录中的第一个图像,当我尝试更新swingImage时,它就失败了。现在,我尝试使用swingImage.setVisible()和swingImage.revalidate()来尝试强制重新加载。我猜这是我的tempImage =新的JLabel,这是根本原因。但我不知道如何将我的BufferedImage或Image转换为JLabel以便更新swingImage。

If you've gotten this far, the first image is my default.jpg, and once I get the directory and identify the first image in that directory, that's where it fails when I try to update the swingImage. Now, I've tried to swingImage.setVisible() and swingImage.revalidate() to try to force it to reload. I'm guessing it's my tempImage = new JLabel that's the root cause. But I'm not sure how to convert my BufferedImage or Image to a JLabel in order to just update swingImage.

推荐答案

而不是为每个图像创建新实例 JLabel ,只需使用方法。

Instead of creating a New Instance of the JLabel for each Image, simply use JLabel#setIcon(...) method of the JLabel to change the image.

小示例程序:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SlideShow extends JPanel
{
    private int i = 0;
    private Timer timer;
    private JLabel images = new JLabel();
    private Icon[] icons = {UIManager.getIcon("OptionPane.informationIcon"),
                            UIManager.getIcon("OptionPane.errorIcon"),
                            UIManager.getIcon("OptionPane.warningIcon")};
    private ImageIcon pictures1, pictures2, pictures3, pictures4;
    private ActionListener action = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            i++;
            System.out.println(i);

            if(i == 1)
            {
                pictures1 = new ImageIcon("image/caIcon.png");
                images.setIcon(icons[i - 1]);
                System.out.println("picture 1 should be displayed here");
            }
            if(i == 2)
            {
                pictures2 = new ImageIcon("image/Keyboard.png");
                images.setIcon(icons[i - 1]);
                System.out.println("picture 2 should be displayed here");
            }
            if(i == 3)
            {
                pictures3 = new ImageIcon("image/ukIcon.png");
                images.setIcon(icons[i - 1]);
                System.out.println("picture 3 should be displayed here");
            }
            if(i == 4)
            {
                pictures4 = new ImageIcon("image/Mouse.png");
                images.setIcon(icons[0]);
                System.out.println("picture 4 should be displayed here");
            }
            if(i == 5)
            {
                timer.stop();
                System.exit(0);
            }
            revalidate();
            repaint();
        }
    };

    public SlideShow()
    {
        JFrame frame = new JFrame("SLIDE SHOW");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);

        frame.getContentPane().add(this);

        add(images);

        frame.setSize(300, 300);
        frame.setVisible(true);
        timer = new Timer(2000, action);
        timer.start();
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new SlideShow();
            }
        });
    }
}

既然您使用ImageIO,这是一个很好的与相关的示例

Since you doing it with ImageIO, here is a good example related to that JLabel using ImageIO

与您的案件有关的信息,关于发生的事情:

Information relating to your case, as to what is happening :

createAndShowGUI()初始化你的 JLabel (swingImage)的方法,然后你间接地将它添加到你的 JPanel JFrame

Inside your createAndShowGUI() method you initializing your JLabel (swingImage), and you added that to your JPanel by virtue of which indirectly to the JFrame.

但是现在在你的 updateImage()方法中,你正在初始化一个新的 JLabel ,现在它驻留在另一个内存位置,通过编写 tempImage = new JLabel(new ImageIcon(scaledImage)); 然后指向你的 swingImage(JLabel)指向这个新创建的 JLabel ,但这个新创建的 JLabel 从未在任何时候添加到 JPanel 。因此,即使您尝试 revalidate()/ repaint()/ setVisible(...),它也不可见。因此,要么将 updateImage(...)方法的代码更改为:

But now inside your updateImage() method, you are initializing a new JLabel, now it resides in some another memory location, by writing tempImage = new JLabel(new ImageIcon(scaledImage)); and after this you pointing your swingImage(JLabel) to point to this newly created JLabel, but this newly created JLabel was never added to the JPanel, at any point. Hence it will not be visible, even if you try revalidate()/repaint()/setVisible(...). Hence either you change the code for your updateImage(...) method to this :

protected void updateImage(String name)
{
    BufferedImage image = null;
    Image scaledImage = null;
    JLabel tempImage;

    try
    {
        image = ImageIO.read(new File(name));
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // getScaledImage returns an Image that's been resized
    // proportionally to my thumbnail constraints
    scaledImage = getScaledImage(image, THUMB_SIZE_X, THUMB_SIZE_Y);
    tempImage = new JLabel(new ImageIcon(scaledImage));
    rightPane.remove(swingImage);
    swingImage = tempImage;
    rightPane.add(swingImage, BorderLayout.PAGE_START);
    rightPane.revalidate();
    rightPane.repaint(); // required sometimes
}

否则使用 JLabel.setIcon (...)如前所述: - )

Or else use JLabel.setIcon(...) as mentioned earlier :-)

更新答案

UPDATED THE ANSWER

这里看看如何将 New JLabel 放置在旧的位置,

Here see how a New JLabel is placed at the position of the old one,

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SlideShow extends JPanel
{
    private int i = 0;
    private Timer timer;
    private JLabel images = new JLabel();
    private Icon[] icons = {UIManager.getIcon("OptionPane.informationIcon"),
                            UIManager.getIcon("OptionPane.errorIcon"),
                            UIManager.getIcon("OptionPane.warningIcon")};
    private ActionListener action = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            i++;
            System.out.println(i);

            if(i == 4)
            {
                timer.stop();
                System.exit(0);
            }
            remove(images);
            JLabel temp = new JLabel(icons[i - 1]);
            images = temp;
            add(images);
            revalidate();
            repaint();
        }
    };

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("SLIDE SHOW");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);

        this.setLayout(new FlowLayout(FlowLayout.LEFT));

        add(images);

        frame.getContentPane().add(this, BorderLayout.CENTER);

        frame.setSize(300, 300);
        frame.setVisible(true);
        timer = new Timer(2000, action);
        timer.start();
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new SlideShow().createAndDisplayGUI();
            }
        });
    }
}

对于你的问题:这两个我试过的选项比另一个好吗?

setIcon(...)在另一方面有优势,从某种意义上说,在添加/删除 JLabel 之后,你不必费心去revalidate()/ repaint()。此外,您每次添加它都不需要记住 JLabel 的位置。它保持在它的位置,你只需调用一种方法来改变图像,没有任何附加条件,工作就完成了,没有任何麻烦。

setIcon(...) has an edge over the other way, in the sense, you doesn't have to bother about revalidate()/repaint() thingy after adding/remove JLabel. Moreover, you don't need to remember the placement of your JLabel everytime, you add it. It remains at it's position, and you simply call the one method to change the image, with no strings attached and the work is done, without any headaches.

和问题2:我有点怀疑,记录数组是什么?

And for Question 2 : I had a bit of doubt, as to what is Array of Records ?

这篇关于更新JLabel中包含的图像 - 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 13:50