/* * */ package application.tools; import java.awt.Desktop; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.FileTime; import java.util.LinkedList; import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; import org.controlsfx.control.Notifications; import application.Main; import javafx.application.Platform; import javafx.geometry.Bounds; import javafx.scene.Node; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.layout.Region; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.util.Duration; /** * A class which has a lot of useful methods. * * @author GOXR3PLUS */ public final class ActionTool { /** The logger for this class */ private static final Logger logger = Logger.getLogger(ActionTool.class.getName()); /** The random. */ private static Random random = new Random(); /** The warning image. */ private static ImageView warningImage = InfoTool.getImageViewFromResourcesFolder("warning.png"); /** The question image. */ private static ImageView questionImage = InfoTool.getImageViewFromResourcesFolder("question.png"); /** * Private Constructor. */ private ActionTool() { } /** * Opens the file with the System default file explorer. * * @param path * the path */ public static void openFileLocation(String path) { // Open the Default Browser if (System.getProperty("os.name").toLowerCase().contains("win")) { showNotification("Message", "Opening in System File Explorer...\n" + InfoTool.getFileName(path), Duration.millis(1500), NotificationType.INFORMATION); //START: --NEEDS TO BE FIXED!!!!!!----------------NOT WORKING WELL----- path = path.trim().replaceAll(" +", " "); String selectPath = "/select," + path; //START: Strip one SPACE among consecutive spaces LinkedList<String> list = new LinkedList<>(); StringBuilder sb = new StringBuilder(); boolean flag = true; for (int i = 0; i < selectPath.length(); i++) { if (i == 0) { sb.append(selectPath.charAt(i)); continue; } if (selectPath.charAt(i) == ' ' && flag) { list.add(sb.toString()); sb.setLength(0); flag = false; continue; } if (!flag && selectPath.charAt(i) != ' ') flag = true; sb.append(selectPath.charAt(i)); } list.add(sb.toString()); list.addFirst("explorer.exe"); //END: Strip one SPACE among consecutive spaces //END: --NEEDS TO BE FIXED!!!!!!----------------NOT WORKING WELL----- try { //Open in Explorer and Highlight new ProcessBuilder(list).start(); } catch (IOException ex) { logger.log(Level.WARNING, ex.getMessage(), ex); showNotification("Folder Explorer Fail", "Failed to open file explorer.", Duration.millis(1500), NotificationType.WARNING); } } else { showNotification("Not Supported", "This function is only supported in Windows \n I am trying my best to implement it and on other operating systems :)", Duration.millis(1500), NotificationType.WARNING); } } /** * Copy a file from source to destination. * * @param source * the source * @param destination * the destination * @return True if succeeded , False if not */ public static boolean copy(String source , String destination) { boolean succeess = true; System.out.println("Copying ->" + source + "\n\tto ->" + destination); try { Files.copy(Paths.get(source), Paths.get(destination), StandardCopyOption.REPLACE_EXISTING); } catch (IOException ex) { logger.log(Level.WARNING, "", ex); succeess = false; } return succeess; } /** * Copy a file from source to destination. * * @param source * the source * @param destination * the destination * @return True if succeeded , False if not */ public static boolean copy(InputStream source , String destination) { boolean succeess = true; System.out.println("Copying ->" + source + "\n\tto ->" + destination); try { System.out.println(Files.copy(source, Paths.get(destination), StandardCopyOption.REPLACE_EXISTING)); } catch (IOException ex) { logger.log(Level.WARNING, "", ex); succeess = false; } return succeess; } /** * Moves a file to a different location. * * @param source * the source * @param destination * the dest * @return true, if successful */ public static boolean move(String source , String destination) { boolean succeess = true; System.out.println("Moving ->" + source + "\n\tto ->" + destination); try { Files.move(Paths.get(source), Paths.get(destination), StandardCopyOption.REPLACE_EXISTING); } catch (IOException ex) { logger.log(Level.WARNING, "", ex); succeess = false; } return succeess; } /** * Deletes Directory of File. * * @param source * The File to be deleted | either if it is directory or File * @return true, if successful */ public static boolean deleteFile(File source) { if (source.isDirectory()) { // Directory try { FileUtils.deleteDirectory(source); } catch (IOException ex) { logger.log(Level.INFO, "", ex); } } else if (source.isFile() && !source.delete()) { // File showNotification("Message", "Can't delete file:\n(" + source.getName() + ") cause is in use by a program.", Duration.millis(2000), NotificationType.WARNING); return false; } return true; } /** * Calculates the creationTime of the File. * * @param path * the path * @return A String in format <b> DD/MM/YYYY</b> */ public static String getFileDateCreated(String path) { String[] dateCreatedF = getFileCreationTime(path).toString().split("-"); return dateCreatedF[2].substring(0, 2) + "/" + dateCreatedF[1] + "/" + dateCreatedF[0]; } /** * Calculates the creationTime of the File. * * @param path * the path * @return FileTime */ public static FileTime getFileCreationTime(String path) { try { return Files.readAttributes(Paths.get(path), BasicFileAttributes.class).creationTime(); } catch (IOException ex) { logger.log(Level.INFO, "", ex); } return null; } /** * Tries to open this File with the default system program * * @param absolutePath * The absolute path of the File * @return <b>True</b> if succeeded , <b>False</b> if not */ public static boolean openFile(String absolutePath) { // Open the Default Browser if (Desktop.isDesktopSupported()) { Desktop desktop = Desktop.getDesktop(); try { desktop.open(new File(absolutePath)); } catch (IOException ex) { Platform.runLater(() -> ActionTool.showNotification("Problem Occured", "Can't open default File at:\n[" + absolutePath + " ]", Duration.millis(2500), NotificationType.INFORMATION)); logger.log(Level.INFO, "", ex); return false; } // Error? } else { Platform.runLater(() -> ActionTool.showNotification("Problem Occured", "Can't open default File at:\n[" + absolutePath + " ]", Duration.millis(2500), NotificationType.INFORMATION)); System.out.println("Error trying to open the default web browser."); return false; } return true; } /** * Tries to open that URI on the default browser * * @param uri * @return <b>True</b> if succeeded , <b>False</b> if not */ public static boolean openWebSite(String uri) { // Open the Default Browser if (Desktop.isDesktopSupported()) { Desktop desktop = Desktop.getDesktop(); try { desktop.browse(new URI(uri)); } catch (IOException | URISyntaxException ex) { Platform.runLater(() -> ActionTool.showNotification("Problem Occured", "Can't open default web browser at:\n[" + uri + " ]", Duration.millis(2500), NotificationType.INFORMATION)); logger.log(Level.INFO, "", ex); return false; } // Error? } else { Platform.runLater(() -> ActionTool.showNotification("Problem Occured", "Can't open default web browser at:\n[" + uri + " ]", Duration.millis(2500), NotificationType.INFORMATION)); System.out.println("Error trying to open the default web browser."); return false; } return true; } /** * Show a notification. * * @param title * The notification title * @param text * The notification text * @param d * The duration that notification will be visible * @param t * The notification type */ public static void showNotification(String title , String text , Duration d , NotificationType t) { //Check if it is JavaFX Application Thread if (!Platform.isFxApplicationThread()) { Platform.runLater(() -> showNotification(title, text, d, t)); return; } Notifications notification1 = Notifications.create().title(title).text(text); notification1.hideAfter(d); switch (t) { case CONFIRM: notification1.showConfirm(); break; case ERROR: notification1.showError(); break; case INFORMATION: notification1.showInformation(); break; case SIMPLE: notification1.show(); break; case WARNING: notification1.showWarning(); break; default: break; } } /** * Shows an Alert * * @param title * @param headerText * @param contentText */ public static void showAlert(String title , String headerText , String contentText) { // Show Alert Alert alert = new Alert(AlertType.INFORMATION); alert.initStyle(StageStyle.UTILITY); alert.initOwner(Main.window); //alert.setGraphic(questionImage) alert.setTitle(title); alert.setHeaderText(title); alert.setContentText(contentText); alert.showAndWait(); } /** * Makes a question to the user. * * @param text * the text * @return true, if successful */ public static boolean doQuestion(String text , Stage window) { boolean[] questionAnswer = { false }; // Show Alert Alert alert = new Alert(AlertType.CONFIRMATION); alert.initStyle(StageStyle.UTILITY); alert.initOwner(window); alert.setGraphic(questionImage); alert.setHeaderText("Question"); alert.setContentText(text); alert.showAndWait().ifPresent(answer -> questionAnswer[0] = ( answer == ButtonType.OK )); return questionAnswer[0]; } /** * Makes a question to the user. * * @param text * the text * @param node * The node owner of the Alert * @return true, if successful */ public static boolean doQuestion(String text , Node node , Stage window) { boolean[] questionAnswer = { false }; // Show Alert Alert alert = new Alert(AlertType.CONFIRMATION); alert.initOwner(window); alert.initStyle(StageStyle.UTILITY); alert.setGraphic(questionImage); alert.setHeaderText("Question"); alert.setContentText(text); // Make sure that JavaFX doesn't cut the text with ... alert.getDialogPane().getChildren().stream().filter(item -> node instanceof Label).forEach(item -> ( (Label) node ).setMinHeight(Region.USE_PREF_SIZE)); // I noticed that height property is notified after width property // that's why i choose to add the listener here alert.heightProperty().addListener(l -> { // Width and Height of the Alert int alertWidth = (int) alert.getWidth(); int alertHeight = (int) alert.getHeight(); // Here it prints 0!! System.out.println("Alert Width: " + alertWidth + " , Alert Height: " + alertHeight); // Find the bounds of the node Bounds bounds = node.localToScreen(node.getBoundsInLocal()); int x = (int) ( bounds.getMinX() + bounds.getWidth() / 2 - alertWidth / 2 ); int y = (int) ( bounds.getMinY() + bounds.getHeight() / 2 - alertHeight / 2 ); // Check if Alert goes out of the Screen on X Axis if (x + alertWidth > InfoTool.getVisualScreenWidth()) x = (int) ( InfoTool.getVisualScreenWidth() - alertWidth ); else if (x < 0) x = 0; // Check if Alert goes out of the Screen on Y AXIS if (y + alertHeight > InfoTool.getVisualScreenHeight()) y = (int) ( InfoTool.getVisualScreenHeight() - alertHeight ); else if (y < 0) y = 0; // Set the X and Y of the Alert alert.setX(x); alert.setY(y); }); // Show the Alert alert.showAndWait().ifPresent(answer -> questionAnswer[0] = ( answer == ButtonType.OK )); return questionAnswer[0]; } /** * Delete confirmation. * * @param permanent * the permanent * @param text * the text * @param i * the i * @return true, if successful */ public static boolean doDeleteQuestion(boolean permanent , String text , int i , Stage window) { boolean[] questionAnswer = { false }; String unique = "\n [" + text + "]"; String multiple = "[" + text + " items]"; Alert alert = new Alert(AlertType.CONFIRMATION); alert.initStyle(StageStyle.UTILITY); alert.initOwner(window); alert.setGraphic(!permanent ? questionImage : warningImage); alert.setHeaderText(!permanent ? "Remove selection" + ( i > 1 ? "s " + multiple : unique ) + " from List?" : "Are you sure you want to permanently delete " + ( i > 1 ? "these " + multiple : "this item " + unique ) + " ?"); alert.setContentText(!permanent ? "Are you sure you want to remove the selected " + ( i > 1 ? "items" : "item" ) + " from the List?" : "If you delete the selection " + ( i > 1 ? "s they" : "it" ) + " will be permanenlty lost."); // LookUpButton ( (Button) alert.getDialogPane().lookupButton(ButtonType.OK) ).setDefaultButton(false); ( (Button) alert.getDialogPane().lookupButton(ButtonType.CANCEL) ).setDefaultButton(true); alert.showAndWait().ifPresent(answer -> { if (answer == ButtonType.OK) questionAnswer[0] = true; }); return questionAnswer[0]; } /** * Returns a Random Number from 0 to ...what i have choosen in method see * the doc * * @return A random integer */ public static int returnRandom() { return random.nextInt(80000); } /** * Return random table name. * * @return Returns a RandomTableName for the database in format * ("_"+randomNumber) */ public static String returnRandomTableName() { return "_" + returnRandom(); } /** * Paint the given text on the given graphics context. * * @param gc * the gc * @param text * the text * @param width * the width * @param height * the height */ public static void paintCanvas(GraphicsContext gc , String text , int width , int height) { // Clear gc.clearRect(0, 0, width, height); // Paint it gc.setLineWidth(2); gc.setLineDashes(3); gc.setFill(Color.WHITE); gc.fillRoundRect(0, 0, width, height, 15, 15); gc.setStroke(Color.BLACK); gc.strokeRoundRect(0, 0, width, height, 15, 15); gc.setFill(Color.BLACK); gc.setFont(Font.font(null, FontWeight.BOLD, 14)); gc.fillText(text, 4, height / 2.00); } }