我有一個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);
}
}
uj5u.com熱心網友回復:
在垃圾神和 camickr 建議的幫助下,
[1]:https : //stackoverflow.com/a/25043676/230513 這就是我的處理方式。
- 將所有文本持有者 JLabels 添加到 JPanel
- 將paintComponent方法寫為:
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(vidThumbnailIcon.getImage(), 0, 0,componentToPaint.getWidth(),componenttoPaint.getHeight(), componentToPaint);
}
- 使用任何多執行緒技術(例如 SwingWorker 或任何其他技術)啟動一個新執行緒以從 URL 下載影像。并在那里執行下載,然后在結束之前呼叫
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
}
- 最終在 GUI 建立后呼叫這個執行緒物件
initGUIComponents(); loadThumbnail(); ///In this method, you create a thread, use it to load the image and then call repaint() inside here.
我不確定這是最好的方法,但至少它對我有用。感謝家人的支持
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/511850.html
標籤:爪哇多线程摇摆背景画
