【发布时间】:2018-05-16 04:39:22
【问题描述】:
我从事我的第一个 JavaFX 项目,但遇到了 listview 自定义单元工厂的问题。这是我的代码
package ir.sadeghpro.instagram.cell;
import com.ibm.icu.util.PersianCalendar;
import ir.sadeghpro.insta.client.Comment;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;
import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
public class DischargeComment extends ListCell<Comment> {
@FXML
private AnchorPane pane;
@FXML
private TextFlow lblComment;
@FXML
private Label lblDate;
@FXML
private Label lblTime;
@FXML
private Hyperlink lblUsername;
@FXML
private ImageView img;
public static String search = "";
private FXMLLoader mLLoader;
private static Map<String, Image> images = new HashMap<>();
@Override
protected void updateItem(Comment item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else {
if (mLLoader == null) {
mLLoader = new FXMLLoader(getClass().getClassLoader().getResource("cell/discharge_comment.fxml"));
mLLoader.setController(this);
try {
mLLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
ObservableList<Node> children = lblComment.getChildren();
lblComment.setTextAlignment(TextAlignment.JUSTIFY);
children.clear();
if (!search.isEmpty() && item.getText().contains(search)) {
int lastIndex = 0;
for (int index = item.getText().indexOf(search); index >= 0; index = item.getText().indexOf(search, index + 1)) {
Text text = new Text(item.getText().substring(lastIndex, index));
text.setTextAlignment(TextAlignment.LEFT);
children.add(text);
text = new Text(item.getText().substring(index, index + search.length()));
text.setTextAlignment(TextAlignment.LEFT);
text.setFill(Color.RED);
children.add(text);
lastIndex = index + search.length();
}
if (lastIndex < item.getText().length()) {
Text text = new Text(item.getText().substring(lastIndex));
text.setTextAlignment(TextAlignment.LEFT);
children.add(text);
}
} else {
children.add(new Text(item.getText()));
}
PersianCalendar persianCalendar = new PersianCalendar();
persianCalendar.setTimeInMillis(item.getTimestamp() * 1000L);
lblDate.setText(persianCalendar.get(Calendar.YEAR) + "/" + (persianCalendar.get(Calendar.MONTH) + 1) + "/" + persianCalendar.get(Calendar.DAY_OF_MONTH));
lblTime.setText(persianCalendar.get(Calendar.HOUR) + ":" + persianCalendar.get(Calendar.MINUTE));
lblUsername.setText(item.getOwnerUsername());
Image image;
if ((image = images.get(item.getOwnerId())) == null) {
img.setImage(null);
new Thread(() -> {
Image image1 = new Image(item.getOwnerProfilePicUrl());
images.put(item.getOwnerId(), image1);
Platform.runLater(() -> img.setImage(image1));
}).start();
} else {
img.setImage(image);
}
Circle clip = new Circle(25, 25, 25);
img.setClip(clip);
lblUsername.setOnMouseClicked(e->{
try {
Desktop.getDesktop().browse(new URI("https://www.instagram.com/" + item.getOwnerUsername()));
} catch (IOException | URISyntaxException exception) {
exception.printStackTrace();
}
});
setText(null);
setGraphic(pane);
setHeight(Region.USE_COMPUTED_SIZE);
}
}
}
我的问题在第 107-114 行。在这一行中,如果用户的图像在我下载它并添加到 hashmap 图像之前没有下载,接下来将它添加到查看,它工作正常但是当滚动列表快速时可能会下载 100 个图像,因为在下载图像后的线程中添加到单元格 ImageView 甚至单元格消失并且不再显示,例如,如果我在 Y 单元格中快速滚动一段时间,则 X 的图像在索引 10 中显示,而在索引 25 中的单元格 Y 显示在 Y 单元格中
对不起,如果我没有解释清楚,因为这是我的第一个 JavaFX 项目
【问题讨论】:
标签: java multithreading listview javafx