当前位置: 首页 > 面试题库 >

更新JLabel中包含的图像-问题

沈伟
2023-03-14
问题内容

我目前无法正常工作的应用程序部分是能够一次滚动浏览并显示一张图像列表。我从用户那里得到一个目录,在该目录中的所有文件中进行后台处理,然后加载仅包含jpeg和png的数组。接下来,我想用第一个图像更新JLabel,并提供上一个和下一个按钮以滚动浏览并依次显示每个图像。当我尝试显示第二张图像时,它没有更新…这是到目前为止我得到的:

public class CreateGallery
{
    private JLabel swingImage;

我用来更新图像的方法:

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放在…

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
= new JLabel。但是我不确定如何将BufferedImage或Image转换为JLabel以便仅更新swingImage。


问题答案:

而不是创建的NewInstanceJLabel每一个Image,只需使用一个JLabel的setIcon#(…)的方法JLabel来改变形象。

一个小示例程序:

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进行操作,因此以下是使用ImageIO与该JLabel相关的好示例

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

createAndShowGUI()方法内部,您初始化了JLabel(swingImage),然后将JPanel其间接添加到中JFrame

但是,现在在您的updateImage()方法内部,您正在初始化一个new JLabel,现在它通过写入tempImage = new JLabel(newImageIcon(scaledImage));而位于另一个内存位置,在此之后,您指向swingImage(JLabel)该新创建的JLabel,但是在任何时候JLabel都从未将该新创建的添加到JPanel。因此,即使您尝试,它也将不可见revalidate()/repaint()/setVisible(...)。因此,您可以将updateImage(...)方法的代码更改为此:

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(...)前面提到的:-)

更新答案

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

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(...)从某种意义上说,在某种意义上具有优势,在添加/删除之后,您不必为revalidate()/
repaint()感到麻烦JLabel。而且,您不必JLabel每次都记住它的位置,只需添加它。它保持原样,您只需调用一个方法即可更改图像,而无需附加任何字符串,并且工作已完成,没有任何麻烦。

对于问题2:我有什么疑问Array of Records



 类似资料:
  • 我想尝试一些东西,但我不知道如何去做,也不确定是否有可能。 我有一个使用GridLayout的jLabel的JPanel。然后将此JPanel添加到JScrollPane中。 如果jlabel中有图像,则为一个。这个图像应该告诉我程序中的角色在哪里。我只是想知道它的位置。因此,基本上,当我想要移动角色时,我会从当前JLabel中删除图像,并将其添加到下一个JLabel中。我知道这可能是有史以来最糟

  • 问题内容: 我程序的想法是从以前保存在其他JFrame中的列表中选择一个名称。我想在标签中一个接一个地打印所有名称,它们之间的间隔很小,然后停在其中一个名称上。问题是,如果有多个代码,则无法正常工作。 这是我的代码的一部分: 问题答案: 不要使用循环或。只需使用即可。以下将导致每1000毫秒发生30 次迭代 。您可以相应地调整代码,使其适应每隔毫秒发生一次的情况。 如果需要,您可以在构造函数中设置

  • 问题内容: 我目前正在建立一个基本上相当于搜索引擎和网络漫画画廊之间的交叉点的网站,该画廊侧重于引用来源并给予作者称赞。 我正在尝试找出一种搜索图像以在其中查找字符的方法。 例如: 假设我将红色字符和绿色字符另存为“ Red Man”和“ Green Man”,我如何确定图像是否包含一个或另一个。 不需要100%识别,或者什么是我想创建的更多功能,我不确定从哪里开始。我已经做了很多谷歌搜索来进行图

  • 问题内容: 我处理了大量直观的示例测试案例。是否有任何方便的方法将它们包含在Java源代码中并在Javadocs中进行链接,因此我的IDE可以在编码时自动显示它们(通过在IDE中调用Javadoc渲染器功能)? 我尝试将图像放置在Java源代码旁边并使用,但是它没有使用(我使用了png)。 (注意-在这种情况下,它在我的测试源中) 问题答案: 由于您没有显示任何消息来源,所以我只能做个玻璃球猜测…

  • 我有一个jfilechooser,它帮助搜索和选择图像上传到项目数据库。还有一个缩略图类可以将上传的图像压缩成所需的大小。运行文件选择器的按钮action_performed的代码如下:

  • 我正在尝试创建一个,它由HTML文本和助记符组成。效果很好。我能够获取为其设置标签的组件的焦点。 感谢任何回答。