Может ли JavaFX Node.snapshot (..) захватывать ComboBox и его всплывающее окно вместе? - PullRequest
1 голос
/ 01 октября 2019

У меня есть пользовательский счетчик, который обрабатывает значения LocalDate и включает PopupControl, который отображает календарь, аналогично элементу управления DatePicker. Это не совсем то же самое, что и проблема, описанная в вопросе, но оба случая аналогичны.

Я хотел бы сделать «снимок» и элемента управления и всплывающего окна, покакалендарь отображается. Используя метод Node.snapshot(..), я могу захватить счетчик отдельно и календарь, но не оба вместе. Примечание: я попытался изменить параметр SnapshotParemeters, требуемый методом, чтобы обеспечить значение viewport, которое включало бы и счетчик, и всплывающее окно, но безуспешно.

Я также пытался использовать Scene.snapshot(..) метод в обработчике событий для типа события WindowEvent.WINDOW_SHOWN. Это захватывает всю сцену, но ... НЕ .. показывает всплывающее окно.

По запросу @Kleopatra приведен некоторый минимальный воспроизводимый код :

public class ComboBoxController {

 @FXML
 private BorderPane rootPane;

 @SuppressWarnings("unchecked")
 @FXML
 private void initialize() {

      //- initialize controls
      final VBox vbox = new VBox();
      final ComboBox<String> comboBox = new ComboBox<>();

      //- populate containers
      rootPane.setCenter(vbox);
      vbox.getChildren().add(comboBox);

      //- make pref sizes sufficiently large to handle combo box and popup list view w/no overflow
      vbox.setPrefSize(200, 200);
      rootPane.setPrefSize(250, 250);

      //- load combo box items
      comboBox.setItems(FXCollections.observableArrayList());
      comboBox.getItems().setAll("red", "orange", "yellow", "green", "blue", "purple", "black", "white");

      //- register event handler
      comboBox.setOnShown(e -> {

           //- get handle for popup list view
           final Object skin = comboBox.getSkin();
           final Node node = ((ComboBoxListViewSkin<String>) comboBox.getSkin()).getPopupContent();
           final ListView<String> popupListView = ((ListView<String>) node);

           final String path = " [enter path to appropriate location on your file system] ";
           final SnapshotParameters parameters = new SnapshotParameters();



           Stream.of(
                     new Pair<>(vbox, "vbox.png"),
                     new Pair<>(comboBox, "comboBox.png"),
                     new Pair<>(popupListView, "popupListView.png"))
                 .forEach(p -> {
                      final WritableImage image = p.getKey().snapshot(parameters, null);
                      final File file = new File(path + p.getValue());
                      try {
                           ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
                      }
                      catch (final IOException ex) {
                      }
                 });

           //- expand viewport for snapshot parameters, this should provide enough space to
           //  display popup list view ..AND.. combo box ... assuming they can both be captured in
           //  the same snapshot.
           final Bounds bounds = vbox.getBoundsInParent();
           final Rectangle2D viewport = new Rectangle2D(
                                                        bounds.getMinX(),
                                                        bounds.getMinY(),
                                                        bounds.getWidth(),
                                                        bounds.getHeight());
           parameters.setViewport(viewport);
           Stream.of(
                     new Pair<>(vbox, "vbox2.png"),
                     new Pair<>(comboBox, "comboBox2.png"),
                     new Pair<>(popupListView, "popupListView2.png"))
                 .forEach(p -> {
                      final WritableImage image = p.getKey().snapshot(parameters, null);
                      final File file = new File(path + p.getValue());
                      try {
                           ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
                      }
                      catch (final IOException ex) {
                      }
                 });
      });
 }

}

Возможно ли то, что я пытаюсь сделать, и если да, то что я пропускаю и / или делаю неправильно?

...