尝试设置单个列表视图单元格时的困难,例如聊天应用程序

时间:2018-04-13 07:13:38

标签: java css listview javafx listcellrenderer

对于我的聊天GUI,我试图“显示”Facebook的Messenger所做的消息,或者至少以这种方式。如果我是发送它们的人,它们应该与右边对齐,如果我从其他任何人那里收到消息,它们应该与左边对齐,并且它们的背景颜色应该是不同的。

我做了类似的东西,但它看起来很丑陋,除此之外,我不能单独设计它们,但是以奇怪的方式,所以它看起来像这样,甚至是,一条消息从来没有被发送给'创造'他们。enter image description here

消息结构非常简单

public void sendMessageOnClick(){
        sendButton.setOnAction((e) -> {
            String message = textInput.getText();
            chatHistory.getItems().add("Sorin: " + message + "\n");
            textInput.clear();
            sendButton.setDisable(true);
        });
    }

1 个答案:

答案 0 :(得分:2)

诀窍是使用单元工厂撤销自定义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;
}

BTW:对于不与其他用户名重叠的自己用户的消息的对齐,您需要将userConstraints的内容设置为用户名的最大文本宽度...