我们正在使用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
}
}
}
}
答案 0 :(得分:1)
这是一个非Kotlin
的示例。不要使用String item
,而要使用对象。在这种情况下,我创建一个Message
类。 Message
对象可以存储更多数据。我们可以使用这些数据来确定用户,然后根据用户设置HBox
对齐方式(您可以使用其他指标。
主要
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);
}
}
控制器
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>
消息类别
/**
*
* @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;
}
}