用 TextField 替换选定的标签
Replace a selected Label with a TextField
我已经使用 :
创建了 ListView
个 Label
ListView<Label> list = new ListView<Label>();
Image folder = new Image(getClass().getResourceAsStream("folder.png"));
ObservableList<Label> data = FXCollections.observableArrayList();
for (int i = 0; i < 6; i++) {
Label lbl = new Label();
lbl.setText("label" + i);
lbl.setGraphic(new ImageView(folder));
lbl.setContentDisplay(ContentDisplay.LEFT);
lbl.setGraphicTextGap(10.2);
data.add(lbl);
}
list.setItems(data);
我希望用户能够双击 ListView
中的任何 Label
,所选择的 Label
应该替换为 TextField
以便用户可以动态输入新的标签名称。
用户按下 Enter 后,TextField
应该变回 Label
。
不要使用 Label
作为 ListView
的 data 的类型。使用 String
。然后你可以只使用标准 TextFieldListCell
,它具有你描述的功能。由于您希望在标准单元格显示中显示图形,只需继承 TextFieldListCell
并覆盖适当的方法以在未显示文本字段时包含图形:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import javafx.util.converter.DefaultStringConverter;
public class EditableListViewTest extends Application {
@Override
public void start(Stage primaryStage) {
ListView<String> list = new ListView<>();
Image testImg = new Rectangle(12, 12, Color.CORNFLOWERBLUE).snapshot(null, null);
for (int i = 0; i < 6; i++) {
list.getItems().add("label "+i);
}
StringConverter<String> identityStringConverter = new DefaultStringConverter();
list.setCellFactory(lv -> new TextFieldListCell<String>(identityStringConverter) {
private ImageView imageView = new ImageView(testImg);
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (! empty && ! isEditing()) {
setStaticGraphic();
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setStaticGraphic();
}
@Override
public void commitEdit(String newValue) {
super.commitEdit(newValue);
setStaticGraphic();
}
private void setStaticGraphic() {
setGraphic(imageView);
setContentDisplay(ContentDisplay.LEFT);
setGraphicTextGap(10.2);
}
});
list.setEditable(true);
primaryStage.setScene(new Scene(new BorderPane(list), 250, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我已经使用 :
创建了ListView
个 Label
ListView<Label> list = new ListView<Label>();
Image folder = new Image(getClass().getResourceAsStream("folder.png"));
ObservableList<Label> data = FXCollections.observableArrayList();
for (int i = 0; i < 6; i++) {
Label lbl = new Label();
lbl.setText("label" + i);
lbl.setGraphic(new ImageView(folder));
lbl.setContentDisplay(ContentDisplay.LEFT);
lbl.setGraphicTextGap(10.2);
data.add(lbl);
}
list.setItems(data);
我希望用户能够双击 ListView
中的任何 Label
,所选择的 Label
应该替换为 TextField
以便用户可以动态输入新的标签名称。
用户按下 Enter 后,TextField
应该变回 Label
。
不要使用 Label
作为 ListView
的 data 的类型。使用 String
。然后你可以只使用标准 TextFieldListCell
,它具有你描述的功能。由于您希望在标准单元格显示中显示图形,只需继承 TextFieldListCell
并覆盖适当的方法以在未显示文本字段时包含图形:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import javafx.util.converter.DefaultStringConverter;
public class EditableListViewTest extends Application {
@Override
public void start(Stage primaryStage) {
ListView<String> list = new ListView<>();
Image testImg = new Rectangle(12, 12, Color.CORNFLOWERBLUE).snapshot(null, null);
for (int i = 0; i < 6; i++) {
list.getItems().add("label "+i);
}
StringConverter<String> identityStringConverter = new DefaultStringConverter();
list.setCellFactory(lv -> new TextFieldListCell<String>(identityStringConverter) {
private ImageView imageView = new ImageView(testImg);
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (! empty && ! isEditing()) {
setStaticGraphic();
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setStaticGraphic();
}
@Override
public void commitEdit(String newValue) {
super.commitEdit(newValue);
setStaticGraphic();
}
private void setStaticGraphic() {
setGraphic(imageView);
setContentDisplay(ContentDisplay.LEFT);
setGraphicTextGap(10.2);
}
});
list.setEditable(true);
primaryStage.setScene(new Scene(new BorderPane(list), 250, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}