简体   繁体   English

如何在 Swing 中加载背景图像而不在顶部隐藏组件

[英]How to load a background image without hiding components on top in Swing

I have a JPanel that holds a few JLabel that display some informations.我有一个JPanel ,其中包含一些显示一些信息的JLabel And i use another JLabel to hold a background image that I'm going to get from a URL.我使用另一个 JLabel 来保存我将从 URL 获得的背景图像。 I have used GirdBagLayout to set this up and this is what I have.我已经使用GirdBagLayout来设置它,这就是我所拥有的。

来自 alux.com 频道的 Youtube 视频

Now The issue i have is this : Since the image if of high resolution, it takes time to load hence the app seems slow.现在我遇到的问题是:由于图像是高分辨率的,因此加载需要时间,因此应用程序似乎很慢。

    vidThumbnailIcon = new ImageIcon(ImageIO.read(imageURL)) ////http link
    thumbnailLabel.setIcon(vidThumbnailIcon);

I have tried to put the previous lines of code in a different thread but, since it loads later, it does paint over the previously inserted JLabels That means all other components disappear.我试图将前面的代码行放在不同的线程中,但是由于它稍后加载,它确实会覆盖先前插入的JLabels这意味着所有其他组件都消失了。 I also tried using the paint method like我也尝试过使用绘画方法,比如

 @Override
protected void paintComponent(Graphics g){
    super.paintComponent(g);
    g.drawImage(vidThumbnailIcon.getImage(), 0, 0, this.getWidth(),this.getHeight(), null);
}

and paint the background of the JPanel with no success.并没有成功绘制JPanel的背景。

The only way i have found is to get the image first, load the image to the background, and then add other components on top.我发现的唯一方法是先获取图像,将图像加载到背景,然后在顶部添加其他组件。 But it's too slow, limited by my slow internet.但它太慢了,受我网速慢的限制。 Is there any alternative to this?有没有其他选择? Meaning, loading the image later but still not hiding everything else.意思是稍后加载图像但仍然没有隐藏其他所有内容。

The code编码

public class VideoDetailsView extends JPanel{

    private ImageIcon vidThumbnailIcon;
    private Video video;
    public VideoDetailsView(Video video){
        this.video = video;
        try{
            var imageLink = new URL(video.thumbnailLink);
            vidThumbnailIcon = new ImageIcon(ImageIO.read(imageLink));
        } catch (MalformedURLException ex) {
            vidThumbnailIcon = new ImageIcon("assets/icons/default_thumbnail.png");
        } catch (Exception ex) { 
            vidThumbnailIcon = new ImageIcon("assets/icons/default_thumbnail.png");
        }
        initGUIComponents();
    }

    private void initGUIComponents() {
        var vidTitleLabel = new JLabel(video.title);
        CustomComponent.customizeLabel(vidTitleLabel, 4);
        var vidViewsLabel = new JLabel(video.viewCount);
        CustomComponent.customizeLabel(vidViewsLabel, 1);
        var vidChannelLabel = new JLabel(video.channel);
        CustomComponent.customizeLabel(vidChannelLabel, 1);
        var vidDateLabel = new JLabel(video.releaseDate);
        CustomComponent.customizeLabel(vidDateLabel, 1);
        var vidDurationLabel = new JLabel(video.duration);
        CustomComponent.customizeLabel(vidDurationLabel, 1);
        var vidCommentsLabel = new JLabel(video.commentCount);
        CustomComponent.customizeLabel(vidCommentsLabel, 1);
        
        var layout = new GridBagLayout();    
        var gbc = new GridBagConstraints();
        setLayout(layout);
   
        gbc.weighty = 1;
        gbc.anchor = GridBagConstraints.WEST;
        addComponent(vidViewsLabel, this, layout,gbc, 0,0,1,1);
        addComponent(vidCommentsLabel, this, layout, gbc, 0,1,1,1);
        addComponent(vidChannelLabel, this, layout,gbc, 0,2,1,1);
        addComponent(vidDateLabel, this, layout,gbc, 0,3,1,1);
        addComponent(vidDurationLabel, this, layout,gbc, 0,4,1,1);
        gbc.weightx = 1;
        addComponent(vidTitleLabel, this, layout,gbc, 0,6,2,2);
        
    }
   public void addComponent(JComponent component, Container container,
            GridBagLayout layout, GridBagConstraints gbc,
            int gridx, int gridy,
            int gridwidth, int gridheight ){
            gbc.gridx = gridx;
            gbc.gridy = gridy;
            gbc.gridwidth = gridwidth;
            gbc.gridheight = gridheight;
            container.add(component,gbc);
    }
    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(vidThumbnailIcon.getImage(), 0, 0, this.getWidth(),this.getHeight(), null);
    }
}

With the help suggested from trashgod and camickr,在垃圾神和 camickr 建议的帮助下,

[1]: https://stackoverflow.com/a/25043676/230513 this is how i have proceded. [1]: https://stackoverflow.com/a/25043676/230513这就是我的处理方式。

  1. Add all the text holder JLabels to the JPanel将所有文本持有者 JLabels 添加到 JPanel
  2. write the paintComponent method as:将paintComponent方法写为:
    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(vidThumbnailIcon.getImage(), 0, 0,componentToPaint.getWidth(),componenttoPaint.getHeight(), componentToPaint);
    }
  1. start a new Thread to download the image from URL using any multithreading technique such as SwingWorker or any other.使用任何多线程技术(例如 SwingWorker 或任何其他技术)启动一个新线程以从 URL 下载图像。 and execute the downloading there then before the end, call repaint() .并在那里执行下载,然后在结束之前调用repaint()
public void run() {
        try{
                    var imageURL = new URL(thumbnailURL);
                    vidThumbnailIcon = new ImageIcon(ImageIO.read(imageURL));  
                } catch (MalformedURLException ex) {
                    vidThumbnailIcon = new ImageIcon("assets/icons/default_thumbnail.png");
                } catch (Exception ex) {
                    
                    vidThumbnailIcon = new ImageIcon("assets/icons/default_thumbnail.png");
                }
        repaint();///this helps display the image right after the downloading has ended
    }
  1. finally call this thread object after the GUI set up最后在 GUI 设置后调用这个线程 object
     initGUIComponents(); loadThumbnail(); ///In this method, you create a thread, use it to load the image and then call repaint() inside here.

I'm not sure this is the best way to do it but atleast it worked for me.我不确定这是最好的方法,但至少它对我有用。 Thank family for the support感谢家人的支持

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

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