尝试为单个列表视图单元格设置样式时遇到困难,例如聊天应用程序
Difficulties while trying to style individual list-view cells, like a chat app
对于我的聊天 GUI,我正在尝试 'show' 将消息的样式设置为 Facebook 的 Messenger 样式,或者至少以这种方式设置。如果我是发送它们的人,它们应该靠右对齐,如果我从其他人那里收到消息,它们应该靠左对齐,并且它们的背景颜色应该不同。
我做了类似的东西,但它真的很难看,除此之外,我不能单独设计它们的样式,但以偶数方式,所以它看起来像这样,即使是,一条消息从未发送给 'create' 他们。
消息结构真的很简单
public void sendMessageOnClick(){
sendButton.setOnAction((e) -> {
String message = textInput.getText();
chatHistory.getItems().add("Sorin: " + message + "\n");
textInput.clear();
sendButton.setDisable(true);
});
}
诀窍是使用细胞工厂返回自定义 ListCell
s:
@FXML
private ListView<ChatMessage> chatHistory;
private String user = "Sorin";
private static final PseudoClass USER_MESSAGE = PseudoClass.getPseudoClass("user-message");
@FXML
private void initialize() {
sendButton.disableProperty().bind(textInput.textProperty().isEmpty());
final ColumnConstraints ownUserConstraints = new ColumnConstraints();
ownUserConstraints.setHalignment(HPos.LEFT);
ownUserConstraints.setHgrow(Priority.ALWAYS);
final ColumnConstraints foreignUserConstraints = new ColumnConstraints();
foreignUserConstraints.setHalignment(HPos.RIGHT);
foreignUserConstraints.setHgrow(Priority.ALWAYS);
final ColumnConstraints userConstraints = new ColumnConstraints();
userConstraints.setHgrow(Priority.NEVER);
chatHistory.setCellFactory(lv -> new ListCell<ChatMessage>() {
private final Label message;
private final Label userName;
private final GridPane content;
{
message = new Label();
userName = new Label();
content = new GridPane();
content.setHgap(10);
content.addRow(0, userName, message);
content.getColumnConstraints().addAll(userConstraints, userConstraints);
}
@Override
protected void updateItem(ChatMessage item, boolean empty) {
super.updateItem(item, empty);
boolean userMessage;
if (empty || item == null) {
userMessage = false;
setGraphic(null);
} else {
userMessage = user.equals(item.getUserName());
userName.setText(item.getUserName() + ":");
message.setText(item.getMessage());
setGraphic(content);
content.getColumnConstraints().set(1, userMessage
? ownUserConstraints
: foreignUserConstraints);
}
pseudoClassStateChanged(USER_MESSAGE, userMessage);
}
});
}
public class ChatMessage {
private final String userName;
private final String message;
public ChatMessage(String userName, String message) {
this.userName = userName;
this.message = message;
}
public String getUserName() {
return userName;
}
public String getMessage() {
return message;
}
}
sendButton.setOnAction((e) -> {
...
chatHistory.getItems().add(new ChatMessage(user, message);
...
});
CSS 样式表:
.list-cell {
-fx-background: lightblue;
}
.list-cell:user-message,
.list-cell:empty {
-fx-background: -fx-control-inner-background;
}
.list-view:focused .list-cell:filled:selected {
-fx-background: -fx-selection-bar;
}
顺便说一句:为了使自己用户的消息不与其他用户名重叠,您需要将 userConstraints
的 with 设置为用户名的最大文本宽度...
对于我的聊天 GUI,我正在尝试 'show' 将消息的样式设置为 Facebook 的 Messenger 样式,或者至少以这种方式设置。如果我是发送它们的人,它们应该靠右对齐,如果我从其他人那里收到消息,它们应该靠左对齐,并且它们的背景颜色应该不同。
我做了类似的东西,但它真的很难看,除此之外,我不能单独设计它们的样式,但以偶数方式,所以它看起来像这样,即使是,一条消息从未发送给 'create' 他们。
消息结构真的很简单
public void sendMessageOnClick(){
sendButton.setOnAction((e) -> {
String message = textInput.getText();
chatHistory.getItems().add("Sorin: " + message + "\n");
textInput.clear();
sendButton.setDisable(true);
});
}
诀窍是使用细胞工厂返回自定义 ListCell
s:
@FXML
private ListView<ChatMessage> chatHistory;
private String user = "Sorin";
private static final PseudoClass USER_MESSAGE = PseudoClass.getPseudoClass("user-message");
@FXML
private void initialize() {
sendButton.disableProperty().bind(textInput.textProperty().isEmpty());
final ColumnConstraints ownUserConstraints = new ColumnConstraints();
ownUserConstraints.setHalignment(HPos.LEFT);
ownUserConstraints.setHgrow(Priority.ALWAYS);
final ColumnConstraints foreignUserConstraints = new ColumnConstraints();
foreignUserConstraints.setHalignment(HPos.RIGHT);
foreignUserConstraints.setHgrow(Priority.ALWAYS);
final ColumnConstraints userConstraints = new ColumnConstraints();
userConstraints.setHgrow(Priority.NEVER);
chatHistory.setCellFactory(lv -> new ListCell<ChatMessage>() {
private final Label message;
private final Label userName;
private final GridPane content;
{
message = new Label();
userName = new Label();
content = new GridPane();
content.setHgap(10);
content.addRow(0, userName, message);
content.getColumnConstraints().addAll(userConstraints, userConstraints);
}
@Override
protected void updateItem(ChatMessage item, boolean empty) {
super.updateItem(item, empty);
boolean userMessage;
if (empty || item == null) {
userMessage = false;
setGraphic(null);
} else {
userMessage = user.equals(item.getUserName());
userName.setText(item.getUserName() + ":");
message.setText(item.getMessage());
setGraphic(content);
content.getColumnConstraints().set(1, userMessage
? ownUserConstraints
: foreignUserConstraints);
}
pseudoClassStateChanged(USER_MESSAGE, userMessage);
}
});
}
public class ChatMessage {
private final String userName;
private final String message;
public ChatMessage(String userName, String message) {
this.userName = userName;
this.message = message;
}
public String getUserName() {
return userName;
}
public String getMessage() {
return message;
}
}
sendButton.setOnAction((e) -> {
...
chatHistory.getItems().add(new ChatMessage(user, message);
...
});
CSS 样式表:
.list-cell {
-fx-background: lightblue;
}
.list-cell:user-message,
.list-cell:empty {
-fx-background: -fx-control-inner-background;
}
.list-view:focused .list-cell:filled:selected {
-fx-background: -fx-selection-bar;
}
顺便说一句:为了使自己用户的消息不与其他用户名重叠,您需要将 userConstraints
的 with 设置为用户名的最大文本宽度...