listview - JavaFx ListView用于聊天应用程序

标签 listview javafx kotlin

我们正在使用JavaFX实现聊天应用程序。但是,它没有按预期出来。

如何获得想要的结果?

这是我的目标。
Wanna result

但是,我陷入了这种结果。
currently result

而且,这是我的代码

我使用TextArea的原因是因为我需要能够拖动和复制。

但是,TextArea不支持高度和宽度自动调整功能,这太复杂了。

class ChatCellFactory(root: Scene) : ListCell<String>() {
    init {
        maxWidthProperty().bind(root.widthProperty().minus(20))
        prefWidthProperty().bind(root.widthProperty().minus(20))
    }

    override fun updateItem(value: String?, empty: Boolean) {
        if (graphic == null && value != null) {
            val textArea = TextArea()
            val root = HBox()
            val timeBar = HBox()
            timeBar.alignment = Pos.BOTTOM_LEFT
            timeBar.add(Label("10:00"))
            timeBar.prefHeightProperty().bind(textArea.heightProperty())
            root.add(timeBar)
            root.add(textArea)

            textArea.maxWidthProperty().bind(widthProperty().minus(100))
            textArea.minHeight = 10.0
            textArea.isWrapText = true
            textArea.isEditable = false
            textArea.text = value
            setMine(root)
            graphic = root
        }



    }

    private fun setMine(hBox: HBox) {
        hBox.alignment = Pos.BASELINE_RIGHT
        for (child in hBox.children) {
            if (child is TextArea) {
                child.style = "-fx-control-inner-background: #ffeb34;"
                break
            }
        }
    }
}

最佳答案

这是一个非Kotlin的示例。代替使用String item,使用对象。在这种情况下,我创建了一个Message类。 Message对象可以存储更多数据。我们可以使用此数据来确定用户,然后根据用户设置HBox对齐方式(您可以使用其他一些指标。

Main


import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 *
 * @author sedri
 */
public class ChatApp extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

Controller


import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;

public class FXMLDocumentController implements Initializable {

    @FXML private ListView<Message> lvChatWindow;
    @FXML private TextField tfUser1, tfUser2;

    ObservableList<Message> chatMessages = FXCollections.observableArrayList();//create observablelist for listview


    //Method use to handle button press that submits the 1st user's text to the listview.
    @FXML
    private void handleUser1SubmitMessage(ActionEvent event) {
        chatMessages.add(new Message(tfUser1.getText(), "User 1"));//get 1st user's text from his/her textfield and add message to observablelist
        tfUser1.setText("");//clear 1st user's textfield
    }

    //Method use to handle button press that submits the 2nd user's text to the listview.
    @FXML
    private void handleUser2SubmitMessage(ActionEvent event) {
        chatMessages.add(new Message(tfUser2.getText(), "User 2"));//get 2nd user's text from his/her textfield and add message to observablelist
        tfUser2.setText("");//clear 2nd user's textfield
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
        lvChatWindow.setItems(chatMessages);//attach the observablelist to the listview
        lvChatWindow.setCellFactory(param -> {
            ListCell<Message> cell = new ListCell<Message>(){                
                Label lblUserLeft = new Label();
                Label lblTextLeft = new Label();
                HBox hBoxLeft = new HBox(lblUserLeft, lblTextLeft);

                Label lblUserRight = new Label();
                Label lblTextRight = new Label();
                HBox hBoxRight = new HBox(lblTextRight, lblUserRight);

                {
                    hBoxLeft.setAlignment(Pos.CENTER_LEFT);
                    hBoxLeft.setSpacing(5);
                    hBoxRight.setAlignment(Pos.CENTER_RIGHT);
                    hBoxRight.setSpacing(5);
                }
                @Override
                protected void updateItem(Message item, boolean empty) {
                    super.updateItem(item, empty);

                    if(empty)
                    {
                        setText(null);
                        setGraphic(null);
                    }
                    else{
                        System.out.println(item.getUser());
                        if(item.getUser().equals("User 1"))
                        {
                            lblUserLeft.setText(item.getUser() + ":");
                            lblTextLeft.setText(item.getText());
                            setGraphic(hBoxLeft);
                        }
                        else{
                            lblUserRight.setText(":" + item.getUser());
                            lblTextRight.setText(item.getText());
                            setGraphic(hBoxRight);
                        }
                    }
                }

            };

            return cell;
        });
    }      
}

FXML


<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="349.0" prefWidth="549.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60" fx:controller="chatapp.FXMLDocumentController">
    <children>
        <Button fx:id="bntUser1Send" layoutX="99.0" layoutY="299.0" onAction="#handleUser1SubmitMessage" text="send message user1" />
        <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
      <Button fx:id="btnUser2Send" layoutX="351.0" layoutY="299.0" mnemonicParsing="false" onAction="#handleUser2SubmitMessage" text="send message user2" />
      <ListView fx:id="lvChatWindow" layoutX="75.0" layoutY="29.0" prefHeight="200.0" prefWidth="419.0" />
      <TextField fx:id="tfUser1" layoutX="36.0" layoutY="258.0" prefHeight="25.0" prefWidth="239.0" />
      <TextField fx:id="tfUser2" layoutX="293.0" layoutY="258.0" prefHeight="25.0" prefWidth="239.0" />
    </children>
</AnchorPane>

Message Class


/**
 *
 * @author sedrick
 */
public class Message {
    private String text;
    private String user;

    public Message(String text, String user) {
        this.text = text;
        this.user = user;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }
}

enter image description here

关于listview - JavaFx ListView用于聊天应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52193921/

相关文章:

kotlin - 如何解析具有相同名称的 Kotlin 函数/属性?

android - 加载图像时 ListView 非常慢(使用 Universal Image Loader)

c# - SQL查询在转换日期后更改列名

android - 在自定义 ListView 中更新 TextView

JavaFX:如何使表格单元格取决于另一个表格单元格的值

JavaFx - 交互式排序应用程序

c - ListView 滚动条闪烁

单元格编辑后 Javafx TableView 失去焦点

java - 带有 gradle build 的 Kotlin 警告

spring-boot - 使用 Kotlin 协程的 Spring Boot Rest 服务