[英]How to load a background image without hiding components on top in Swing
我有一个JPanel
,其中包含一些显示一些信息的JLabel
。 我使用另一个 JLabel 来保存我将从 URL 获得的背景图像。 我已经使用GirdBagLayout
来设置它,这就是我所拥有的。
现在我遇到的问题是:由于图像是高分辨率的,因此加载需要时间,因此应用程序似乎很慢。
vidThumbnailIcon = new ImageIcon(ImageIO.read(imageURL)) ////http link
thumbnailLabel.setIcon(vidThumbnailIcon);
我试图将前面的代码行放在不同的线程中,但是由于它稍后加载,它确实会覆盖先前插入的JLabels
这意味着所有其他组件都消失了。 我也尝试过使用绘画方法,比如
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(vidThumbnailIcon.getImage(), 0, 0, this.getWidth(),this.getHeight(), null);
}
并没有成功绘制JPanel的背景。
我发现的唯一方法是先获取图像,将图像加载到背景,然后在顶部添加其他组件。 但它太慢了,受我网速慢的限制。 有没有其他选择? 意思是稍后加载图像但仍然没有隐藏其他所有内容。
编码
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);
}
}
在垃圾神和 camickr 建议的帮助下,
[1]: https://stackoverflow.com/a/25043676/230513这就是我的处理方式。
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(vidThumbnailIcon.getImage(), 0, 0,componentToPaint.getWidth(),componenttoPaint.getHeight(), componentToPaint);
}
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
}
initGUIComponents(); loadThumbnail(); ///In this method, you create a thread, use it to load the image and then call repaint() inside here.
我不确定这是最好的方法,但至少它对我有用。 感谢家人的支持
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.