package com.codingotaku.apps.callback; import java.awt.Desktop; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import com.codingotaku.apps.download.DownloadInfo; import com.codingotaku.apps.download.DownloadManager; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.control.TableRow; import javafx.scene.control.TableView; import javafx.scene.input.MouseEvent; import javafx.util.Callback; public class TableSelectListener implements Callback<TableView<DownloadInfo>, TableRow<DownloadInfo>> { private static Logger logger = Logger.getLogger(TableSelectListener.class.getName()); private static DownloadManager manager = DownloadManager.getInstance(); // For selected row private final MenuItem pause; private final MenuItem resume; private final MenuItem cancel; private final MenuItem retry; private final MenuItem restart; private final MenuItem delete; private final MenuItem open; final ContextMenu rowMenu = new ContextMenu(); public TableSelectListener() { pause = new MenuItem("pause"); resume = new MenuItem("Resume"); cancel = new MenuItem("Cancel"); retry = new MenuItem("Retry"); restart = new MenuItem("Restart"); delete = new MenuItem("Delete"); open = new MenuItem("Open Folder"); rowMenu.getItems().addAll(pause, resume, cancel, retry, restart, delete, open); } private void pause(DownloadInfo info) { Platform.runLater(() -> manager.pause(info)); } private void resume(DownloadInfo info) { Platform.runLater(() -> manager.resume(info)); } private void cancel(DownloadInfo info) { Platform.runLater(() -> manager.cancel(info)); } private void retry(DownloadInfo info) { Platform.runLater(() -> manager.retry(info)); } private void restart(DownloadInfo info) { Platform.runLater(() -> manager.restart(info)); } private void delete(TableView<DownloadInfo> view, DownloadInfo info) { Platform.runLater(() -> { view.getItems().remove(info); manager.cancel(info); manager.remove(info); view.refresh(); }); } private void open(DownloadInfo info) { if (Desktop.isDesktopSupported()) { new Thread(() -> { try { Desktop desktop = Desktop.getDesktop(); desktop.open(new File(info.getFileName()).getParentFile()); } catch (IOException e) { logger.log(Level.SEVERE, e.getMessage()); } }).start(); } } private void initListeners(TableView<DownloadInfo> view, DownloadInfo info) { // Add for selected row (add nothing if the row is empty) if (info != null) { pause.setOnAction(e -> pause(info)); resume.setOnAction(e -> resume(info)); cancel.setOnAction(e -> cancel(info)); retry.setOnAction(e -> retry(info)); restart.setOnAction(e -> restart(info)); delete.setOnAction(e -> delete(view, info)); open.setOnAction(e -> open(info)); } // For all rows } @Override public TableRow<DownloadInfo> call(TableView<DownloadInfo> view) { final TableRow<DownloadInfo> row = new TableRow<>(); DownloadInfo info = view.getSelectionModel().getSelectedItem(); initListeners(view, info); row.contextMenuProperty().bind( Bindings.when(Bindings.isNotNull(row.itemProperty())).then(rowMenu).otherwise((ContextMenu) null)); row.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> { final int index = row.getIndex(); if (!event.isPrimaryButtonDown()) return; // no action if it is not primary button if (index >= view.getItems().size() || view.getSelectionModel().isSelected(index)) { view.getSelectionModel().clearSelection(); event.consume(); } }); return row; } }