/* * Copyright [2014] [Christian Loehnert, krampenschiesser@gmail.com] * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.ks.idnadrev.information.chart; import de.ks.BaseController; import de.ks.activity.initialization.LoadInFXThread; import de.ks.i18n.Localized; import de.ks.idnadrev.entity.information.*; import de.ks.validation.validators.NamedEntityMustNotExistValidator; import de.ks.validation.validators.NotEmptyValidator; import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.embed.swing.SwingFXUtils; import javafx.fxml.FXML; import javafx.geometry.Rectangle2D; import javafx.scene.Node; import javafx.scene.chart.Chart; import javafx.scene.control.*; import javafx.scene.image.WritableImage; import javafx.scene.layout.StackPane; import javafx.stage.FileChooser; import javafx.stage.Popup; import javafx.stage.Screen; import org.controlsfx.dialog.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Optional; import java.util.ResourceBundle; @LoadInFXThread public class ChartInfoController extends BaseController<ChartInfo> { private static final Logger log = LoggerFactory.getLogger(ChartInfoController.class); @FXML protected Button saveImage; @FXML protected Button fullscreen; @FXML protected StackPane previewContainer; @FXML protected TextField name; @FXML protected TextField yaxisTitle; @FXML protected Button addColumn; @FXML protected SplitPane splitPane; @FXML protected ChartDataEditor editorController; @FXML protected ScrollPane contentContainer; @FXML protected Button saveBtn; @FXML protected ComboBox<ChartType> chartType; protected final ChartPreviewHelper previewHelper = new ChartPreviewHelper(this); protected final ChartPreviewHelper fullScreenPreviewHelper = new ChartPreviewHelper(null); @Override public void initialize(URL location, ResourceBundle resources) { StringProperty nameProperty = store.getBinding().getStringProperty(UmlDiagramInfo.class, t -> t.getName()); name.textProperty().bindBidirectional(nameProperty); chartType.setItems(FXCollections.observableArrayList(ChartType.values())); chartType.getItems().remove(ChartType.BUBBLE); chartType.valueProperty().addListener((p, o, n) -> { ChartInfo model = store.getModel(); if (model != null) { ChartData data = editorController.getData(); model.setChartType(n); model.setChartData(data); initializePreviewChart(model); } }); validationRegistry.registerValidator(name, new NotEmptyValidator()); validationRegistry.registerValidator(name, new NamedEntityMustNotExistValidator<>(UmlDiagramInfo.class, t -> t.getId() == store.<TextInfo>getModel().getId())); saveBtn.disableProperty().bind(validationRegistry.invalidProperty()); editorController.setCallback(previewHelper::recompute); previewContainer.getStyleClass().add("fullScreenBg"); } protected void initializePreviewChart(ChartInfo chartInfo) { previewContainer.getChildren().clear(); if (chartInfo != null) { Chart chart = previewHelper.createNewChart(chartInfo); previewContainer.getChildren().add(chart); } } @FXML protected void onSave() { if (saveBtn.isFocused()) { controller.save(); controller.stopCurrent(); } } @FXML protected void onSaveImage() { FileChooser fileChooser = new FileChooser(); fileChooser.setInitialFileName("chart"); FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("png", "png"); fileChooser.setSelectedExtensionFilter(filter); File file = fileChooser.showOpenDialog(saveBtn.getScene().getWindow()); if (file != null) { Node pane = createFullScreenPopup(Screen.getPrimary()).getContent().get(0); WritableImage image = pane.snapshot(null, null); BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null); // Get buffered bufferedImage. try { ImageIO.write(bufferedImage, "png", file); } catch (IOException e) { log.error("Could not write image {}", file, e); } } } @FXML public void onShowFullScreen() { ObservableList<Screen> screens = Screen.getScreens(); Screen screen; if (screens.size() == 1) { screen = screens.get(0); } else { Optional<Screen> other = screens.stream().filter(s -> !s.equals(Screen.getPrimary())).findFirst(); screen = other.get(); } Popup popup = createFullScreenPopup(screen); popup.show(fullscreen.getScene().getWindow()); } protected Popup createFullScreenPopup(Screen screen) { StackPane pane = getFullScreenPane(screen); Rectangle2D visualBounds = screen.getVisualBounds(); Popup popup = new Popup(); popup.getContent().add(pane); popup.setX(visualBounds.getMinX()); popup.setY(visualBounds.getMinY()); popup.setWidth(visualBounds.getWidth()); popup.setHeight(visualBounds.getHeight()); return popup; } protected StackPane getFullScreenPane(Screen screen) { Rectangle2D visualBounds = screen.getVisualBounds(); ChartInfo model = store.getModel(); model.setChartData(editorController.getData()); model.setChartType(chartType.getValue()); Chart fullScreenChart = fullScreenPreviewHelper.createNewChart(model); StackPane pane = new StackPane(); pane.getStyleClass().add("fullScreenBg"); pane.setPrefWidth(visualBounds.getWidth()); pane.setPrefHeight(visualBounds.getHeight()); pane.getChildren().add(fullScreenChart); return pane; } @FXML void onAddColumn() { Optional<String> input = Dialogs.create().message(Localized.get("column.title")).showTextInput(); if (input.isPresent()) { editorController.addColumnHeader(input.get()); } } @Override protected void onRefresh(ChartInfo model) { ChartData chartData = model.getChartData(); if (chartData != null) { yaxisTitle.setText(chartData.getYAxisTitle()); } else { yaxisTitle.setText(""); } if (model.getChartData() == null) { editorController.reset(); model.setChartData(editorController.getData()); } else { editorController.setData(model.getChartData()); } controller.getJavaFXExecutor().submit(() -> chartType.getSelectionModel().select(model.getChartType())); } @Override public void duringSave(ChartInfo model) { model.setChartType(chartType.getValue()); } }