2017-08-01 99 views
0

我正在使用此答案中建议的组合框:JavaFx: show DatePicker,但显示正确的文本时出现问题。如果我从DatePicker中选择一个日期,我试图设置编辑器的文本,但它什么都没发生。 这是我曾尝试:JavaFx:组合框编辑器的文本

getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) ->{ 
    if (newValue != null) { 
     if (MyTupe.DATE.equals(newValue.getType())) { 
      initDatePicker(); 
      datePicker.valueProperty().addListener((obs, oldDate, newDate) -> { 
       newValue.setValue(newDate); 
       getEditor().setText(newDate.toString()); 
       datePopOver.hide(); 
      }); 
      StackPane stackPane = new StackPane(datePicker); 
      stackPane.setPadding(new Insets(10, 10, 10, 10)); 

      datePopOver.setContentNode(stackPane); 
      datePopOver.show(this); 
     } else { 
      datePopOver.hide(); 
     } 
    } 
}); 

尝试了很多之后,我添加了两个事件编辑器的textProperty和setOnMouseClicked这样的:如果我不用手动设置

getEditor().textProperty().addListener((observable, oldValue, newValue) -> { 
    System.out.println("Text changed"); 
}); 
setOnMouseClicked(event -> { 
    System.out.println(getEditor().getText()); 
}); 

首先不会被触发getEditor().setText();即使我改变了comboBox的值,这对我来说有点奇怪,因为我认为这个textField包含了comboBox的文本(也许我错了)。如果删除该行,则每次显示空字符串时都会显示mouseClick事件。 如果getEditor().setText();行存在,编辑器的getText()将返回正确的文本,但不会显示在组合框中。

的问题:

  • 在哪里存储组合框的文本?
  • 如何更改selectedItemProperty侦听器中的文本?

我认为,也许我在某处犯了一个错误,所以这是为什么这不起作用,但我不知道什么,你能帮助我吗?

+0

- ComboBoxes可以有一个StringConverter,将它的值转换为显示的文本。 - 使用onAction替代onMouseClicked来触发ComboBox和DatePicker上的用户输入操作。 –

回答

1

在链接代码

替换:

items.set(0, new ComboBoxNode(newDate, DATE_TYPE)); 

有:

items.set(customComboBox.getSelectionModel().getSelectedIndex(), new ComboBoxNode(newDate, DATE_TYPE)); 

链接的代码只在位置零更改日期。在这个新代码中,适当位置的日期发生了变化。

全码:

import java.time.LocalDate; 
import java.time.Month; 
import java.util.Objects; 
import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.DatePicker; 
import javafx.scene.layout.FlowPane; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 
import org.controlsfx.control.PopOver; 

/** 
* 
* @author blj0011 
*/ 
public class JavaFXApplication155 extends Application 
{ 

    private static final String DATE_TYPE = "DATE"; 

    private class ComboBoxNode { 
     private final Object value; 
     private final String type; 

     private ComboBoxNode(final Object value, final String type) { 
      this.value = value; 
      this.type = type; 
     } 

     @Override 
     public String toString() { 
      return Objects.toString(value); 
     } 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) { 
     final ObservableList<ComboBoxNode> items = 
       FXCollections.observableArrayList(
         new ComboBoxNode(LocalDate.now(), DATE_TYPE), 
         new ComboBoxNode(LocalDate.of(2017, Month.APRIL, 15), DATE_TYPE),//Added new date to ComboBox 
         new ComboBoxNode("11:35AM", "TIME")); 

     final PopOver datePopOver = new PopOver(); 
     datePopOver.setTitle("Enter new date"); 
     datePopOver.setCornerRadius(10); 
     datePopOver.setHeaderAlwaysVisible(true); 
     //datePopOver.set(true); 
     datePopOver.setAutoHide(true); 

     final ComboBox<ComboBoxNode> customComboBox = new ComboBox<>(items); 


     customComboBox.getSelectionModel().selectedItemProperty().addListener((o, old, newNode) -> { 
      if (newNode != null) { 
       if (newNode.type.equals(DATE_TYPE)) { 
        final DatePicker datePicker = new DatePicker((LocalDate) newNode.value); 
        datePicker.valueProperty().addListener((obs, oldDate, newDate) -> { 
         items.set(customComboBox.getSelectionModel().getSelectedIndex(), new ComboBoxNode(newDate, DATE_TYPE));//Fixed this line of code 
         datePopOver.hide(); 
        }); 

        final StackPane stackPane = new StackPane(datePicker); 
        stackPane.setPadding(new Insets(10, 10, 10, 10)); 

        datePopOver.setContentNode(stackPane); 
        datePopOver.show(customComboBox); 
       } else { 
        datePopOver.hide(); 
       } 
      } 
     }); 

     final FlowPane pane = new FlowPane(customComboBox); 
     pane.setPadding(new Insets(10, 10, 10, 10)); 
     pane.setPrefWidth(400); 
     pane.setPrefHeight(300); 

     // Show Scene 
     final Scene scene = new Scene(pane); 
     primaryStage.setTitle("Popup calendar"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 
} 
+1

它工作,其实我这样做:'newValue.setDate(newDate);'和'items.set(customComboBox.getSelectionModel()。getSelectedIndex(),customComboBox.getselectionModel()。getSelecteditem());'' – Sunflame

1

关于你的问题:其中存储组合框的文本? 通常,JavaFX控件基于MVC架构,数据存储在模型中。控件仅根据定义的转换器表示模型数据,并自动对模型的任何更改作出反应。

因此,在你的情况下,数据存储在ObservableList items。要更新组合框,只需用新对象替换相应的项目即可。

请注意,组合框已经听ObservableList和任何添加/删除/设置将自动表示在用户界面。

为什么这个代码不工作:

newValue.setValue(newDate); 

因为你改变一个项目的内部状态和ObservableList items不会对这种变化做出反应。只有更改名单才有用。 @Sedrick提出了正确的解决方案。请参阅the related question