Search in sources :

Example 1 with SortedList

use of javafx.collections.transformation.SortedList in project Retrospector by NonlinearFruit.

the class SearchTabController method initSearchTab.

private void initSearchTab() {
    searchEditMedia.setDisable(true);
    searchDeleteMedia.setDisable(true);
    // Table Double Click
    searchTable.setRowFactory(tv -> {
        TableRow<Media> row = new TableRow<>();
        row.setOnMouseClicked(event -> {
            if (event.getClickCount() == 2 && (!row.isEmpty())) {
                setMedia(row.getItem());
                setTab(TAB.MEDIA);
            }
        });
        return row;
    });
    // Table data setup
    searchTableData = DataManager.getMedia();
    FilteredList<Media> mediaFiltered = new FilteredList(searchTableData, x -> true);
    SortedList<Media> mediaSortable = new SortedList<>(mediaFiltered);
    searchTable.setItems(mediaSortable);
    mediaSortable.comparatorProperty().bind(searchTable.comparatorProperty());
    // Link to data properties
    searchTitleColumn.setCellValueFactory(new PropertyValueFactory<>("Title"));
    searchCreatorColumn.setCellValueFactory(new PropertyValueFactory<>("Creator"));
    searchSeasonColumn.setCellValueFactory(new PropertyValueFactory<>("SeasonId"));
    searchEpisodeColumn.setCellValueFactory(new PropertyValueFactory<>("EpisodeId"));
    searchCategoryColumn.setCellValueFactory(new PropertyValueFactory<>("Category"));
    // Values for special columns
    searchNumberColumn.setSortable(false);
    searchNumberColumn.setCellValueFactory(p -> new ReadOnlyObjectWrapper(1 + searchTable.getItems().indexOf(p.getValue())));
    searchReviewsColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Media, Integer>, ObservableValue<Integer>>() {

        @Override
        public ObservableValue<Integer> call(TableColumn.CellDataFeatures<Media, Integer> p) {
            return new ReadOnlyObjectWrapper(p.getValue().getReviews().size());
        }
    });
    searchMeanRColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Media, BigDecimal>, ObservableValue<BigDecimal>>() {

        @Override
        public ObservableValue<BigDecimal> call(TableColumn.CellDataFeatures<Media, BigDecimal> p) {
            return new ReadOnlyObjectWrapper(p.getValue().getAverageRating());
        }
    });
    searchCurrentRColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Media, BigDecimal>, ObservableValue<BigDecimal>>() {

        @Override
        public ObservableValue<BigDecimal> call(TableColumn.CellDataFeatures<Media, BigDecimal> p) {
            return new ReadOnlyObjectWrapper(p.getValue().getCurrentRating());
        }
    });
    // Comparators for string columns
    searchTitleColumn.setComparator(new NaturalOrderComparator());
    searchCreatorColumn.setComparator(new NaturalOrderComparator());
    searchSeasonColumn.setComparator(new NaturalOrderComparator());
    searchEpisodeColumn.setComparator(new NaturalOrderComparator());
    searchCategoryColumn.setComparator(new NaturalOrderComparator());
    searchTable.getSelectionModel().selectedItemProperty().addListener((observe, old, neo) -> {
        setMedia(neo);
    });
    searchBox.textProperty().addListener((observa, old, neo) -> {
        String query = neo;
        if (query == null || query.equals(""))
            mediaFiltered.setPredicate(x -> true);
        else {
            String[] queries = query.split(":");
            mediaFiltered.setPredicate(x -> QueryProcessor.isMatchForMedia(query, x));
        }
        updateStats();
    });
    // Buttons
    searchNewMedia.setOnAction(e -> {
        Media neo = new Media();
        neo.setId(DataManager.createDB(neo));
        setMedia(neo);
        setTab(TAB.MEDIA);
    });
    searchQuickEntry.setOnAction(e -> {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("QuickEntry.fxml"));
            Parent root1 = (Parent) fxmlLoader.load();
            QuickEntryController qec = fxmlLoader.getController();
            qec.setup(currentTab);
            Stage stage = new Stage();
            stage.setTitle("Quick Entry");
            stage.setScene(new Scene(root1));
            stage.show();
        } catch (Exception ex) {
        }
    });
    searchStandardEntry.setOnAction(e -> {
        Media neo = new Media();
        neo.setId(DataManager.createDB(neo));
        setMedia(neo);
        setTab(TAB.MEDIA);
    });
    searchBackup.setOnAction(e -> DataManager.makeBackup());
    searchCheatsheet.setOnAction(e -> {
        new Cheatsheet().start(new Stage());
    });
    searchEditMedia.setOnAction(e -> {
        setTab(TAB.MEDIA);
    });
    searchDeleteMedia.setOnAction(e -> {
        if (new Alert(Alert.AlertType.WARNING, "Are you sure you want to delete this?", ButtonType.NO, ButtonType.YES).showAndWait().get().equals(ButtonType.YES)) {
            DataManager.deleteDB(getMedia());
            updateSearchTab();
        }
    });
    // Init stuff
    updateStats();
}
Also used : Button(javafx.scene.control.Button) Scene(javafx.scene.Scene) Arrays(java.util.Arrays) Initializable(javafx.fxml.Initializable) URL(java.net.URL) ButtonType(javafx.scene.control.ButtonType) Factoid(retrospector.model.Factoid) ArrayList(java.util.ArrayList) TableColumn(javafx.scene.control.TableColumn) Media(retrospector.model.Media) Application(javafx.application.Application) BigDecimal(java.math.BigDecimal) Parent(javafx.scene.Parent) ResourceBundle(java.util.ResourceBundle) ReadOnlyObjectWrapper(javafx.beans.property.ReadOnlyObjectWrapper) FXMLLoader(javafx.fxml.FXMLLoader) QuickEntryController(retrospector.fxml.QuickEntryController) NaturalOrderComparator(retrospector.util.NaturalOrderComparator) TableView(javafx.scene.control.TableView) Callback(javafx.util.Callback) SortedList(javafx.collections.transformation.SortedList) Alert(javafx.scene.control.Alert) ObjectProperty(javafx.beans.property.ObjectProperty) TextField(javafx.scene.control.TextField) MenuItem(javafx.scene.control.MenuItem) Review(retrospector.model.Review) PropertyValueFactory(javafx.scene.control.cell.PropertyValueFactory) TableRow(javafx.scene.control.TableRow) FilteredList(javafx.collections.transformation.FilteredList) TAB(retrospector.fxml.CoreController.TAB) FXML(javafx.fxml.FXML) Text(javafx.scene.text.Text) List(java.util.List) Stage(javafx.stage.Stage) MenuButton(javafx.scene.control.MenuButton) ObservableValue(javafx.beans.value.ObservableValue) ObservableList(javafx.collections.ObservableList) DataManager(retrospector.model.DataManager) QuickEntryController(retrospector.fxml.QuickEntryController) Parent(javafx.scene.Parent) SortedList(javafx.collections.transformation.SortedList) ObservableValue(javafx.beans.value.ObservableValue) FXMLLoader(javafx.fxml.FXMLLoader) FilteredList(javafx.collections.transformation.FilteredList) Stage(javafx.stage.Stage) Media(retrospector.model.Media) Scene(javafx.scene.Scene) TableColumn(javafx.scene.control.TableColumn) BigDecimal(java.math.BigDecimal) NaturalOrderComparator(retrospector.util.NaturalOrderComparator) TableRow(javafx.scene.control.TableRow) Alert(javafx.scene.control.Alert) ReadOnlyObjectWrapper(javafx.beans.property.ReadOnlyObjectWrapper)

Example 2 with SortedList

use of javafx.collections.transformation.SortedList in project Retrospector by NonlinearFruit.

the class MediaSectionController method initialize.

/**
     * Initializes the controller class.
     */
@Override
public void initialize(URL url, ResourceBundle rb) {
    chartRatingOverTime.getData().add(new XYChart.Series(FXCollections.observableArrayList(new XYChart.Data(0, 0))));
    checkTitle.setSelected(true);
    checkCreator.setSelected(true);
    checkSeason.setSelected(true);
    checkEpisode.setSelected(true);
    checkCategory.setSelected(true);
    checkTitle.selectedProperty().addListener((observe, old, neo) -> updateMedia());
    checkCreator.selectedProperty().addListener((observe, old, neo) -> updateMedia());
    checkSeason.selectedProperty().addListener((observe, old, neo) -> updateMedia());
    checkEpisode.selectedProperty().addListener((observe, old, neo) -> updateMedia());
    checkCategory.selectedProperty().addListener((observe, old, neo) -> updateMedia());
    mediaTableFilter = new FilteredList(allMedia);
    SortedList<Media> mediaSortable = new SortedList<>(mediaTableFilter);
    mediaTable.setItems(mediaSortable);
    mediaSortable.comparatorProperty().bind(mediaTable.comparatorProperty());
    mediaColumnRowNumber.setSortable(false);
    mediaColumnRowNumber.setCellValueFactory(p -> new ReadOnlyObjectWrapper(1 + mediaTable.getItems().indexOf(p.getValue())));
    mediaColumnTitle.setComparator(new NaturalOrderComparator());
    mediaColumnCreator.setComparator(new NaturalOrderComparator());
    mediaColumnSeason.setComparator(new NaturalOrderComparator());
    mediaColumnEpisode.setComparator(new NaturalOrderComparator());
    mediaColumnCategory.setComparator(new NaturalOrderComparator());
    mediaColumnTitle.setCellValueFactory(new PropertyValueFactory<>("Title"));
    mediaColumnCreator.setCellValueFactory(new PropertyValueFactory<>("Creator"));
    mediaColumnSeason.setCellValueFactory(new PropertyValueFactory<>("SeasonId"));
    mediaColumnEpisode.setCellValueFactory(new PropertyValueFactory<>("EpisodeId"));
    mediaColumnCategory.setCellValueFactory(new PropertyValueFactory<>("Category"));
    chartRotY.setLabel("Reviews");
    chartRotY.setAutoRanging(false);
    chartRotY.setLowerBound(0);
    chartRotY.setUpperBound(10);
    chartRotY.setTickUnit(2);
    chartRotY.setMinorTickCount(2);
    chartRotX.setLabel("Time");
    chartRotX.setAutoRanging(false);
    chartRotX.setTickUnit(1);
    chartRotX.setMinorTickCount(4);
    chartRotX.setTickLabelFormatter(new StringConverter<Number>() {

        @Override
        public String toString(Number number) {
            double x = number.doubleValue();
            double decimal = x % 1;
            double year = x - decimal;
            double days = decimal * 365.25;
            if (days > 365 || days < 1) {
                return ((int) year) + "";
            }
            LocalDate date = LocalDate.ofYearDay((int) year, (int) days);
            return date.format(DateTimeFormatter.ofPattern("MMM uuuu"));
        }

        @Override
        public Number fromString(String string) {
            //To change body of generated methods, choose Tools | Templates.
            throw new UnsupportedOperationException("Not supported yet.");
        }
    });
}
Also used : SortedList(javafx.collections.transformation.SortedList) Media(retrospector.model.Media) LocalDate(java.time.LocalDate) FilteredList(javafx.collections.transformation.FilteredList) NaturalOrderComparator(retrospector.util.NaturalOrderComparator) XYChart(javafx.scene.chart.XYChart) ReadOnlyObjectWrapper(javafx.beans.property.ReadOnlyObjectWrapper)

Example 3 with SortedList

use of javafx.collections.transformation.SortedList in project jgnash by ccavanaugh.

the class RegisterTableController method initialize.

@FXML
void initialize() {
    // table view displays the sorted list of data.  The comparator property must be bound
    tableView.setItems(sortedList);
    sortedList.comparatorProperty().bind(tableView.comparatorProperty());
    // Bind the account property
    getAccountPropertyWrapper().accountProperty().bind(account);
    accountNameLabel.textProperty().bind(getAccountPropertyWrapper().accountNameProperty());
    balanceLabel.textProperty().bind(getAccountPropertyWrapper().accountBalanceProperty());
    tableView.setTableMenuButtonVisible(true);
    tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    // hide the horizontal scrollbar and prevent ghosting
    tableView.getStylesheets().addAll(StyleClass.HIDE_HORIZONTAL_CSS);
    // Load the table on change and set the row factory if the account in not locked
    accountProperty().addListener((observable, oldValue, newValue) -> {
        loadAccount();
        if (!newValue.isLocked()) {
            tableView.setRowFactory(new TransactionRowFactory());
        }
        numberFormat = CommodityFormat.getFullNumberFormat(newValue.getCurrencyNode());
    });
    selectedTransaction.bind(tableView.getSelectionModel().selectedItemProperty());
    // Update the selection size property when the selection list changes
    tableView.getSelectionModel().getSelectedItems().addListener((ListChangeListener<Transaction>) c -> selectionSize.set(tableView.getSelectionModel().getSelectedIndices().size()));
    selectionSize.addListener((observable, oldValue, newValue) -> {
        if ((Integer) newValue > 1) {
            final List<Transaction> transactions = new ArrayList<>(tableView.getSelectionModel().getSelectedItems());
            BigDecimal total = BigDecimal.ZERO;
            for (final Transaction transaction : transactions) {
                if (transaction != null) {
                    total = total.add(transaction.getAmount(account.get()));
                }
            }
            selectionSummaryTooltip.setText(numberFormat.format(AccountBalanceDisplayManager.convertToSelectedBalanceMode(account.get().getAccountType(), total)));
        } else {
            selectionSummaryTooltip.setText(null);
        }
    });
    // For the table view to refresh itself if the mode changes
    AccountBalanceDisplayManager.accountBalanceDisplayMode().addListener((observable, oldValue, newValue) -> tableView.refresh());
    reconciledStateFilterComboBox.getItems().addAll(ReconciledStateEnum.values());
    reconciledStateFilterComboBox.setValue(ReconciledStateEnum.ALL);
    transactionAgeFilterComboBox.getItems().addAll(AgeEnum.values());
    transactionAgeFilterComboBox.setValue(AgeEnum.ALL);
    final ChangeListener<Object> filterChangeListener = (observable, oldValue, newValue) -> handleFilterChange();
    reconciledStateFilterComboBox.valueProperty().addListener(filterChangeListener);
    transactionAgeFilterComboBox.valueProperty().addListener(filterChangeListener);
    // Rebuild filters when regex properties change
    Options.regexForFiltersProperty().addListener(filterChangeListener);
    if (memoFilterTextField != null) {
        // memo filter may not have been initialized for all register types
        memoFilterTextField.textProperty().addListener(filterChangeListener);
    }
    if (payeeFilterTextField != null) {
        // payee filter may not have been initialized for all register types
        payeeFilterTextField.textProperty().addListener(filterChangeListener);
    }
    // Repack the table if the font scale changes
    ThemeManager.fontScaleProperty().addListener((observable, oldValue, newValue) -> tableViewManager.packTable());
    // Listen for transaction events
    MessageBus.getInstance().registerListener(messageBusHandler, MessageChannel.TRANSACTION);
}
Also used : Engine(jgnash.engine.Engine) TransactionAgePredicate(jgnash.util.function.TransactionAgePredicate) TableViewManager(jgnash.uifx.util.TableViewManager) MessageBus(jgnash.engine.message.MessageBus) BigDecimal(java.math.BigDecimal) MessageProperty(jgnash.engine.message.MessageProperty) ReadOnlyObjectWrapper(javafx.beans.property.ReadOnlyObjectWrapper) ListChangeListener(javafx.collections.ListChangeListener) ComboBox(javafx.scene.control.ComboBox) MessageChannel(jgnash.engine.message.MessageChannel) ContextMenu(javafx.scene.control.ContextMenu) SimpleIntegerProperty(javafx.beans.property.SimpleIntegerProperty) TableView(javafx.scene.control.TableView) MemoPredicate(jgnash.util.function.MemoPredicate) MessageListener(jgnash.engine.message.MessageListener) SortedList(javafx.collections.transformation.SortedList) TextField(javafx.scene.control.TextField) MenuItem(javafx.scene.control.MenuItem) Predicate(java.util.function.Predicate) RecurringEntryDialog(jgnash.uifx.views.recurring.RecurringEntryDialog) FilteredList(javafx.collections.transformation.FilteredList) Set(java.util.Set) JavaFXUtils(jgnash.uifx.util.JavaFXUtils) TransactionType(jgnash.engine.TransactionType) Objects(java.util.Objects) Platform(javafx.application.Platform) FXML(javafx.fxml.FXML) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) List(java.util.List) ReconciledPredicate(jgnash.util.function.ReconciledPredicate) Optional(java.util.Optional) ObservableList(javafx.collections.ObservableList) Message(jgnash.engine.message.Message) ReadOnlyObjectProperty(javafx.beans.property.ReadOnlyObjectProperty) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) Transaction(jgnash.engine.Transaction) EngineFactory(jgnash.engine.EngineFactory) ResourceUtils(jgnash.util.ResourceUtils) FXCollections(javafx.collections.FXCollections) Bindings(javafx.beans.binding.Bindings) IntegerProperty(javafx.beans.property.IntegerProperty) NumberFormat(java.text.NumberFormat) ArrayList(java.util.ArrayList) ResourceBundle(java.util.ResourceBundle) AccountBalanceDisplayManager(jgnash.uifx.views.AccountBalanceDisplayManager) InvestmentTransaction(jgnash.engine.InvestmentTransaction) Callback(javafx.util.Callback) ThemeManager(jgnash.uifx.skin.ThemeManager) Tooltip(javafx.scene.control.Tooltip) ReconciledState(jgnash.engine.ReconciledState) ObjectProperty(javafx.beans.property.ObjectProperty) Label(javafx.scene.control.Label) TableRow(javafx.scene.control.TableRow) Reminder(jgnash.engine.recurring.Reminder) Menu(javafx.scene.control.Menu) TimeUnit(java.util.concurrent.TimeUnit) CommodityFormat(jgnash.text.CommodityFormat) ChronoUnit(java.time.temporal.ChronoUnit) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) StyleClass(jgnash.uifx.skin.StyleClass) Account(jgnash.engine.Account) PayeePredicate(jgnash.util.function.PayeePredicate) ChangeListener(javafx.beans.value.ChangeListener) Collections(java.util.Collections) Options(jgnash.uifx.Options) Transaction(jgnash.engine.Transaction) InvestmentTransaction(jgnash.engine.InvestmentTransaction) ArrayList(java.util.ArrayList) BigDecimal(java.math.BigDecimal) FXML(javafx.fxml.FXML)

Example 4 with SortedList

use of javafx.collections.transformation.SortedList in project POL-POM-5 by PlayOnLinux.

the class LibraryFeaturePanelSkin method createCombinedListWidget.

private CombinedListWidget<ShortcutDTO> createCombinedListWidget() {
    final FilteredList<ShortcutDTO> filteredShortcuts = ConcatenatedList.create(new MappedList<>(getControl().getCategories().sorted(Comparator.comparing(ShortcutCategoryDTO::getName)), ShortcutCategoryDTO::getShortcuts)).filtered(getControl().getFilter()::filter);
    filteredShortcuts.predicateProperty().bind(Bindings.createObjectBinding(() -> getControl().getFilter()::filter, getControl().getFilter().searchTermProperty(), getControl().getFilter().selectedShortcutCategoryProperty()));
    final SortedList<ShortcutDTO> sortedShortcuts = filteredShortcuts.sorted(Comparator.comparing(shortcut -> shortcut.getInfo().getName()));
    final ObservableList<ListWidgetElement<ShortcutDTO>> listWidgetEntries = new MappedList<>(sortedShortcuts, ListWidgetElement::create);
    final CombinedListWidget<ShortcutDTO> combinedListWidget = new CombinedListWidget<>(listWidgetEntries, this.selectedListWidget);
    // bind direction: controller property -> skin property
    getControl().selectedShortcutProperty().addListener((observable, oldValue, newValue) -> {
        if (newValue != null) {
            combinedListWidget.select(newValue);
        } else {
            combinedListWidget.deselect();
        }
    });
    // bind direction: skin property -> controller properties
    combinedListWidget.selectedElementProperty().addListener((observable, oldValue, newValue) -> {
        if (newValue != null) {
            final ShortcutDTO selectedItem = newValue.getItem();
            final MouseEvent event = newValue.getEvent();
            getControl().setSelectedShortcut(selectedItem);
            getControl().setOpenedDetailsPanel(new ShortcutInformation(selectedItem));
            if (event.getClickCount() == 2) {
                getControl().runShortcut(selectedItem);
            }
        } else {
            getControl().setSelectedShortcut(null);
            getControl().setOpenedDetailsPanel(new None());
        }
    });
    return combinedListWidget;
}
Also used : CombinedListWidget(org.phoenicis.javafx.components.common.widgets.control.CombinedListWidget) ShortcutCategoryDTO(org.phoenicis.library.dto.ShortcutCategoryDTO) StringBindings(org.phoenicis.javafx.utils.StringBindings) ObjectExpression(javafx.beans.binding.ObjectExpression) MappedList(org.phoenicis.javafx.collections.MappedList) MouseEvent(javafx.scene.input.MouseEvent) ShortcutEditing(org.phoenicis.javafx.components.library.panelstates.ShortcutEditing) Bindings(javafx.beans.binding.Bindings) SidebarBase(org.phoenicis.javafx.components.common.control.SidebarBase) org.phoenicis.javafx.components.library.control(org.phoenicis.javafx.components.library.control) ListWidgetElement(org.phoenicis.javafx.components.common.widgets.utils.ListWidgetElement) ShortcutInformation(org.phoenicis.javafx.components.library.panelstates.ShortcutInformation) ShortcutCreation(org.phoenicis.javafx.components.library.panelstates.ShortcutCreation) TabPane(javafx.scene.control.TabPane) None(org.phoenicis.javafx.components.common.panelstates.None) FeaturePanelSkin(org.phoenicis.javafx.components.common.skin.FeaturePanelSkin) ShortcutDTO(org.phoenicis.library.dto.ShortcutDTO) SwitchBinding(org.phoenicis.javafx.utils.SwitchBinding) SortedList(javafx.collections.transformation.SortedList) ListWidgetType(org.phoenicis.javafx.components.common.widgets.utils.ListWidgetType) ObjectProperty(javafx.beans.property.ObjectProperty) Node(javafx.scene.Node) FilteredList(javafx.collections.transformation.FilteredList) Localisation.tr(org.phoenicis.configuration.localisation.Localisation.tr) Observable(javafx.beans.Observable) JavaFxSettingsManager(org.phoenicis.javafx.settings.JavaFxSettingsManager) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) Tab(javafx.scene.control.Tab) OpenDetailsPanel(org.phoenicis.javafx.components.common.panelstates.OpenDetailsPanel) DetailsPanel(org.phoenicis.javafx.components.common.control.DetailsPanel) Optional(java.util.Optional) ObjectBindings(org.phoenicis.javafx.utils.ObjectBindings) ObservableList(javafx.collections.ObservableList) ConcatenatedList(org.phoenicis.javafx.collections.ConcatenatedList) Comparator(java.util.Comparator) CombinedListWidget(org.phoenicis.javafx.components.common.widgets.control.CombinedListWidget) MouseEvent(javafx.scene.input.MouseEvent) ListWidgetElement(org.phoenicis.javafx.components.common.widgets.utils.ListWidgetElement) ShortcutInformation(org.phoenicis.javafx.components.library.panelstates.ShortcutInformation) ShortcutDTO(org.phoenicis.library.dto.ShortcutDTO) MappedList(org.phoenicis.javafx.collections.MappedList) ShortcutCategoryDTO(org.phoenicis.library.dto.ShortcutCategoryDTO) None(org.phoenicis.javafx.components.common.panelstates.None)

Example 5 with SortedList

use of javafx.collections.transformation.SortedList in project bitsquare by bitsquare.

the class TraderDisputeView method onSelectDispute.

private void onSelectDispute(Dispute dispute) {
    removeListenersOnSelectDispute();
    if (dispute == null) {
        if (root.getChildren().size() > 2)
            root.getChildren().remove(2);
        selectedDispute = null;
    } else if (selectedDispute != dispute) {
        this.selectedDispute = dispute;
        boolean isTrader = disputeManager.isTrader(selectedDispute);
        tableGroupHeadline = new TableGroupHeadline();
        tableGroupHeadline.setText("Messages");
        AnchorPane.setTopAnchor(tableGroupHeadline, 10d);
        AnchorPane.setRightAnchor(tableGroupHeadline, 0d);
        AnchorPane.setBottomAnchor(tableGroupHeadline, 0d);
        AnchorPane.setLeftAnchor(tableGroupHeadline, 0d);
        disputeCommunicationMessages = selectedDispute.getDisputeCommunicationMessagesAsObservableList();
        SortedList<DisputeCommunicationMessage> sortedList = new SortedList<>(disputeCommunicationMessages);
        sortedList.setComparator((o1, o2) -> o1.getDate().compareTo(o2.getDate()));
        messageListView = new ListView<>(sortedList);
        messageListView.setId("message-list-view");
        messageListView.setMinHeight(150);
        AnchorPane.setTopAnchor(messageListView, 30d);
        AnchorPane.setRightAnchor(messageListView, 0d);
        AnchorPane.setLeftAnchor(messageListView, 0d);
        messagesAnchorPane = new AnchorPane();
        VBox.setVgrow(messagesAnchorPane, Priority.ALWAYS);
        inputTextArea = new TextArea();
        inputTextArea.setPrefHeight(70);
        inputTextArea.setWrapText(true);
        sendButton = new Button("Send");
        sendButton.setDefaultButton(true);
        sendButton.setOnAction(e -> {
            if (p2PService.isBootstrapped()) {
                String text = inputTextArea.getText();
                if (!text.isEmpty())
                    onSendMessage(text, selectedDispute);
            } else {
                new Popup().information("You need to wait until you are fully connected to the network.\n" + "That might take up to about 2 minutes at startup.").show();
            }
        });
        inputTextAreaTextSubscription = EasyBind.subscribe(inputTextArea.textProperty(), t -> sendButton.setDisable(t.isEmpty()));
        Button uploadButton = new Button("Add attachments");
        uploadButton.setOnAction(e -> onRequestUpload());
        sendMsgInfoLabel = new Label();
        sendMsgInfoLabel.setVisible(false);
        sendMsgInfoLabel.setManaged(false);
        sendMsgInfoLabel.setPadding(new Insets(5, 0, 0, 0));
        sendMsgBusyAnimation = new BusyAnimation(false);
        if (!selectedDispute.isClosed()) {
            HBox buttonBox = new HBox();
            buttonBox.setSpacing(10);
            buttonBox.getChildren().addAll(sendButton, uploadButton, sendMsgBusyAnimation, sendMsgInfoLabel);
            if (!isTrader) {
                Button closeDisputeButton = new Button("Close ticket");
                closeDisputeButton.setOnAction(e -> onCloseDispute(selectedDispute));
                closeDisputeButton.setDefaultButton(true);
                Pane spacer = new Pane();
                HBox.setHgrow(spacer, Priority.ALWAYS);
                buttonBox.getChildren().addAll(spacer, closeDisputeButton);
            }
            messagesInputBox = new VBox();
            messagesInputBox.setSpacing(10);
            messagesInputBox.getChildren().addAll(inputTextArea, buttonBox);
            VBox.setVgrow(buttonBox, Priority.ALWAYS);
            AnchorPane.setRightAnchor(messagesInputBox, 0d);
            AnchorPane.setBottomAnchor(messagesInputBox, 5d);
            AnchorPane.setLeftAnchor(messagesInputBox, 0d);
            AnchorPane.setBottomAnchor(messageListView, 120d);
            messagesAnchorPane.getChildren().addAll(tableGroupHeadline, messageListView, messagesInputBox);
        } else {
            AnchorPane.setBottomAnchor(messageListView, 0d);
            messagesAnchorPane.getChildren().addAll(tableGroupHeadline, messageListView);
        }
        messageListView.setCellFactory(new Callback<ListView<DisputeCommunicationMessage>, ListCell<DisputeCommunicationMessage>>() {

            @Override
            public ListCell<DisputeCommunicationMessage> call(ListView<DisputeCommunicationMessage> list) {
                return new ListCell<DisputeCommunicationMessage>() {

                    public ChangeListener<Boolean> sendMsgBusyAnimationListener;

                    final Pane bg = new Pane();

                    final ImageView arrow = new ImageView();

                    final Label headerLabel = new Label();

                    final Label messageLabel = new Label();

                    final Label copyIcon = new Label();

                    final HBox attachmentsBox = new HBox();

                    final AnchorPane messageAnchorPane = new AnchorPane();

                    final Label statusIcon = new Label();

                    final double arrowWidth = 15d;

                    final double attachmentsBoxHeight = 20d;

                    final double border = 10d;

                    final double bottomBorder = 25d;

                    final double padding = border + 10d;

                    final double msgLabelPaddingRight = padding + 20d;

                    {
                        bg.setMinHeight(30);
                        messageLabel.setWrapText(true);
                        headerLabel.setTextAlignment(TextAlignment.CENTER);
                        attachmentsBox.setSpacing(5);
                        statusIcon.setStyle("-fx-font-size: 10;");
                        Tooltip.install(copyIcon, new Tooltip("Copy to clipboard"));
                        messageAnchorPane.getChildren().addAll(bg, arrow, headerLabel, messageLabel, copyIcon, attachmentsBox, statusIcon);
                    }

                    @Override
                    public void updateItem(final DisputeCommunicationMessage item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null && !empty) {
                            copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(messageLabel.getText()));
                            /* messageAnchorPane.prefWidthProperty().bind(EasyBind.map(messageListView.widthProperty(),
                                        w -> (double) w - padding - GUIUtil.getScrollbarWidth(messageListView)));*/
                            if (!messageAnchorPane.prefWidthProperty().isBound())
                                messageAnchorPane.prefWidthProperty().bind(messageListView.widthProperty().subtract(padding + GUIUtil.getScrollbarWidth(messageListView)));
                            AnchorPane.setTopAnchor(bg, 15d);
                            AnchorPane.setBottomAnchor(bg, bottomBorder);
                            AnchorPane.setTopAnchor(headerLabel, 0d);
                            AnchorPane.setBottomAnchor(arrow, bottomBorder + 5d);
                            AnchorPane.setTopAnchor(messageLabel, 25d);
                            AnchorPane.setTopAnchor(copyIcon, 25d);
                            AnchorPane.setBottomAnchor(attachmentsBox, bottomBorder + 10);
                            boolean senderIsTrader = item.isSenderIsTrader();
                            boolean isMyMsg = isTrader ? senderIsTrader : !senderIsTrader;
                            arrow.setVisible(!item.isSystemMessage());
                            arrow.setManaged(!item.isSystemMessage());
                            statusIcon.setVisible(false);
                            if (item.isSystemMessage()) {
                                headerLabel.setStyle("-fx-text-fill: -bs-green; -fx-font-size: 11;");
                                bg.setId("message-bubble-green");
                                messageLabel.setStyle("-fx-text-fill: white;");
                                copyIcon.setStyle("-fx-text-fill: white;");
                            } else if (isMyMsg) {
                                headerLabel.setStyle("-fx-text-fill: -fx-accent; -fx-font-size: 11;");
                                bg.setId("message-bubble-blue");
                                messageLabel.setStyle("-fx-text-fill: white;");
                                copyIcon.setStyle("-fx-text-fill: white;");
                                if (isTrader)
                                    arrow.setId("bubble_arrow_blue_left");
                                else
                                    arrow.setId("bubble_arrow_blue_right");
                                if (sendMsgBusyAnimationListener != null)
                                    sendMsgBusyAnimation.isRunningProperty().removeListener(sendMsgBusyAnimationListener);
                                sendMsgBusyAnimationListener = (observable, oldValue, newValue) -> {
                                    if (!newValue) {
                                        if (item.arrivedProperty().get())
                                            showArrivedIcon();
                                        else if (item.storedInMailboxProperty().get())
                                            showMailboxIcon();
                                    }
                                };
                                sendMsgBusyAnimation.isRunningProperty().addListener(sendMsgBusyAnimationListener);
                                if (item.arrivedProperty().get())
                                    showArrivedIcon();
                                else if (item.storedInMailboxProperty().get())
                                    showMailboxIcon();
                            //TODO show that icon on error
                            /*else if (sendMsgProgressIndicator.getProgress() == 0)
                                        showNotArrivedIcon();*/
                            } else {
                                headerLabel.setStyle("-fx-text-fill: -bs-light-grey; -fx-font-size: 11;");
                                bg.setId("message-bubble-grey");
                                messageLabel.setStyle("-fx-text-fill: black;");
                                copyIcon.setStyle("-fx-text-fill: black;");
                                if (isTrader)
                                    arrow.setId("bubble_arrow_grey_right");
                                else
                                    arrow.setId("bubble_arrow_grey_left");
                            }
                            if (item.isSystemMessage()) {
                                AnchorPane.setLeftAnchor(headerLabel, padding);
                                AnchorPane.setRightAnchor(headerLabel, padding);
                                AnchorPane.setLeftAnchor(bg, border);
                                AnchorPane.setRightAnchor(bg, border);
                                AnchorPane.setLeftAnchor(messageLabel, padding);
                                AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight);
                                AnchorPane.setRightAnchor(copyIcon, padding);
                                AnchorPane.setLeftAnchor(attachmentsBox, padding);
                                AnchorPane.setRightAnchor(attachmentsBox, padding);
                            } else if (senderIsTrader) {
                                AnchorPane.setLeftAnchor(headerLabel, padding + arrowWidth);
                                AnchorPane.setLeftAnchor(bg, border + arrowWidth);
                                AnchorPane.setRightAnchor(bg, border);
                                AnchorPane.setLeftAnchor(arrow, border);
                                AnchorPane.setLeftAnchor(messageLabel, padding + arrowWidth);
                                AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight);
                                AnchorPane.setRightAnchor(copyIcon, padding);
                                AnchorPane.setLeftAnchor(attachmentsBox, padding + arrowWidth);
                                AnchorPane.setRightAnchor(attachmentsBox, padding);
                                AnchorPane.setRightAnchor(statusIcon, padding);
                            } else {
                                AnchorPane.setRightAnchor(headerLabel, padding + arrowWidth);
                                AnchorPane.setLeftAnchor(bg, border);
                                AnchorPane.setRightAnchor(bg, border + arrowWidth);
                                AnchorPane.setRightAnchor(arrow, border);
                                AnchorPane.setLeftAnchor(messageLabel, padding);
                                AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight + arrowWidth);
                                AnchorPane.setRightAnchor(copyIcon, padding + arrowWidth);
                                AnchorPane.setLeftAnchor(attachmentsBox, padding);
                                AnchorPane.setRightAnchor(attachmentsBox, padding + arrowWidth);
                                AnchorPane.setLeftAnchor(statusIcon, padding);
                            }
                            AnchorPane.setBottomAnchor(statusIcon, 7d);
                            headerLabel.setText(formatter.formatDateTime(item.getDate()));
                            messageLabel.setText(item.getMessage());
                            attachmentsBox.getChildren().clear();
                            if (item.getAttachments().size() > 0) {
                                AnchorPane.setBottomAnchor(messageLabel, bottomBorder + attachmentsBoxHeight + 10);
                                attachmentsBox.getChildren().add(new Label("Attachments: ") {

                                    {
                                        setPadding(new Insets(0, 0, 3, 0));
                                        if (isMyMsg)
                                            setStyle("-fx-text-fill: white;");
                                        else
                                            setStyle("-fx-text-fill: black;");
                                    }
                                });
                                item.getAttachments().stream().forEach(attachment -> {
                                    final Label icon = new Label();
                                    setPadding(new Insets(0, 0, 3, 0));
                                    if (isMyMsg)
                                        icon.getStyleClass().add("attachment-icon");
                                    else
                                        icon.getStyleClass().add("attachment-icon-black");
                                    AwesomeDude.setIcon(icon, AwesomeIcon.FILE_TEXT);
                                    icon.setPadding(new Insets(-2, 0, 0, 0));
                                    icon.setTooltip(new Tooltip(attachment.getFileName()));
                                    icon.setOnMouseClicked(event -> onOpenAttachment(attachment));
                                    attachmentsBox.getChildren().add(icon);
                                });
                            } else {
                                AnchorPane.setBottomAnchor(messageLabel, bottomBorder + 10);
                            }
                            // Need to set it here otherwise style is not correct
                            AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY, "16.0");
                            copyIcon.getStyleClass().add("copy-icon-disputes");
                            // TODO There are still some cell rendering issues on updates
                            setGraphic(messageAnchorPane);
                        } else {
                            if (sendMsgBusyAnimation != null && sendMsgBusyAnimationListener != null)
                                sendMsgBusyAnimation.isRunningProperty().removeListener(sendMsgBusyAnimationListener);
                            messageAnchorPane.prefWidthProperty().unbind();
                            AnchorPane.clearConstraints(bg);
                            AnchorPane.clearConstraints(headerLabel);
                            AnchorPane.clearConstraints(arrow);
                            AnchorPane.clearConstraints(messageLabel);
                            AnchorPane.clearConstraints(copyIcon);
                            AnchorPane.clearConstraints(statusIcon);
                            AnchorPane.clearConstraints(attachmentsBox);
                            copyIcon.setOnMouseClicked(null);
                            setGraphic(null);
                        }
                    }

                    /*  private void showNotArrivedIcon() {
                            statusIcon.setVisible(true);
                            AwesomeDude.setIcon(statusIcon, AwesomeIcon.WARNING_SIGN, "14");
                            Tooltip.install(statusIcon, new Tooltip("Message did not arrive. Please try to send again."));
                            statusIcon.setTextFill(Paint.valueOf("#dd0000"));
                        }*/
                    private void showMailboxIcon() {
                        statusIcon.setVisible(true);
                        AwesomeDude.setIcon(statusIcon, AwesomeIcon.ENVELOPE_ALT, "14");
                        Tooltip.install(statusIcon, new Tooltip("Message saved in receiver's mailbox"));
                        statusIcon.setTextFill(Paint.valueOf("#0f87c3"));
                    }

                    private void showArrivedIcon() {
                        statusIcon.setVisible(true);
                        AwesomeDude.setIcon(statusIcon, AwesomeIcon.OK, "14");
                        Tooltip.install(statusIcon, new Tooltip("Message arrived at receiver"));
                        statusIcon.setTextFill(Paint.valueOf("#0f87c3"));
                    }
                };
            }
        });
        if (root.getChildren().size() > 2)
            root.getChildren().remove(2);
        root.getChildren().add(2, messagesAnchorPane);
        scrollToBottom();
    }
    addListenersOnSelectDispute();
}
Also used : EventHandler(javafx.event.EventHandler) PubKeyRing(io.bitsquare.common.crypto.PubKeyRing) Popup(io.bitsquare.gui.main.overlays.popups.Popup) javafx.scene.layout(javafx.scene.layout) javafx.scene.control(javafx.scene.control) URL(java.net.URL) ReadOnlyBooleanProperty(javafx.beans.property.ReadOnlyBooleanProperty) DisputeManager(io.bitsquare.arbitration.DisputeManager) Trade(io.bitsquare.trade.Trade) ActivatableView(io.bitsquare.gui.common.view.ActivatableView) DisputeCommunicationMessage(io.bitsquare.arbitration.messages.DisputeCommunicationMessage) GUIUtil(io.bitsquare.gui.util.GUIUtil) KeyCombination(javafx.scene.input.KeyCombination) ReadOnlyObjectWrapper(javafx.beans.property.ReadOnlyObjectWrapper) ListChangeListener(javafx.collections.ListChangeListener) KeyRing(io.bitsquare.common.crypto.KeyRing) DisputeSummaryWindow(io.bitsquare.gui.main.overlays.windows.DisputeSummaryWindow) ParseException(java.text.ParseException) DateFormat(java.text.DateFormat) SortedList(javafx.collections.transformation.SortedList) TableGroupHeadline(io.bitsquare.gui.components.TableGroupHeadline) Contract(io.bitsquare.trade.Contract) FilteredList(javafx.collections.transformation.FilteredList) KeyEvent(javafx.scene.input.KeyEvent) Subscription(org.fxmisc.easybind.Subscription) PrivateNotificationManager(io.bitsquare.alert.PrivateNotificationManager) Attachment(io.bitsquare.arbitration.payload.Attachment) Paint(javafx.scene.paint.Paint) ByteStreams(com.google.common.io.ByteStreams) Dispute(io.bitsquare.arbitration.Dispute) ObservableList(javafx.collections.ObservableList) AwesomeIcon(de.jensd.fx.fontawesome.AwesomeIcon) Version(io.bitsquare.app.Version) Scene(javafx.scene.Scene) java.util(java.util) P2PService(io.bitsquare.p2p.P2PService) SimpleDateFormat(java.text.SimpleDateFormat) Connection(io.bitsquare.p2p.network.Connection) Timer(io.bitsquare.common.Timer) Inject(javax.inject.Inject) TradeManager(io.bitsquare.trade.TradeManager) Lists(com.google.common.collect.Lists) Insets(javafx.geometry.Insets) TradeDetailsWindow(io.bitsquare.gui.main.overlays.windows.TradeDetailsWindow) TextAlignment(javafx.scene.text.TextAlignment) Callback(javafx.util.Callback) Nullable(javax.annotation.Nullable) BSFormatter(io.bitsquare.gui.util.BSFormatter) KeyCode(javafx.scene.input.KeyCode) InputTextField(io.bitsquare.gui.components.InputTextField) Utilities(io.bitsquare.common.util.Utilities) ContractWindow(io.bitsquare.gui.main.overlays.windows.ContractWindow) MalformedURLException(java.net.MalformedURLException) UserThread(io.bitsquare.common.UserThread) AwesomeDude(de.jensd.fx.fontawesome.AwesomeDude) NodeAddress(io.bitsquare.p2p.NodeAddress) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) File(java.io.File) KeyCodeCombination(javafx.scene.input.KeyCodeCombination) TimeUnit(java.util.concurrent.TimeUnit) FileChooser(javafx.stage.FileChooser) HyperlinkWithIcon(io.bitsquare.gui.components.HyperlinkWithIcon) Stage(javafx.stage.Stage) EasyBind(org.fxmisc.easybind.EasyBind) ImageView(javafx.scene.image.ImageView) BusyAnimation(io.bitsquare.gui.components.BusyAnimation) SendPrivateNotificationWindow(io.bitsquare.gui.main.overlays.windows.SendPrivateNotificationWindow) FxmlView(io.bitsquare.gui.common.view.FxmlView) ChangeListener(javafx.beans.value.ChangeListener) InputStream(java.io.InputStream) TableGroupHeadline(io.bitsquare.gui.components.TableGroupHeadline) Insets(javafx.geometry.Insets) BusyAnimation(io.bitsquare.gui.components.BusyAnimation) SortedList(javafx.collections.transformation.SortedList) Callback(javafx.util.Callback) Popup(io.bitsquare.gui.main.overlays.popups.Popup) ListChangeListener(javafx.collections.ListChangeListener) ChangeListener(javafx.beans.value.ChangeListener) ImageView(javafx.scene.image.ImageView) DisputeCommunicationMessage(io.bitsquare.arbitration.messages.DisputeCommunicationMessage)

Aggregations

SortedList (javafx.collections.transformation.SortedList)12 FilteredList (javafx.collections.transformation.FilteredList)10 ObservableList (javafx.collections.ObservableList)8 ReadOnlyObjectWrapper (javafx.beans.property.ReadOnlyObjectWrapper)7 Callback (javafx.util.Callback)6 TimeUnit (java.util.concurrent.TimeUnit)5 URL (java.net.URL)4 DateFormat (java.text.DateFormat)4 ParseException (java.text.ParseException)4 SimpleDateFormat (java.text.SimpleDateFormat)4 Date (java.util.Date)4 ChangeListener (javafx.beans.value.ChangeListener)4 ListChangeListener (javafx.collections.ListChangeListener)4 Insets (javafx.geometry.Insets)4 Inject (javax.inject.Inject)4 EasyBind (org.fxmisc.easybind.EasyBind)4 Subscription (org.fxmisc.easybind.Subscription)4 ObjectProperty (javafx.beans.property.ObjectProperty)3 SimpleStringProperty (javafx.beans.property.SimpleStringProperty)3 FXCollections (javafx.collections.FXCollections)3