package ztf.start;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import ztf.bean.ChatListModel;
import java.util.Random;
/**
* @Description:
* @Author:ZTF
* @Date:2018/6/6 18:06
*/
public class ListViewWithImages extends Application {
private final Image IMAGE1 = new Image("http://othgjp7hs.bkt.clouddn.com/18-6-8/2780393.jpg");
private final Image IMAGE2 = new Image("http://othgjp7hs.bkt.clouddn.com/18-6-8/36061669.jpg");
private final Image IMAGE3 = new Image("http://othgjp7hs.bkt.clouddn.com/18-6-8/35725819.jpg");
private final Image IMAGEWHITE = new Image("http://othgjp7hs.bkt.clouddn.com/18-6-8/75659527.jpg");
private Image[] listOfImages = {IMAGE1, IMAGE2, IMAGE3};
@Override
public void start(Stage primaryStage) throws Exception {
ListView listView = new ListView<>();
ObservableList items =FXCollections.observableArrayList (
new ChatListModel("aaa","1","123"),
new ChatListModel("bbb","2","123"),
new ChatListModel("ccc","3","123")
);
listView.setItems(items);
listView.setOnMouseClicked(click -> {
if (click.getClickCount() == 2) {
ChatListModel selectedItem = listView.getSelectionModel()
.getSelectedItem();
System.out.println(selectedItem);
}
});
listView.setCellFactory(param -> new ListCell() {
private ImageView imageView = new ImageView();
@Override
public void updateItem(ChatListModel chatListModel, boolean empty) {
super.updateItem(chatListModel, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if(chatListModel.getInit().equals("false")){
chatListModel.setInit("ture");
int index = new Random().nextInt(listOfImages.length);
imageView.setImage(listOfImages[index]);
chatListModel.setHeadPortrait(String.valueOf(index));
imageView.setFitHeight(56);
imageView.setFitWidth(56);
setText(chatListModel.getUserName());
setGraphic(imageView);
}else{
if(chatListModel.getMsgFlag().equals("true")){
if(chatListModel.getFlicker().equals("true")){
imageView.setImage(IMAGEWHITE);
imageView.setFitHeight(56);
imageView.setFitWidth(56);
setText(chatListModel.getUserName());
setGraphic(imageView);
}else{
normalHeadPortrait(chatListModel);
}
}else{
normalHeadPortrait(chatListModel);
}
}
}
}
private void normalHeadPortrait(ChatListModel chatListModel) {
imageView.setImage(listOfImages[Integer.valueOf(chatListModel.getHeadPortrait())]);
imageView.setFitHeight(56);
imageView.setFitWidth(56);
setText(chatListModel.getUserName());
setGraphic(imageView);
}
});
new Thread(() -> {
try{
Thread.sleep(4000);
while(true){
items.get(0).setMsgFlag("true");
items.get(1).setMsgFlag("true");
items.get(2).setMsgFlag("true");
for(int i=0;i<10;i++){
items.get(0).setFlicker("true");
items.get(1).setFlicker("true");
items.get(2).setFlicker("true");
listView.refresh();
Thread.sleep(200);
items.get(0).setFlicker("false");
items.get(1).setFlicker("false");
items.get(2).setFlicker("false");
listView.refresh();
Thread.sleep(200);
}
items.get(0).setMsgFlag("false");
items.get(1).setMsgFlag("false");
items.get(1).setMsgFlag("false");
listView.refresh();
Thread.sleep(4000);
}
}catch (Exception e){
}
}).start();
VBox box = new VBox(listView);
box.setAlignment(Pos.CENTER);
Scene scene = new Scene(box, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
package ztf.bean;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.image.Image;
import java.io.Serializable;
/**
* @Description:
* @Author:ZTF
* @Date:2018/6/8 8:21
*/
public class ChatListModel implements Serializable {
private final StringProperty userName;
private final StringProperty ip;
private final StringProperty port;
//头像序号
private final StringProperty headPortrait;
//是否有未读信息
private final StringProperty msgFlag;
//当前是否闪烁白色状态
private final StringProperty flicker;
//是否已经初始化
private final StringProperty init;
{
this.msgFlag = new SimpleStringProperty("false");
this.flicker = new SimpleStringProperty("false");
this.init=new SimpleStringProperty("false");
this.headPortrait=new SimpleStringProperty("null");
}
public ChatListModel(String userName, String ip, String port ) {
this.userName = new SimpleStringProperty(userName);
this.ip = new SimpleStringProperty(ip);
this.port = new SimpleStringProperty(port);
}
public String getUserName() {
return userName.get();
}
public StringProperty userNameProperty() {
return userName;
}
public void setUserName(String userName) {
this.userName.set(userName);
}
public String getIp() {
return ip.get();
}
public StringProperty ipProperty() {
return ip;
}
public void setIp(String ip) {
this.ip.set(ip);
}
public String getPort() {
return port.get();
}
public StringProperty portProperty() {
return port;
}
public void setPort(String port) {
this.port.set(port);
}
public String getHeadPortrait() {
return headPortrait.get();
}
public StringProperty headPortraitProperty() {
return headPortrait;
}
public void setHeadPortrait(String headPortrait) {
this.headPortrait.set(headPortrait);
}
public String getMsgFlag() {
return msgFlag.get();
}
public StringProperty msgFlagProperty() {
return msgFlag;
}
public void setMsgFlag(String msgFlag) {
this.msgFlag.set(msgFlag);
}
public String getFlicker() {
return flicker.get();
}
public StringProperty flickerProperty() {
return flicker;
}
public void setFlicker(String flicker) {
this.flicker.set(flicker);
}
public String getInit() {
return init.get();
}
public StringProperty initProperty() {
return init;
}
public void setInit(String init) {
this.init.set(init);
}
@Override
public String toString() {
return "ChatListModel{" +
"userName=" + userName +
", ip=" + ip +
", port=" + port +
", headPortrait=" + headPortrait +
'}';
}
}
代码写得很粗糙,主要为了展示相应API,主要实现思路是用listview中的重写的函数进行监听并且在item里面附加一个image,同时添加一个双击事件,便于后期弹出窗口,一旦item发生改变了,就会执行该方法,值得注意的是,代码中的refresh不是javafx推崇的方式,这种强制刷新UI布局的方式并不是最佳实践,有兴趣可以自行研究