[英]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.