From 0ba5721315bbeb1b59da63f5e2b9335135cbc4d9 Mon Sep 17 00:00:00 2001 From: xfarrow Date: Mon, 7 Aug 2023 12:39:29 +0200 Subject: [PATCH] Code formatting --- Guify/src/code/Constants.java | 8 +- .../Implementations/JFrameFactory.java | 47 +- .../Implementations/JGenericTextArea.java | 54 +- .../Interfaces/IGenericTextArea.java | 14 +- Guify/src/code/GuifySftpProgressMonitor.java | 13 +- Guify/src/code/Helper.java | 15 +- Guify/src/code/IDirectoryNodeButton.java | 5 +- Guify/src/code/JDirectoryNodeButton.java | 21 +- Guify/src/code/Main.java | 6 +- Guify/src/code/QueueEventManager.java | 70 +- Guify/src/code/SshEngine.java | 348 +++--- Guify/src/code/TransferProgress.java | 10 +- Guify/src/code/TreeNode.java | 3 +- Guify/src/code/WrapLayout.java | 283 ++--- Guify/src/controllers/DesktopController.java | 326 ++--- .../controllers/FindAndReplaceController.java | 98 +- Guify/src/controllers/LoginController.java | 44 +- Guify/src/controllers/NotepadController.java | 23 +- Guify/src/controllers/QueueController.java | 170 +-- Guify/src/views/Desktop.java | 1074 +++++++++-------- Guify/src/views/FindAndReplace.java | 162 +-- Guify/src/views/Login.java | 42 +- Guify/src/views/Notepad.java | 129 +- Guify/src/views/Queue.java | 194 +-- 24 files changed, 1691 insertions(+), 1468 deletions(-) diff --git a/Guify/src/code/Constants.java b/Guify/src/code/Constants.java index 882120b..0a4a87b 100644 --- a/Guify/src/code/Constants.java +++ b/Guify/src/code/Constants.java @@ -6,14 +6,14 @@ public class Constants { public static final String APP_NAME = "Guify"; public static final String VERSION = "1.0.4"; public static final int VERSION_PROGRESSIVE = 4; - - public static class Constants_FSOperations{ + + public static class Constants_FSOperations { public static final int NONE = 0; public static final int CUT = 1; public static final int COPY = 2; } - - public static class GuifyColors{ + + public static class GuifyColors { public static final Color BLUE = new Color(3, 169, 244); public static final Color GRAY = new Color(240, 240, 240); public static final Color GRAY_HOVER = new Color(220, 220, 220); diff --git a/Guify/src/code/GuiAbstractions/Implementations/JFrameFactory.java b/Guify/src/code/GuiAbstractions/Implementations/JFrameFactory.java index b79de58..b8807bc 100644 --- a/Guify/src/code/GuiAbstractions/Implementations/JFrameFactory.java +++ b/Guify/src/code/GuiAbstractions/Implementations/JFrameFactory.java @@ -7,29 +7,30 @@ import views.*; * Frame factory. Factory for JFrame (Java Swing). */ public class JFrameFactory implements IFrameFactory { - - public static Object createJFrame(int frameType, Object controller) throws Exception{ - - switch(frameType) { - - case LOGIN: - return new Login(controller); - - case DESKTOP: - return new Desktop(controller); - - case NOTEPAD: - return new Notepad(controller); - - case FIND_AND_REPLACE: - return new FindAndReplace(controller); - - case QUEUE: - return new Queue(controller); - - default: - throw new Exception("Invalid frame name"); + + public static Object createJFrame(int frameType, Object controller) + throws Exception { + + switch (frameType) { + + case LOGIN : + return new Login(controller); + + case DESKTOP : + return new Desktop(controller); + + case NOTEPAD : + return new Notepad(controller); + + case FIND_AND_REPLACE : + return new FindAndReplace(controller); + + case QUEUE : + return new Queue(controller); + + default : + throw new Exception("Invalid frame name"); } } - + } diff --git a/Guify/src/code/GuiAbstractions/Implementations/JGenericTextArea.java b/Guify/src/code/GuiAbstractions/Implementations/JGenericTextArea.java index 11ce49e..36b2685 100644 --- a/Guify/src/code/GuiAbstractions/Implementations/JGenericTextArea.java +++ b/Guify/src/code/GuiAbstractions/Implementations/JGenericTextArea.java @@ -5,71 +5,71 @@ import code.GuiAbstractions.Interfaces.IGenericTextArea; /** * - * A class implementing an interface for a generic text - * area. It is currently using JTextArea (Java Swing) + * A class implementing an interface for a generic text area. It is currently + * using JTextArea (Java Swing) * */ public class JGenericTextArea implements IGenericTextArea { - + private JTextArea textArea; - + public JGenericTextArea(JTextArea textArea) { this.textArea = textArea; } - + @Override public void selectText(int start, int end) { - if(textArea == null) + if (textArea == null) return; - - textArea.requestFocus(); // enforce focus or it will not be selected - textArea.select(start, end); + + textArea.requestFocus(); // enforce focus or it will not be selected + textArea.select(start, end); } - + public String getText() { - if(textArea == null) { + if (textArea == null) { throw new NullPointerException("TextArea is null"); } - + return textArea.getText(); } - + public void setText(String text) { - if(textArea == null) { + if (textArea == null) { throw new NullPointerException("TextArea is null"); } - + textArea.setText(text); } - + public void replaceRange(String s, int start, int end) { - if(textArea == null) { + if (textArea == null) { throw new NullPointerException("TextArea is null"); } - + textArea.replaceRange(s, start, end); } @Override public void setCaretPosition(int position) { - if(textArea == null) { + if (textArea == null) { throw new NullPointerException("TextArea is null"); } - + textArea.setCaretPosition(position); } @Override public int getCaretPosition() { - if(textArea == null) { + if (textArea == null) { throw new NullPointerException("TextArea is null"); } - + return textArea.getCaretPosition(); } - - public int getSelectionStart(){ - if(textArea == null) { + + public int getSelectionStart() { + if (textArea == null) { throw new NullPointerException("TextArea is null"); } return textArea.getSelectionStart(); @@ -77,10 +77,10 @@ public class JGenericTextArea implements IGenericTextArea { @Override public boolean hasHighlightedText() { - if(textArea == null) { + if (textArea == null) { throw new NullPointerException("TextArea is null"); } return textArea.getSelectionStart() != textArea.getCaretPosition(); } - + } diff --git a/Guify/src/code/GuiAbstractions/Interfaces/IGenericTextArea.java b/Guify/src/code/GuiAbstractions/Interfaces/IGenericTextArea.java index 0ad2123..1326c0e 100644 --- a/Guify/src/code/GuiAbstractions/Interfaces/IGenericTextArea.java +++ b/Guify/src/code/GuiAbstractions/Interfaces/IGenericTextArea.java @@ -3,17 +3,13 @@ package code.GuiAbstractions.Interfaces; /** * * - * Interface for a generic TextArea. - * It is used to create an abstraction of a - * TextArea, without using view-specific objects - * (such as JTextArea). + * Interface for a generic TextArea. It is used to create an abstraction of a + * TextArea, without using view-specific objects (such as JTextArea). * - * This increases modularity, flexibility and - * creates a separation of concerns. + * This increases modularity, flexibility and creates a separation of concerns. * - * In case of change of the GUI library you - * do not need to change neither the Controllers nor - * these interfaces, but only the implementations. + * In case of change of the GUI library you do not need to change neither the + * Controllers nor these interfaces, but only the implementations. * */ public interface IGenericTextArea { diff --git a/Guify/src/code/GuifySftpProgressMonitor.java b/Guify/src/code/GuifySftpProgressMonitor.java index 34266a3..d65e81a 100644 --- a/Guify/src/code/GuifySftpProgressMonitor.java +++ b/Guify/src/code/GuifySftpProgressMonitor.java @@ -6,16 +6,17 @@ import com.jcraft.jsch.SftpProgressMonitor; public class GuifySftpProgressMonitor implements SftpProgressMonitor { TransferProgress transferProgress = null; - + @Override public boolean count(long bytes) { - - if(transferProgress != null) { - transferProgress.setTransferredBytes(transferProgress.getTransferredBytes() + bytes); + + if (transferProgress != null) { + transferProgress.setTransferredBytes( + transferProgress.getTransferredBytes() + bytes); transferProgress.setTransferStatus(TransferProgress.UPDATING); QueueEventManager.getInstance().notify(transferProgress); } - + // true if the transfer should go on // false if the transfer should be cancelled return true; @@ -23,7 +24,7 @@ public class GuifySftpProgressMonitor implements SftpProgressMonitor { @Override public void end() { - if(transferProgress != null) { + if (transferProgress != null) { transferProgress.setTransferStatus(TransferProgress.END); QueueEventManager.getInstance().notify(transferProgress); } diff --git a/Guify/src/code/Helper.java b/Guify/src/code/Helper.java index 62c9d9e..2a9b1ed 100644 --- a/Guify/src/code/Helper.java +++ b/Guify/src/code/Helper.java @@ -9,21 +9,20 @@ public class Helper { */ public static String combinePath(String s1, String s2) { StringBuilder result = new StringBuilder(s1); - if(!s1.endsWith("/")) { + if (!s1.endsWith("/")) { result.append('/'); } result.append(s2); return result.toString(); } - + public static String getParentPath(String path) { - if(path.equals("/")) { + if (path.equals("/")) { return "/"; - } - else if(path.equals("~")) { - return Path.of(SshEngine.executeCommand("pwd")).getParent().toString().replace('\\', '/'); - } - else { + } else if (path.equals("~")) { + return Path.of(SshEngine.executeCommand("pwd")).getParent() + .toString().replace('\\', '/'); + } else { return Path.of(path).getParent().toString().replace('\\', '/'); } } diff --git a/Guify/src/code/IDirectoryNodeButton.java b/Guify/src/code/IDirectoryNodeButton.java index 48ecf93..b8512c0 100644 --- a/Guify/src/code/IDirectoryNodeButton.java +++ b/Guify/src/code/IDirectoryNodeButton.java @@ -4,9 +4,8 @@ import com.jcraft.jsch.ChannelSftp.LsEntry; /** * - * Interface describing a DirectoryNodeButton, - * independently of how a concrete DirectoryNodeButton - * will be (currently it is concretely a JButton) + * Interface describing a DirectoryNodeButton, independently of how a concrete + * DirectoryNodeButton will be (currently it is concretely a JButton) * */ public interface IDirectoryNodeButton { diff --git a/Guify/src/code/JDirectoryNodeButton.java b/Guify/src/code/JDirectoryNodeButton.java index 33580ed..0224527 100644 --- a/Guify/src/code/JDirectoryNodeButton.java +++ b/Guify/src/code/JDirectoryNodeButton.java @@ -7,34 +7,35 @@ import com.jcraft.jsch.ChannelSftp.LsEntry; /** * - * A JButton representing a Directory Node. - * Useful when a Directory Node is needed - * to be drew on screen. + * A JButton representing a Directory Node. Useful when a Directory Node is + * needed to be drew on screen. * */ -public class JDirectoryNodeButton extends JButton implements IDirectoryNodeButton { - +public class JDirectoryNodeButton extends JButton + implements + IDirectoryNodeButton { + private static final long serialVersionUID = 1L; public ChannelSftp.LsEntry node = null; private boolean isSelected = false; - + public JDirectoryNodeButton() { super(); } - + public JDirectoryNodeButton(ChannelSftp.LsEntry node) { super(); setNode(node); } - + public void setNode(ChannelSftp.LsEntry node) { this.node = node; } - + public void setSelected(boolean selected) { this.isSelected = selected; } - + public boolean getSelected() { return this.isSelected; } diff --git a/Guify/src/code/Main.java b/Guify/src/code/Main.java index ee0a7ee..62e4983 100644 --- a/Guify/src/code/Main.java +++ b/Guify/src/code/Main.java @@ -4,7 +4,7 @@ import java.awt.EventQueue; import controllers.LoginController; public class Main { - + /** * Guify's entry point */ @@ -19,5 +19,7 @@ public class Main { } }); } - + } + +// In loving memory of L.B. and E.B. diff --git a/Guify/src/code/QueueEventManager.java b/Guify/src/code/QueueEventManager.java index 06ec5b1..3c9e835 100644 --- a/Guify/src/code/QueueEventManager.java +++ b/Guify/src/code/QueueEventManager.java @@ -1,41 +1,43 @@ package code; -import java.util.Observable; +import java.util.Observable; import java.util.concurrent.*; @SuppressWarnings("deprecation") // Observer is okay here public class QueueEventManager extends Observable { - + private static QueueEventManager instance; - - // Cannot instantiate from outside - private QueueEventManager() {} - - // We need this object in order to retrieve old transfers which are not being transferred - ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); - - public static synchronized QueueEventManager getInstance() { - if (instance == null) { - instance = new QueueEventManager(); - } - return instance; - } - - public void notify(TransferProgress arg) { - updateQueue(arg); - setChanged(); - notifyObservers(arg); - } - - private void updateQueue(TransferProgress transferProgressObj) { - if(transferProgressObj.getTransferStatus() == TransferProgress.INIT) { - queue.add(transferProgressObj); - } - else if(transferProgressObj.getTransferStatus() == TransferProgress.END) { - queue.remove(); - } - } - - public TransferProgress[] getQueue() { - return queue.toArray(new TransferProgress[queue.size()]); - } + + // Cannot instantiate from outside + private QueueEventManager() { + } + + // We need this object in order to retrieve old transfers which are not + // being transferred + ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); + + public static synchronized QueueEventManager getInstance() { + if (instance == null) { + instance = new QueueEventManager(); + } + return instance; + } + + public void notify(TransferProgress arg) { + updateQueue(arg); + setChanged(); + notifyObservers(arg); + } + + private void updateQueue(TransferProgress transferProgressObj) { + if (transferProgressObj.getTransferStatus() == TransferProgress.INIT) { + queue.add(transferProgressObj); + } else if (transferProgressObj + .getTransferStatus() == TransferProgress.END) { + queue.remove(); + } + } + + public TransferProgress[] getQueue() { + return queue.toArray(new TransferProgress[queue.size()]); + } } diff --git a/Guify/src/code/SshEngine.java b/Guify/src/code/SshEngine.java index 47059b3..19dda28 100644 --- a/Guify/src/code/SshEngine.java +++ b/Guify/src/code/SshEngine.java @@ -16,29 +16,29 @@ import java.nio.file.*; /** * - * Underlying SSH engine for - * the application + * Underlying SSH engine for the application * */ public class SshEngine { - + private static Session session = null; - + /* * ========== BEGIN SSH Utilities ========== */ - + public static boolean connetion() { return createSession(); } - + private static boolean createSession() { Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); JSch jsch = new JSch(); try { - session = jsch.getSession(LoginController.LoginCredentials.username, LoginController.LoginCredentials.host, + session = jsch.getSession(LoginController.LoginCredentials.username, + LoginController.LoginCredentials.host, LoginController.LoginCredentials.port); session.setPassword(LoginController.LoginCredentials.password); session.setConfig(config); @@ -52,32 +52,31 @@ public class SshEngine { return true; } - private static void checkValidityOrCreateSession() throws JSchException { - if(session == null || !session.isConnected()) { - if(!createSession()) { + private static void checkValidityOrCreateSession() throws JSchException { + if (session == null || !session.isConnected()) { + if (!createSession()) { throw new JSchException("Failed to create a session in Jsch"); } } } public static void disconnectSession() { - if(session != null) { + if (session != null) { session.disconnect(); } } - + /* * ========== END SSH Utilities ========== */ - /* * ========== BEGIN SFTP get() and put() methods ========== */ /** - * Downloads a file from remote host to local machine. - * Executed asynchronously. + * Downloads a file from remote host to local machine. Executed + * asynchronously. */ public static void downloadFile(String source, String dest) { // We execute the lengthy and time-consuming operation on a different @@ -85,36 +84,38 @@ public class SshEngine { // We use SwingWorker so any GUI changes requested by this thread will // be correctly addressed to the Event Dispatch Thread new Thread(new Runnable() { - public void run() { - ChannelSftp channelSftp = null; + public void run() { + ChannelSftp channelSftp = null; try { checkValidityOrCreateSession(); channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); - channelSftp.get(source, dest, new GuifySftpProgressMonitor()); - System.out.println("File " + source + " downloaded in " + dest); + channelSftp.get(source, dest, + new GuifySftpProgressMonitor()); + System.out.println( + "File " + source + " downloaded in " + dest); } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } - } + } }).start(); } - + /** - * Downloads a directory recursively. - * Executed asynchronously. + * Downloads a directory recursively. Executed asynchronously. */ - public static void downloadDirectoryRecursively(String source, String dest) { + public static void downloadDirectoryRecursively(String source, + String dest) { // We execute the lengthy and time-consuming operation on a different // thread instead of the Event Dispatch Thread. // We use SwingWorker so any GUI changes requested by this thread will // be correctly addressed to the Event Dispatch Thread new Thread(new Runnable() { - public void run() { - ChannelSftp channelSftp = null; + public void run() { + ChannelSftp channelSftp = null; try { channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); @@ -125,143 +126,170 @@ public class SshEngine { if (channelSftp != null) channelSftp.disconnect(); } - } + } }).start(); } - + /** * Private utility - * @param channel_aux An auxiliary SFTP channel + * + * @param channel_aux + * An auxiliary SFTP channel * @param remoteDirectory * @param localDirectory * @throws SftpException */ - private static void downloadDirectoryRecursively_aux(ChannelSftp channel_aux, String remoteDirectory, String localDirectory) throws SftpException { - channel_aux.cd(remoteDirectory); - String newLocalDir = Helper.combinePath(localDirectory, Paths.get(remoteDirectory).getFileName().toString()); - new java.io.File(newLocalDir).mkdirs(); - @SuppressWarnings("unchecked") + private static void downloadDirectoryRecursively_aux( + ChannelSftp channel_aux, String remoteDirectory, + String localDirectory) throws SftpException { + channel_aux.cd(remoteDirectory); + String newLocalDir = Helper.combinePath(localDirectory, + Paths.get(remoteDirectory).getFileName().toString()); + new java.io.File(newLocalDir).mkdirs(); + @SuppressWarnings("unchecked") Vector entries = channel_aux.ls("*"); - - for (ChannelSftp.LsEntry entry : entries) { - if (!entry.getAttrs().isDir()) { - // File - download it - // Creates a thread for each file. If there are a lot of files - // it may be resource-draining. Consider using a ThreadPool - downloadFile(Helper.combinePath(remoteDirectory, entry.getFilename()), Helper.combinePath(newLocalDir, entry.getFilename())); - } else if (!".".equals(entry.getFilename()) && !"..".equals(entry.getFilename())) { - // Directory - download recursively - String newRemoteDir = Helper.combinePath(remoteDirectory, entry.getFilename()); - downloadDirectoryRecursively_aux(channel_aux, newRemoteDir, newLocalDir); - } - } - } - + + for (ChannelSftp.LsEntry entry : entries) { + if (!entry.getAttrs().isDir()) { + // File - download it + // Creates a thread for each file. If there are a lot of files + // it may be resource-draining. Consider using a ThreadPool + downloadFile( + Helper.combinePath(remoteDirectory, + entry.getFilename()), + Helper.combinePath(newLocalDir, entry.getFilename())); + } else if (!".".equals(entry.getFilename()) + && !"..".equals(entry.getFilename())) { + // Directory - download recursively + String newRemoteDir = Helper.combinePath(remoteDirectory, + entry.getFilename()); + downloadDirectoryRecursively_aux(channel_aux, newRemoteDir, + newLocalDir); + } + } + } + /** - * Uploads a file from the local machine to the remote host. - * Executed asynchronously. + * Uploads a file from the local machine to the remote host. Executed + * asynchronously. */ - public static void uploadFile(File fileToUpload, String remoteDirectory) throws SftpException { + public static void uploadFile(File fileToUpload, String remoteDirectory) + throws SftpException { // We execute the lengthy and time-consuming operation on a different // thread instead of the Event Dispatch Thread. // We use SwingWorker so any GUI changes requested by this thread will // be correctly addressed to the Event Dispatch Thread new Thread(new Runnable() { - public void run() { - ChannelSftp channelSftp = null; + public void run() { + ChannelSftp channelSftp = null; String remotePath = null; try { checkValidityOrCreateSession(); channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); - remotePath = Helper.combinePath(remoteDirectory, fileToUpload.getName()); - channelSftp.put(fileToUpload.getAbsolutePath(), remotePath, new GuifySftpProgressMonitor()); - System.out.println("File: " + fileToUpload.getAbsolutePath() + " uploaded to remote path: " + remotePath); - } - catch(SftpException sftpex) { + remotePath = Helper.combinePath(remoteDirectory, + fileToUpload.getName()); + channelSftp.put(fileToUpload.getAbsolutePath(), remotePath, + new GuifySftpProgressMonitor()); + System.out.println("File: " + fileToUpload.getAbsolutePath() + + " uploaded to remote path: " + remotePath); + } catch (SftpException sftpex) { // TODO maybe no permissions - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } - } + } }).start(); } - + /** - * Uploads directory recursively. - * Executed asynchronously. - * @param directory Full path of the local directory to upload - * @param remoteDirectory Full path of the remote directory which the local - * directory will be uploaded in + * Uploads directory recursively. Executed asynchronously. + * + * @param directory + * Full path of the local directory to upload + * @param remoteDirectory + * Full path of the remote directory which the local directory + * will be uploaded in */ - public static void uploadDirectoriesRecursively(File directory, String remoteDirectory) throws SftpException { + public static void uploadDirectoriesRecursively(File directory, + String remoteDirectory) throws SftpException { // We execute the lengthy and time-consuming operation on a different // thread instead of the Event Dispatch Thread. // We use SwingWorker so any GUI changes requested by this thread will // be correctly addressed to the Event Dispatch Thread new Thread(new Runnable() { - public void run() { + public void run() { ChannelSftp channelSftp = null; try { checkValidityOrCreateSession(); channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); - uploadDirectoriesRecursively_aux(channelSftp, directory, remoteDirectory); - } - catch(SftpException sftpex) { - //TODO maybe no permissions - } - catch (Exception e) { + uploadDirectoriesRecursively_aux(channelSftp, directory, + remoteDirectory); + } catch (SftpException sftpex) { + // TODO maybe no permissions + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } - } + } }).start(); } - + /** * Private utility + * * @param channel_aux * @param localPath * @param remoteDirectory * @throws SftpException */ - private static void uploadDirectoriesRecursively_aux(ChannelSftp channel_aux, File localPath, String remoteDirectory) throws SftpException { - if(localPath != null) { - String subDirectoryPath = Helper.combinePath(remoteDirectory, localPath.getName()); - channel_aux.mkdir(subDirectoryPath); - - File[] files = localPath.listFiles(); - if (files != null) { - for (File file : files) { - if (file.isFile()) { - // Creates a thread for each file. If there are a lot of files - // it may be resource-draining. Consider using a ThreadPool - channel_aux.put(file.getAbsolutePath(), Helper.combinePath(subDirectoryPath, file.getName()), new GuifySftpProgressMonitor()); - System.out.println("File: " + file.getAbsolutePath() + " uploaded to remote path: " + Helper.combinePath(subDirectoryPath, file.getName())); - } else if (file.isDirectory()) { - uploadDirectoriesRecursively_aux(channel_aux, file, subDirectoryPath); - } - } - } - } - } - + private static void uploadDirectoriesRecursively_aux( + ChannelSftp channel_aux, File localPath, String remoteDirectory) + throws SftpException { + if (localPath != null) { + String subDirectoryPath = Helper.combinePath(remoteDirectory, + localPath.getName()); + channel_aux.mkdir(subDirectoryPath); + + File[] files = localPath.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isFile()) { + // Creates a thread for each file. If there are a lot of + // files + // it may be resource-draining. Consider using a + // ThreadPool + channel_aux.put(file.getAbsolutePath(), + Helper.combinePath(subDirectoryPath, + file.getName()), + new GuifySftpProgressMonitor()); + System.out.println("File: " + file.getAbsolutePath() + + " uploaded to remote path: " + + Helper.combinePath(subDirectoryPath, + file.getName())); + } else if (file.isDirectory()) { + uploadDirectoriesRecursively_aux(channel_aux, file, + subDirectoryPath); + } + } + } + } + } + /* * ========== END SFTP get() and put() methods ========== */ - - + /* * ========== BEGIN File System operations ========== */ - + public static void mkdir(String path) throws SftpException { ChannelSftp channelSftp = null; try { @@ -269,18 +297,16 @@ public class SshEngine { channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); channelSftp.mkdir(path); - } - catch(SftpException sftpex) { - throw sftpex; - } - catch (Exception e) { + } catch (SftpException sftpex) { + throw sftpex; + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } } - + public static String readFile(String filePath) { ChannelSftp channel = null; try { @@ -296,14 +322,15 @@ public class SshEngine { channel.disconnect(); } } - + public static void writeFile(String content, String pathToFile) { ChannelSftp channelSftp = null; try { checkValidityOrCreateSession(); channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); - channelSftp.put(new ByteArrayInputStream(content.getBytes()), pathToFile); + channelSftp.put(new ByteArrayInputStream(content.getBytes()), + pathToFile); } catch (Exception e) { e.printStackTrace(); } finally { @@ -311,29 +338,29 @@ public class SshEngine { channelSftp.disconnect(); } } - - public static void rename(String oldPath, String newPath) throws SftpException { + + public static void rename(String oldPath, String newPath) + throws SftpException { ChannelSftp channelSftp = null; try { checkValidityOrCreateSession(); channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); channelSftp.rename(oldPath, newPath); - } - catch(SftpException sftpex) { + } catch (SftpException sftpex) { throw sftpex; - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } } - + /** * Creates an empty file in the specified remote file path - * @throws SftpException + * + * @throws SftpException */ public static void touch(String remoteFilePath) throws SftpException { ChannelSftp channelSftp = null; @@ -341,19 +368,18 @@ public class SshEngine { checkValidityOrCreateSession(); channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); - channelSftp.put(new ByteArrayInputStream(new byte[0]), remoteFilePath); - } - catch(SftpException sftpex) { + channelSftp.put(new ByteArrayInputStream(new byte[0]), + remoteFilePath); + } catch (SftpException sftpex) { throw sftpex; - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } } - + public static void rm(String remoteFilePath) throws SftpException { ChannelSftp channelSftp = null; try { @@ -361,43 +387,40 @@ public class SshEngine { channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); channelSftp.rm(remoteFilePath); - } - catch(SftpException sftpex) { + } catch (SftpException sftpex) { throw sftpex; - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } } - + public static void rm(List remoteFilePaths) throws SftpException { ChannelSftp channelSftp = null; try { checkValidityOrCreateSession(); channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); - for(String remoteFilePath : remoteFilePaths) { + for (String remoteFilePath : remoteFilePaths) { rm(remoteFilePath, channelSftp); } - } - catch(SftpException sftpex) { + } catch (SftpException sftpex) { throw sftpex; - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } } - - private static void rm(String remoteFilePath, ChannelSftp channelSftp) throws SftpException, JSchException { + + private static void rm(String remoteFilePath, ChannelSftp channelSftp) + throws SftpException, JSchException { channelSftp.rm(remoteFilePath); } - + public static void rmdir(String remoteFilePath) throws SftpException { ChannelSftp channelSftp = null; try { @@ -405,45 +428,43 @@ public class SshEngine { channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); channelSftp.rmdir(remoteFilePath); - } - catch(SftpException sftpex) { + } catch (SftpException sftpex) { throw sftpex; - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } } - + public static void rmdir(List remotePaths) throws SftpException { ChannelSftp channelSftp = null; try { checkValidityOrCreateSession(); channelSftp = (ChannelSftp) session.openChannel("sftp"); channelSftp.connect(); - for(String remotePath : remotePaths) { + for (String remotePath : remotePaths) { rmdir(remotePath, channelSftp); } - } - catch(SftpException sftpex) { + } catch (SftpException sftpex) { throw sftpex; - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } finally { if (channelSftp != null) channelSftp.disconnect(); } } - - private static void rmdir(String remotePath, ChannelSftp channelSftp) throws SftpException, JSchException { + + private static void rmdir(String remotePath, ChannelSftp channelSftp) + throws SftpException, JSchException { channelSftp.rmdir(remotePath); } - + @SuppressWarnings("unchecked") - public static Vector ls(String path) throws SftpException{ + public static Vector ls(String path) + throws SftpException { ChannelSftp channelSftp = null; try { checkValidityOrCreateSession(); @@ -451,13 +472,13 @@ public class SshEngine { channelSftp.connect(); Vector entries = channelSftp.ls(path); // remove hidden directories (TODO create a setting for that) - entries.removeIf(entry -> entry.getFilename().equals(".") || entry.getFilename().equals("..") || entry.getFilename().startsWith(".")); + entries.removeIf(entry -> entry.getFilename().equals(".") + || entry.getFilename().equals("..") + || entry.getFilename().startsWith(".")); return entries; - } - catch(SftpException sftpex) { + } catch (SftpException sftpex) { throw sftpex; - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); return null; } finally { @@ -465,16 +486,15 @@ public class SshEngine { channelSftp.disconnect(); } } - + /* * ========== END File System operations ========== */ - - + /* * ========== BEGIN Other ========== */ - + public static String executeCommand(String command) { System.out.println("> " + command); Channel channel = null; @@ -485,7 +505,8 @@ public class SshEngine { ((ChannelExec) channel).setCommand(command); channel.connect(); in = channel.getInputStream(); - String returnText = new String(in.readAllBytes(), StandardCharsets.UTF_8); + String returnText = new String(in.readAllBytes(), + StandardCharsets.UTF_8); in.close(); // Remove possible \r\n at the end of the string returnText = returnText.replaceAll("[\r\n]+$", "").trim(); @@ -502,12 +523,11 @@ public class SshEngine { } return null; } - + /* * ========== END Other ========== */ - - + } /* * When executing a command on a remote server using SSH with Jsch in Java, we diff --git a/Guify/src/code/TransferProgress.java b/Guify/src/code/TransferProgress.java index d8bbe63..199357d 100644 --- a/Guify/src/code/TransferProgress.java +++ b/Guify/src/code/TransferProgress.java @@ -2,24 +2,24 @@ package code; /** * - * An object representing the transfer progress of a - * file between the server and the host machine. + * An object representing the transfer progress of a file between the server and + * the host machine. * */ public class TransferProgress { - + // Transfer statuses public static final int INIT = 0; public static final int UPDATING = 1; public static final int END = 2; - + private String source; private String destination; private long totalBytes; private long transferredBytes; private int operation; private int transferStatus; - + public String getSource() { return source; } diff --git a/Guify/src/code/TreeNode.java b/Guify/src/code/TreeNode.java index bf98b99..c982ac2 100644 --- a/Guify/src/code/TreeNode.java +++ b/Guify/src/code/TreeNode.java @@ -2,8 +2,7 @@ package code; /** * - * A class representing a - * "tree -J" result + * A class representing a "tree -J" result * */ public class TreeNode { diff --git a/Guify/src/code/WrapLayout.java b/Guify/src/code/WrapLayout.java index 81e366c..d7b4ca6 100644 --- a/Guify/src/code/WrapLayout.java +++ b/Guify/src/code/WrapLayout.java @@ -5,188 +5,191 @@ import javax.swing.JScrollPane; import javax.swing.SwingUtilities; /** - * FlowLayout subclass that fully supports wrapping of components. + * FlowLayout subclass that fully supports wrapping of components. */ -public class WrapLayout extends FlowLayout -{ +public class WrapLayout extends FlowLayout { /** * */ private static final long serialVersionUID = 1L; /** - * Constructs a new WrapLayout with a left - * alignment and a default 5-unit horizontal and vertical gap. - */ - public WrapLayout() - { + * Constructs a new WrapLayout with a left alignment and a + * default 5-unit horizontal and vertical gap. + */ + public WrapLayout() { super(); } /** - * Constructs a new FlowLayout with the specified - * alignment and a default 5-unit horizontal and vertical gap. - * The value of the alignment argument must be one of - * WrapLayout, WrapLayout, - * or WrapLayout. - * @param align the alignment value - */ - public WrapLayout(int align) - { + * Constructs a new FlowLayout with the specified alignment and + * a default 5-unit horizontal and vertical gap. The value of the alignment + * argument must be one of WrapLayout, WrapLayout, + * or WrapLayout. + * + * @param align + * the alignment value + */ + public WrapLayout(int align) { super(align); } /** - * Creates a new flow layout manager with the indicated alignment - * and the indicated horizontal and vertical gaps. - *

- * The value of the alignment argument must be one of - * WrapLayout, WrapLayout, - * or WrapLayout. - * @param align the alignment value - * @param hgap the horizontal gap between components - * @param vgap the vertical gap between components - */ - public WrapLayout(int align, int hgap, int vgap) - { + * Creates a new flow layout manager with the indicated alignment and the + * indicated horizontal and vertical gaps. + *

+ * The value of the alignment argument must be one of + * WrapLayout, WrapLayout, or + * WrapLayout. + * + * @param align + * the alignment value + * @param hgap + * the horizontal gap between components + * @param vgap + * the vertical gap between components + */ + public WrapLayout(int align, int hgap, int vgap) { super(align, hgap, vgap); } /** - * Returns the preferred dimensions for this layout given the - * visible components in the specified target container. - * @param target the component which needs to be laid out - * @return the preferred dimensions to lay out the - * subcomponents of the specified container - */ + * Returns the preferred dimensions for this layout given the visible + * components in the specified target container. + * + * @param target + * the component which needs to be laid out + * @return the preferred dimensions to lay out the subcomponents of the + * specified container + */ @Override - public Dimension preferredLayoutSize(Container target) - { + public Dimension preferredLayoutSize(Container target) { return layoutSize(target, true); } /** - * Returns the minimum dimensions needed to layout the visible - * components contained in the specified target container. - * @param target the component which needs to be laid out - * @return the minimum dimensions to lay out the - * subcomponents of the specified container - */ + * Returns the minimum dimensions needed to layout the visible + * components contained in the specified target container. + * + * @param target + * the component which needs to be laid out + * @return the minimum dimensions to lay out the subcomponents of the + * specified container + */ @Override - public Dimension minimumLayoutSize(Container target) - { + public Dimension minimumLayoutSize(Container target) { Dimension minimum = layoutSize(target, false); minimum.width -= (getHgap() + 1); return minimum; } /** - * Returns the minimum or preferred dimension needed to layout the target - * container. - * - * @param target target to get layout size for - * @param preferred should preferred size be calculated - * @return the dimension to layout the target container - */ - private Dimension layoutSize(Container target, boolean preferred) - { - synchronized (target.getTreeLock()) - { - // Each row must fit with the width allocated to the containter. - // When the container width = 0, the preferred width of the container - // has not yet been calculated so lets ask for the maximum. + * Returns the minimum or preferred dimension needed to layout the target + * container. + * + * @param target + * target to get layout size for + * @param preferred + * should preferred size be calculated + * @return the dimension to layout the target container + */ + private Dimension layoutSize(Container target, boolean preferred) { + synchronized (target.getTreeLock()) { + // Each row must fit with the width allocated to the containter. + // When the container width = 0, the preferred width of the + // container + // has not yet been calculated so lets ask for the maximum. - int targetWidth = target.getSize().width; - Container container = target; + int targetWidth = target.getSize().width; + Container container = target; - while (container.getSize().width == 0 && container.getParent() != null) - { - container = container.getParent(); - } - - targetWidth = container.getSize().width; - - if (targetWidth == 0) - targetWidth = Integer.MAX_VALUE; - - int hgap = getHgap(); - int vgap = getVgap(); - Insets insets = target.getInsets(); - int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2); - int maxWidth = targetWidth - horizontalInsetsAndGap; - - // Fit components into the allowed width - - Dimension dim = new Dimension(0, 0); - int rowWidth = 0; - int rowHeight = 0; - - int nmembers = target.getComponentCount(); - - for (int i = 0; i < nmembers; i++) - { - Component m = target.getComponent(i); - - if (m.isVisible()) - { - Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize(); - - // Can't add the component to current row. Start a new row. - - if (rowWidth + d.width > maxWidth) - { - addRow(dim, rowWidth, rowHeight); - rowWidth = 0; - rowHeight = 0; - } - - // Add a horizontal gap for all components after the first - - if (rowWidth != 0) - { - rowWidth += hgap; - } - - rowWidth += d.width; - rowHeight = Math.max(rowHeight, d.height); + while (container.getSize().width == 0 + && container.getParent() != null) { + container = container.getParent(); } + + targetWidth = container.getSize().width; + + if (targetWidth == 0) + targetWidth = Integer.MAX_VALUE; + + int hgap = getHgap(); + int vgap = getVgap(); + Insets insets = target.getInsets(); + int horizontalInsetsAndGap = insets.left + insets.right + + (hgap * 2); + int maxWidth = targetWidth - horizontalInsetsAndGap; + + // Fit components into the allowed width + + Dimension dim = new Dimension(0, 0); + int rowWidth = 0; + int rowHeight = 0; + + int nmembers = target.getComponentCount(); + + for (int i = 0; i < nmembers; i++) { + Component m = target.getComponent(i); + + if (m.isVisible()) { + Dimension d = preferred + ? m.getPreferredSize() + : m.getMinimumSize(); + + // Can't add the component to current row. Start a new row. + + if (rowWidth + d.width > maxWidth) { + addRow(dim, rowWidth, rowHeight); + rowWidth = 0; + rowHeight = 0; + } + + // Add a horizontal gap for all components after the first + + if (rowWidth != 0) { + rowWidth += hgap; + } + + rowWidth += d.width; + rowHeight = Math.max(rowHeight, d.height); + } + } + + addRow(dim, rowWidth, rowHeight); + + dim.width += horizontalInsetsAndGap; + dim.height += insets.top + insets.bottom + vgap * 2; + + // When using a scroll pane or the DecoratedLookAndFeel we need to + // make sure the preferred size is less than the size of the + // target containter so shrinking the container size works + // correctly. Removing the horizontal gap is an easy way to do this. + + Container scrollPane = SwingUtilities + .getAncestorOfClass(JScrollPane.class, target); + + if (scrollPane != null && target.isValid()) { + dim.width -= (hgap + 1); + } + + return dim; } - - addRow(dim, rowWidth, rowHeight); - - dim.width += horizontalInsetsAndGap; - dim.height += insets.top + insets.bottom + vgap * 2; - - // When using a scroll pane or the DecoratedLookAndFeel we need to - // make sure the preferred size is less than the size of the - // target containter so shrinking the container size works - // correctly. Removing the horizontal gap is an easy way to do this. - - Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target); - - if (scrollPane != null && target.isValid()) - { - dim.width -= (hgap + 1); - } - - return dim; - } } /* - * A new row has been completed. Use the dimensions of this row - * to update the preferred size for the container. + * A new row has been completed. Use the dimensions of this row to update + * the preferred size for the container. * - * @param dim update the width and height when appropriate - * @param rowWidth the width of the row to add - * @param rowHeight the height of the row to add + * @param dim update the width and height when appropriate + * + * @param rowWidth the width of the row to add + * + * @param rowHeight the height of the row to add */ - private void addRow(Dimension dim, int rowWidth, int rowHeight) - { + private void addRow(Dimension dim, int rowWidth, int rowHeight) { dim.width = Math.max(dim.width, rowWidth); - if (dim.height > 0) - { + if (dim.height > 0) { dim.height += getVgap(); } diff --git a/Guify/src/controllers/DesktopController.java b/Guify/src/controllers/DesktopController.java index ac5161c..e002dd3 100644 --- a/Guify/src/controllers/DesktopController.java +++ b/Guify/src/controllers/DesktopController.java @@ -17,85 +17,81 @@ import java.io.File; import java.util.*; import java.util.List; public class DesktopController { - + /* * ========== BEGIN Attributes ========== */ - + private IDesktopFrame frame; private String currentWorkingDirectory = "~"; private String lastSafeDirectory = null; private List selectedNodes = new ArrayList(); public CutCopyPasteController cutCopyPasteController = new CutCopyPasteController(); - + /* * ========== END Attributes ========== */ - + /* * ========== BEGIN Constructors ========== */ - + public DesktopController() { try { - frame = (IDesktopFrame) JFrameFactory.createJFrame(JFrameFactory.DESKTOP, this); + frame = (IDesktopFrame) JFrameFactory + .createJFrame(JFrameFactory.DESKTOP, this); frame.drawComponentsForDirectory("~"); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - + /* * ========== END Constructors ========== */ - - + /* * ========== BEGIN Getters and Setters ========== */ - + public String getCurrentWorkingDirectory() { return currentWorkingDirectory; } - + public void setCurrentWorkingDirectory(String directory) { - if(directory.equals("~")) { + if (directory.equals("~")) { currentWorkingDirectory = SshEngine.executeCommand("pwd"); - } - else { + } else { currentWorkingDirectory = directory.trim(); } } - + public String getLastSafeDirectory() { return lastSafeDirectory; } - + public void setLastSafeDirectory(String directory) { - - if(directory == null) { + + if (directory == null) { lastSafeDirectory = null; return; } - - if(directory.equals("~")) { + + if (directory.equals("~")) { lastSafeDirectory = SshEngine.executeCommand("pwd"); - } - else { + } else { lastSafeDirectory = directory.trim(); } } - + /* * ========== END Getters and Setters ========== */ - /* * ========== BEGIN Create desktop helper methods ========== */ - + public TreeNode getTree() { final int maxDepth = 3; StringBuilder command = new StringBuilder("tree -Ji -L "); @@ -104,222 +100,233 @@ public class DesktopController { command.append(currentWorkingDirectory); String jsonTree = SshEngine.executeCommand(command.toString()); TreeNode[] tree = null; - + try { // Might throw Invalid JSON exception because of incorrect // JSON output returned from tree: // https://gitlab.com/OldManProgrammer/unix-tree/-/issues/11 - // Fixed in tree 2.1.1 https://gitlab.com/OldManProgrammer/unix-tree/-/commit/84fa3ddff51b30835a0f9c4a9e4c9225970f9aff + // Fixed in tree 2.1.1 + // https://gitlab.com/OldManProgrammer/unix-tree/-/commit/84fa3ddff51b30835a0f9c4a9e4c9225970f9aff // // For this reason, we temporarily explicitly avoid it to happen jsonTree = jsonTree.replace("}{\"error\"", "},{\"error\""); tree = new Gson().fromJson(jsonTree, TreeNode[].class); return tree[0]; - } - catch(Exception ex) { + } catch (Exception ex) { return null; } } - - public Vector getDirectoryElements() throws SftpException { + + public Vector getDirectoryElements() + throws SftpException { return SshEngine.ls(currentWorkingDirectory); } - + /* * ========== END Create desktop helper methods ========== */ - - + /* * ========== BEGIN Download and Upload section ========== */ - + /** * Downloads a file from the remote server to the local machine - * @param sourcePath Remote file's full path - * @param destinationPath Local file's full path + * + * @param sourcePath + * Remote file's full path + * @param destinationPath + * Local file's full path */ public void downloadFile(String sourcePath, String destinationPath) { SshEngine.downloadFile(sourcePath, destinationPath); } - + /** * Uploads files and folders to the remote server + * * @param selectedNodes * @throws SftpException */ - public void uploadToRemoteServer(File[] selectedNodes) throws SftpException { - if (selectedNodes.length > 0) { - List selectedFiles = new ArrayList(); - List selectedDirectories = new ArrayList(); - for (java.io.File file : selectedNodes) { - if(file.isFile()) { - selectedFiles.add(file); - } - else if(file.isDirectory()) { - selectedDirectories.add(file); - } - } - - for(File file : selectedFiles) { - SshEngine.uploadFile(file, this.getCurrentWorkingDirectory()); - } - - - if(selectedDirectories.size() > 0) { - for(File directory : selectedDirectories) { - SshEngine.uploadDirectoriesRecursively(directory, this.getCurrentWorkingDirectory()); - } - } - } + public void uploadToRemoteServer(File[] selectedNodes) + throws SftpException { + if (selectedNodes.length > 0) { + List selectedFiles = new ArrayList(); + List selectedDirectories = new ArrayList(); + for (java.io.File file : selectedNodes) { + if (file.isFile()) { + selectedFiles.add(file); + } else if (file.isDirectory()) { + selectedDirectories.add(file); + } + } + + for (File file : selectedFiles) { + SshEngine.uploadFile(file, this.getCurrentWorkingDirectory()); + } + + if (selectedDirectories.size() > 0) { + for (File directory : selectedDirectories) { + SshEngine.uploadDirectoriesRecursively(directory, + this.getCurrentWorkingDirectory()); + } + } + } } - + /* * ========== END Download and Upload section ========== */ - - + /* * ========== BEGIN Selected Nodes section ========== */ - + public void addSelectedNode(IDirectoryNodeButton node) { selectedNodes.add(node); node.setSelected(true); } - + public void removeSelectedNode(IDirectoryNodeButton node) { selectedNodes.remove(node); node.setSelected(false); } - + public void clearSelectedNodes() { - if(selectedNodes != null) { + if (selectedNodes != null) { Iterator iterator = selectedNodes.iterator(); while (iterator.hasNext()) { - IDirectoryNodeButton node = iterator.next(); - iterator.remove(); - node.setSelected(false); + IDirectoryNodeButton node = iterator.next(); + iterator.remove(); + node.setSelected(false); } } } - + public List getSelectedNodes() { return selectedNodes; } - + public int countSelectedNodes() { return selectedNodes.size(); } - + public void deleteSelectedNodes() throws SftpException { - + List filesToDelete = new ArrayList(); List directoriesToDelete = new ArrayList(); - - for(IDirectoryNodeButton node : selectedNodes) { - if(node.getNode().getAttrs().isDir()) { - directoriesToDelete.add(Helper.combinePath(getCurrentWorkingDirectory(), node.getNode().getFilename()).replace("\"", "\\\"")); - } - else { - filesToDelete.add(Helper.combinePath(getCurrentWorkingDirectory(), node.getNode().getFilename()).replace("\"", "\\\"")); + + for (IDirectoryNodeButton node : selectedNodes) { + if (node.getNode().getAttrs().isDir()) { + directoriesToDelete.add(Helper + .combinePath(getCurrentWorkingDirectory(), + node.getNode().getFilename()) + .replace("\"", "\\\"")); + } else { + filesToDelete.add(Helper + .combinePath(getCurrentWorkingDirectory(), + node.getNode().getFilename()) + .replace("\"", "\\\"")); } } - + SshEngine.rm(filesToDelete); SshEngine.rmdir(directoriesToDelete); clearSelectedNodes(); } - + public void downloadSelectedNodes(String destinationPath) { List directories = new ArrayList(); List files = new ArrayList(); String tmp; - for(IDirectoryNodeButton node : selectedNodes) { - tmp = Helper.combinePath(getCurrentWorkingDirectory(), node.getNode().getFilename()); - if(node.getNode().getAttrs().isDir()) { + for (IDirectoryNodeButton node : selectedNodes) { + tmp = Helper.combinePath(getCurrentWorkingDirectory(), + node.getNode().getFilename()); + if (node.getNode().getAttrs().isDir()) { directories.add(tmp); - } - else { + } else { files.add(tmp); } } - - for(String dir : directories) { + + for (String dir : directories) { SshEngine.downloadDirectoryRecursively(dir, destinationPath); } - - for(String file : files) { + + for (String file : files) { SshEngine.downloadFile(file, destinationPath); } } - + /* * ========== END Selected Nodes section ========== */ - - + /* * ========== BEGIN CutCopyPasteController controller ========== */ - - public class CutCopyPasteController{ + + public class CutCopyPasteController { private List sources = new ArrayList(); private int selectedOperation = Constants.Constants_FSOperations.NONE; - - public void startCopying(List selectedNodes, String currentPath) { + + public void startCopying(List selectedNodes, + String currentPath) { String fullPath = null; - for(IDirectoryNodeButton nodeBtn : selectedNodes) { - fullPath = Helper.combinePath(currentPath, nodeBtn.getNode().getFilename()); + for (IDirectoryNodeButton nodeBtn : selectedNodes) { + fullPath = Helper.combinePath(currentPath, + nodeBtn.getNode().getFilename()); sources.add(fullPath); } selectedOperation = Constants.Constants_FSOperations.COPY; } - - public void startCuttying(List selectedNodes, String currentPath) { + + public void startCuttying(List selectedNodes, + String currentPath) { String fullPath = null; - for(IDirectoryNodeButton nodeBtn : selectedNodes) { - fullPath = Helper.combinePath(currentPath, nodeBtn.getNode().getFilename()); + for (IDirectoryNodeButton nodeBtn : selectedNodes) { + fullPath = Helper.combinePath(currentPath, + nodeBtn.getNode().getFilename()); sources.add(fullPath); } selectedOperation = Constants.Constants_FSOperations.CUT; } - + public void paste(String destination) { StringBuilder command = null; - + // no source - if(sources.size() == 0) { + if (sources.size() == 0) { return; } - + // cannot write on destination // we keep using isWriteable as // the executeCommand() does not fire // an exception in case of fail - if(!isWriteable(destination)) { + if (!isWriteable(destination)) { return; } - + // copy - if(selectedOperation == Constants.Constants_FSOperations.COPY) { + if (selectedOperation == Constants.Constants_FSOperations.COPY) { command = new StringBuilder("cp -r"); } - + // cut - else if(selectedOperation == Constants.Constants_FSOperations.CUT) { + else if (selectedOperation == Constants.Constants_FSOperations.CUT) { command = new StringBuilder("mv"); } - + // invalid command else { return; } - + // execute - for(String path : sources) { + for (String path : sources) { command.append(' '); command.append('"'); command.append(path.replace("\"", "\\\"")); @@ -332,7 +339,7 @@ public class DesktopController { SshEngine.executeCommand(command.toString()); selectedOperation = Constants_FSOperations.NONE; } - + public int getSelectedOperation() { return selectedOperation; } @@ -341,41 +348,47 @@ public class DesktopController { /* * ========== END CutCopyPasteController controller ========== */ - - + /* * ========== BEGIN File System Operations ========== */ - - + /** * Creates a new folder - * @param newFolderPath Folder's path - * @throws SftpException + * + * @param newFolderPath + * Folder's path + * @throws SftpException */ public void mkdir(String newFolderPath) throws SftpException { SshEngine.mkdir(newFolderPath); } - + /** * Creates a file in the remote file path - * @param remoteFilePath remote file path - * @throws SftpException + * + * @param remoteFilePath + * remote file path + * @throws SftpException */ public void touch(String remoteFilePath) throws SftpException { SshEngine.touch(remoteFilePath); } - + /** * Renames a file - * @param oldNamePath Path of the old name - * @param newNamePath Path of the new name + * + * @param oldNamePath + * Path of the old name + * @param newNamePath + * Path of the new name * @throws SftpException */ - public void rename(String oldNamePath, String newNamePath) throws SftpException { + public void rename(String oldNamePath, String newNamePath) + throws SftpException { SshEngine.rename(oldNamePath, newNamePath); } - + /* * ========== END File System Operations ========== */ @@ -383,63 +396,66 @@ public class DesktopController { /* * ========== BEGIN Other ========== */ - + /** * Given a remote file path, opens a graphical notepad for it - * @param filePath remote file path to display in the notepad + * + * @param filePath + * remote file path to display in the notepad */ public void openNotepadForFile(String filePath) { new NotepadController(filePath).show(); } - + /** - * Disposes resources which need to be freed before exiting - * the application + * Disposes resources which need to be freed before exiting the application */ public void disposeResources() { SshEngine.disconnectSession(); } /** - * @deprecated This method is deprecated. - * Catch SftpException - * and look for "Permission denied" instead. This prevents - * unnecessary overhead + * @deprecated This method is deprecated. Catch SftpException and look for + * "Permission denied" instead. This prevents unnecessary + * overhead */ public boolean isReadable(String path) { StringBuilder command = new StringBuilder(); command.append("[ -r \""); - command.append(path.equals("~") ? SshEngine.executeCommand("pwd").replace("\"", "\\\"") : path.replace("\"", "\\\"")); + command.append(path.equals("~") + ? SshEngine.executeCommand("pwd").replace("\"", "\\\"") + : path.replace("\"", "\\\"")); command.append("\" ] && echo 1 || echo 0"); // short circuiting return SshEngine.executeCommand(command.toString()).trim().equals("1"); } - + /** - * @deprecated This method is deprecated. - * Catch SftpException - * and look for "Permission denied" instead + * @deprecated This method is deprecated. Catch SftpException and look for + * "Permission denied" instead */ public boolean isWriteable(String path) { StringBuilder command = new StringBuilder(); command.append("[ -w \""); - command.append(path.equals("~") ? SshEngine.executeCommand("pwd").replace("\"", "\\\"") : path.replace("\"", "\\\"")); + command.append(path.equals("~") + ? SshEngine.executeCommand("pwd").replace("\"", "\\\"") + : path.replace("\"", "\\\"")); command.append("\" ] && echo 1 || echo 0"); // short circuiting return SshEngine.executeCommand(command.toString()).trim().equals("1"); } - + public void showFrame(boolean show) { frame.setVisible(show); } - + public String getTitle() { StringBuilder title = new StringBuilder(Constants.APP_NAME); title.append(" - "); title.append(LoginCredentials.host); return title.toString(); } - + /* * ========== END Other ========== */ - + } diff --git a/Guify/src/controllers/FindAndReplaceController.java b/Guify/src/controllers/FindAndReplaceController.java index 65b4926..075a894 100644 --- a/Guify/src/controllers/FindAndReplaceController.java +++ b/Guify/src/controllers/FindAndReplaceController.java @@ -9,78 +9,82 @@ public class FindAndReplaceController { private IGenericTextArea textArea; private IFindAndReplaceFrame frame; - + public FindAndReplaceController(IGenericTextArea textArea) { this.textArea = textArea; try { - frame = (IFindAndReplaceFrame) JFrameFactory.createJFrame(IFrameFactory.FIND_AND_REPLACE, this); + frame = (IFindAndReplaceFrame) JFrameFactory + .createJFrame(IFrameFactory.FIND_AND_REPLACE, this); } catch (Exception e) { e.printStackTrace(); } } - + /** * Show frame centered to parent */ public void showAtTheCenterOfFrame(INotepadFrame notepadFrame) { - int childX = notepadFrame.getX() + (notepadFrame.getWidth() - frame.getWidth()) / 2; - int childY = notepadFrame.getY() + (notepadFrame.getHeight() - frame.getHeight()) / 2; - frame.setLocation(childX, childY); + int childX = notepadFrame.getX() + + (notepadFrame.getWidth() - frame.getWidth()) / 2; + int childY = notepadFrame.getY() + + (notepadFrame.getHeight() - frame.getHeight()) / 2; + frame.setLocation(childX, childY); frame.setVisible(true); } - - public int findNext(String searchText) { - String text = textArea.getText(); - int currentIndex = textArea.getCaretPosition(); - int nextIndex = text.indexOf(searchText, currentIndex); - if (nextIndex != -1) { - textArea.selectText(nextIndex, nextIndex + searchText.length()); - return nextIndex; - } - return -1; + public int findNext(String searchText) { + String text = textArea.getText(); + int currentIndex = textArea.getCaretPosition(); + int nextIndex = text.indexOf(searchText, currentIndex); + + if (nextIndex != -1) { + textArea.selectText(nextIndex, nextIndex + searchText.length()); + return nextIndex; + } + return -1; } - + public int findPrevious(String searchText) { - String text = textArea.getText(); - int cutAt; - - if(textArea.hasHighlightedText()) { - cutAt = textArea.getSelectionStart(); - } - else { - cutAt = textArea.getCaretPosition(); - } - String firstPart = text.substring(0, cutAt); - int previousIndex = firstPart.lastIndexOf(searchText, firstPart.length() - 1); - if (previousIndex != -1) { - textArea.selectText(previousIndex, previousIndex + searchText.length()); - return previousIndex; - } - else { - return -1; - } + String text = textArea.getText(); + int cutAt; + + if (textArea.hasHighlightedText()) { + cutAt = textArea.getSelectionStart(); + } else { + cutAt = textArea.getCaretPosition(); + } + String firstPart = text.substring(0, cutAt); + int previousIndex = firstPart.lastIndexOf(searchText, + firstPart.length() - 1); + if (previousIndex != -1) { + textArea.selectText(previousIndex, + previousIndex + searchText.length()); + return previousIndex; + } else { + return -1; + } } - + public int replaceNext(String toReplace, String replaceWith) { int index = findNext(toReplace); - - if(index != -1) { - textArea.replaceRange(replaceWith, index, index + toReplace.length()); + + if (index != -1) { + textArea.replaceRange(replaceWith, index, + index + toReplace.length()); } - + return index; } - + public void replaceAll(String searchText, String replacement) { - String text = textArea.getText(); - text = text.replaceAll(searchText, replacement); - textArea.setText(text); + String text = textArea.getText(); + text = text.replaceAll(searchText, replacement); + textArea.setText(text); } - + public void disposeMyFrame() { - if(frame != null) { - frame.dispose(); + if (frame != null) { + frame.dispose(); } } } diff --git a/Guify/src/controllers/LoginController.java b/Guify/src/controllers/LoginController.java index 12423ba..2b50221 100644 --- a/Guify/src/controllers/LoginController.java +++ b/Guify/src/controllers/LoginController.java @@ -10,65 +10,65 @@ import code.GuiAbstractions.Interfaces.IFrameFactory; import views.interfaces.ILoginFrame; public class LoginController { - + private ILoginFrame frame; - + public LoginController() { try { - frame = (ILoginFrame) JFrameFactory.createJFrame(IFrameFactory.LOGIN, this); - } - catch (Exception e) { + frame = (ILoginFrame) JFrameFactory + .createJFrame(IFrameFactory.LOGIN, this); + } catch (Exception e) { e.printStackTrace(); } } - - public boolean Login(String host, String username, String password, String port) throws IllegalArgumentException { + + public boolean Login(String host, String username, String password, + String port) throws IllegalArgumentException { LoginCredentials.host = host; LoginCredentials.username = username; LoginCredentials.password = password; LoginCredentials.port = Integer.parseInt(port); - + if (SshEngine.connetion()) { frame.setVisible(false); new DesktopController().showFrame(true);; return true; - } - else { + } else { return false; } } - - public void ValidateInput(String host, String username, String password, String port) throws IllegalArgumentException { - + + public void ValidateInput(String host, String username, String password, + String port) throws IllegalArgumentException { + // Host Validation. Consider its necessity. try { InetAddress.getByName(host); } catch (UnknownHostException ex) { throw new IllegalArgumentException("Host could not be found", ex); } - + // Port Validation try { Integer.parseInt(port); - } - catch(NumberFormatException ex) { + } catch (NumberFormatException ex) { throw new IllegalArgumentException("Invalid port number", ex); - } + } } - + public void showFrame(boolean show) { frame.setVisible(show); } - + public String getTitle() { return Constants.APP_NAME + " " + Constants.VERSION; } - - public static class LoginCredentials{ + + public static class LoginCredentials { public static String host; public static String username; public static String password; public static int port; } - + } diff --git a/Guify/src/controllers/NotepadController.java b/Guify/src/controllers/NotepadController.java index ca57941..ecbf1c1 100644 --- a/Guify/src/controllers/NotepadController.java +++ b/Guify/src/controllers/NotepadController.java @@ -6,13 +6,13 @@ import code.GuiAbstractions.Interfaces.IFrameFactory; import code.GuiAbstractions.Interfaces.IGenericTextArea; import views.interfaces.INotepadFrame; public class NotepadController { - + private String filePath = null; private INotepadFrame notepadFrame = null; private FindAndReplaceController myFindAndReplaceController; private boolean unsaved = false; private String initialText = null; - + public boolean isUnsaved() { return unsaved; } @@ -24,40 +24,41 @@ public class NotepadController { public String getFilePath() { return this.filePath; } - + public String getInitialText() { return this.initialText; } - + public NotepadController(String filePath) { this.filePath = filePath; initialText = SshEngine.readFile(filePath); try { - notepadFrame = (INotepadFrame) JFrameFactory.createJFrame(IFrameFactory.NOTEPAD, this); + notepadFrame = (INotepadFrame) JFrameFactory + .createJFrame(IFrameFactory.NOTEPAD, this); } catch (Exception e) { e.printStackTrace(); return; } } - + public void show() { notepadFrame.setVisible(true); } - + public void writeOnFile(String text) { SshEngine.writeFile(text, this.filePath); } - + public void showFindAndReplace(IGenericTextArea textArea) { myFindAndReplaceController = new FindAndReplaceController(textArea); myFindAndReplaceController.showAtTheCenterOfFrame(notepadFrame); } - + public void disposeFindAndReplaceFrame() { - if(myFindAndReplaceController != null) + if (myFindAndReplaceController != null) myFindAndReplaceController.disposeMyFrame(); } - + public String getTitle() { return filePath + (unsaved ? " - UNSAVED" : ""); } diff --git a/Guify/src/controllers/QueueController.java b/Guify/src/controllers/QueueController.java index 5523c6c..85a6fa4 100644 --- a/Guify/src/controllers/QueueController.java +++ b/Guify/src/controllers/QueueController.java @@ -11,70 +11,84 @@ import views.interfaces.IQueueFrame; import java.util.HashMap; @SuppressWarnings("deprecation") // Observer - Observable are okay here -public class QueueController implements Observer{ - +public class QueueController implements Observer { + /* * ========== BEGIN Attributes ========== */ - + private IQueueFrame frame; // Accessed only through the EDT, so no need to use ConcurrentHashMap private HashMap indexHashMap = new HashMap<>(); private long lastGuiExecutionTime = 0; private static final long THROTTLE_TIME_MS = 10; // 10ms = 1/100th of second - + /* * ========== END Attributes ========== */ - + // Executed by the EDT public QueueController() { try { - frame = (IQueueFrame) JFrameFactory.createJFrame(IFrameFactory.QUEUE, this); - } - catch (Exception e) {} - + frame = (IQueueFrame) JFrameFactory + .createJFrame(IFrameFactory.QUEUE, this); + } catch (Exception e) { + } + // Register observer of the changes QueueEventManager.getInstance().addObserver(this); - - // Get previous enqueued elements. Do not place before addObserver(this) or some + + // Get previous enqueued elements. Do not place before addObserver(this) + // or some // transfers could go lost. // - // A necessary but not sufficient condition in order to claim that the Queue - // works well, is that when it gets opened at time x, all the non-finished + // A necessary but not sufficient condition in order to claim that the + // Queue + // works well, is that when it gets opened at time x, all the + // non-finished // transfers initiated in a time t such that t < x must be shown // in the table. - // More specifically, x represents the time of completion of the instruction - // QueueEventManager.getInstance().addObserver(this); as - // any subsequent transfer initiated after this point will be guaranteed to + // More specifically, x represents the time of completion of the + // instruction + // QueueEventManager.getInstance().addObserver(this); as + // any subsequent transfer initiated after this point will be guaranteed + // to // be shown in the table (handled by the "update()" method). // - // Having understood this, we may now suppose t1 to be the time of completion of the + // Having understood this, we may now suppose t1 to be the time of + // completion of the // instruction QueueEventManager.getInstance().getQueue() and t2 to be // the time of completion of the instruction // QueueEventManager.getInstance().addObserver(this) where t1 < t2. // This would've meant that any transfer initiated in a time t such that - // t1 < t < t2 would not have been adequately processed as "getQueue()" was - // already executed, and "addObserver(this)" would not have been performed yet, - // making the transfer not visible in the queue when the Queue frame would've + // t1 < t < t2 would not have been adequately processed as "getQueue()" + // was + // already executed, and "addObserver(this)" would not have been + // performed yet, + // making the transfer not visible in the queue when the Queue frame + // would've // been opened. // - // One could argue that when any chunk of data is transferred at any time t - // where t > t2, the update() method will be called, showing the transfer in - // the queue. It's not guaranteed that this happens (as it may encounter an - // error before t2 and after t1 or simply in may complete in this time frame) - + // One could argue that when any chunk of data is transferred at any + // time t + // where t > t2, the update() method will be called, showing the + // transfer in + // the queue. It's not guaranteed that this happens (as it may encounter + // an + // error before t2 and after t1 or simply in may complete in this time + // frame) + TransferProgress[] queued = QueueEventManager.getInstance().getQueue(); - for(TransferProgress transferProgress : queued) { + for (TransferProgress transferProgress : queued) { SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - frame.manageTransferProgress(transferProgress); - } + @Override + public void run() { + frame.manageTransferProgress(transferProgress); + } }); } } - + // Executed on different threads. Called by notifyObservers in // QueueEventManager in turn called // by the threads created in SshEngine. @@ -83,8 +97,9 @@ public class QueueController implements Observer{ // For all distinct pairs of calls on the method update(o, arg) // denoted as (update(o, arg)_1 , update(o, arg)_2) having the same // object "arg", it holds that - // ((TransferProgress)arg).getTransferredBytes() evaluated during - // update(o, arg)_1 is less or equal than ((TransferProgress)arg).getTransferredBytes() + // ((TransferProgress)arg).getTransferredBytes() evaluated during + // update(o, arg)_1 is less or equal than + // ((TransferProgress)arg).getTransferredBytes() // evaluated during update(o, arg)_2. // In simple words, if update() is called at time t1 and at time t2, // where arg is the same TransferProgress object, then the second time @@ -93,7 +108,8 @@ public class QueueController implements Observer{ // than the value of // transferProgress.getTransferredBytes() evaluated the first time. // This happens as the transfer of a single object is an operation executed - // on a single thread, hence any update will have a getTransferredBytes() greater + // on a single thread, hence any update will have a getTransferredBytes() + // greater // or equal than the previous one. // // Keep also in mind that SwingUtilities.invokeLater() called at time t1 @@ -107,78 +123,94 @@ public class QueueController implements Observer{ // will go down (e.g. from 50% to 49%), but this would be true even if // the concept described above would be false. This happens because // the TransferProgress - // handled by manageTransferProgress will always have the latest updated values + // handled by manageTransferProgress will always have the latest updated + // values // for that specific object, as it is shared with the thread - // which continuously updates it. + // which continuously updates it. // We do not need any locks as no race conditions - // can happen because in the EDT thread we only read said object, nor any + // can happen because in the EDT thread we only read said object, nor any // inconsistencies can arise. - // For more information you can view the comments at Queue@manageTransferProgress + // For more information you can view the comments at + // Queue@manageTransferProgress @Override public void update(Observable o, Object arg) { - TransferProgress transferProgress = (TransferProgress)arg; - + TransferProgress transferProgress = (TransferProgress) arg; + // Do not invoke the Event Dispatch Thread too frequently as // it may impact the performance of low-end computer systems. - if(System.currentTimeMillis() - lastGuiExecutionTime >= THROTTLE_TIME_MS || - transferProgress.getTransferStatus() == TransferProgress.END) { + if (System.currentTimeMillis() + - lastGuiExecutionTime >= THROTTLE_TIME_MS + || transferProgress + .getTransferStatus() == TransferProgress.END) { SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - frame.manageTransferProgress(transferProgress); - lastGuiExecutionTime = System.currentTimeMillis(); - } + @Override + public void run() { + frame.manageTransferProgress(transferProgress); + lastGuiExecutionTime = System.currentTimeMillis(); + } }); } } - + /** * Computes the transfer completion percentage - * @param transferProgress A transferProgress object - * @return A value in the range [0, 100] indicating - * the transfer completion percentage + * + * @param transferProgress + * A transferProgress object + * @return A value in the range [0, 100] indicating the transfer completion + * percentage */ public int computePercentage(TransferProgress transferProgress) { // Avoid division by zero - if(transferProgress.getTotalBytes() == 0) { - // The percentage is 100% if ∀ byte in the file, byte was transferred. - // If there are no bytes in the file, this logic proposition holds true (vacuous truth) + if (transferProgress.getTotalBytes() == 0) { + // The percentage is 100% if ∀ byte in the file, byte was + // transferred. + // If there are no bytes in the file, this logic proposition holds + // true (vacuous truth) return 100; - } - else { - return (int) Math.round( ((transferProgress.getTransferredBytes() * 100F) / transferProgress.getTotalBytes()) ); + } else { + return (int) Math + .round(((transferProgress.getTransferredBytes() * 100F) + / transferProgress.getTotalBytes())); } } - + /** * Given a TransferProgress object, retrieve its index + * * @param transferProgress * @return Its index or null if not present */ public Integer getTableIndex(TransferProgress transferProgress) { return indexHashMap.get(transferProgress); } - + /** * Put index in the HashMap - * @param transferProgress TransferProgress object - * @param index An integer value representing the index + * + * @param transferProgress + * TransferProgress object + * @param index + * An integer value representing the index */ - public void putTableIndex(TransferProgress transferProgress, Integer index) { + public void putTableIndex(TransferProgress transferProgress, + Integer index) { indexHashMap.put(transferProgress, index); } - + /** - * Checks if a specific TransferProgress is contained in - * the HashMap - * @param transferProgress A TransferProgress object + * Checks if a specific TransferProgress is contained in the HashMap + * + * @param transferProgress + * A TransferProgress object * @return true if present, false otherwise */ - public boolean isTransferProgressInHashMap(TransferProgress transferProgress) { + public boolean isTransferProgressInHashMap( + TransferProgress transferProgress) { return getTableIndex(transferProgress) != null; } - + public void showFrame(boolean visible) { frame.setVisible(visible); - } + } } diff --git a/Guify/src/views/Desktop.java b/Guify/src/views/Desktop.java index ed3e719..4cc1e90 100644 --- a/Guify/src/views/Desktop.java +++ b/Guify/src/views/Desktop.java @@ -59,7 +59,7 @@ public class Desktop extends JFrame implements IDesktopFrame { /* * ========== BEGIN Attributes ========== */ - + private static final long serialVersionUID = 1L; private DesktopController controller; private JTree tree; @@ -73,59 +73,59 @@ public class Desktop extends JFrame implements IDesktopFrame { private JButton deleteBtn; private JButton downloadBtn; private JTextField pathTextBox; - + /* * ========== END Attributes ========== */ - - + /* * ========== BEGIN Constructors ========== */ - + public Desktop(Object controller) { this.controller = (DesktopController) controller; - - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setTitle(this.controller.getTitle()); - getContentPane().setLayout(new BorderLayout()); - - treePanel = new JScrollPane(); - // You can adjust the preferred size as needed - treePanel.setPreferredSize(new Dimension(150, 634)); - getContentPane().add(treePanel, BorderLayout.WEST); - desktopPanel = new JPanel(); - desktopPanel.setLayout(new WrapLayout(FlowLayout.LEFT, 5, 5)); - desktopPanel.setBackground(Color.WHITE); - desktopPanel.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - unselectAllNodes(); - desktopPanel.requestFocus(); - } - }); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setTitle(this.controller.getTitle()); + getContentPane().setLayout(new BorderLayout()); - JScrollPane scrollPane = new JScrollPane(desktopPanel); - scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - scrollPane.getVerticalScrollBar().setUnitIncrement(25); - getContentPane().add(scrollPane, BorderLayout.CENTER); + treePanel = new JScrollPane(); + // You can adjust the preferred size as needed + treePanel.setPreferredSize(new Dimension(150, 634)); + getContentPane().add(treePanel, BorderLayout.WEST); - toolBar = new JToolBar(); - toolBar.setFloatable(false); - toolBar.setBackground(GuifyColors.GRAY); - createJToolBar(); - getContentPane().add(toolBar, BorderLayout.NORTH); + desktopPanel = new JPanel(); + desktopPanel.setLayout(new WrapLayout(FlowLayout.LEFT, 5, 5)); + desktopPanel.setBackground(Color.WHITE); + desktopPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + unselectAllNodes(); + desktopPanel.requestFocus(); + } + }); + + JScrollPane scrollPane = new JScrollPane(desktopPanel); + scrollPane.setHorizontalScrollBarPolicy( + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.getVerticalScrollBar().setUnitIncrement(25); + getContentPane().add(scrollPane, BorderLayout.CENTER); + + toolBar = new JToolBar(); + toolBar.setFloatable(false); + toolBar.setBackground(GuifyColors.GRAY); + createJToolBar(); + getContentPane().add(toolBar, BorderLayout.NORTH); setSize(1280, 720); setLocationRelativeTo(null); - + addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - ((DesktopController) controller).disposeResources(); - } - }); - + @Override + public void windowClosing(WindowEvent e) { + ((DesktopController) controller).disposeResources(); + } + }); + // Create drag and drop handler new DropTarget(desktopPanel, new DropTargetListener() { @@ -145,46 +145,58 @@ public class Desktop extends JFrame implements IDesktopFrame { @Override public void dragExit(DropTargetEvent dte) { desktopPanel.setBorder(null); - + } @Override public void drop(DropTargetDropEvent dtde) { dtde.acceptDrop(dtde.getDropAction()); Transferable data = dtde.getTransferable(); - if (data.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + if (data.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { try { - File[] droppedFileArray = ((Collection)(data.getTransferData(DataFlavor.javaFileListFlavor))).toArray(new File[((Collection)(data.getTransferData(DataFlavor.javaFileListFlavor))).size()]); + File[] droppedFileArray = ((Collection) (data + .getTransferData( + DataFlavor.javaFileListFlavor))) + .toArray(new File[((Collection) (data + .getTransferData( + DataFlavor.javaFileListFlavor))) + .size()]); try { - ((DesktopController)controller).uploadToRemoteServer(droppedFileArray); - drawComponentsForDirectory(((DesktopController)controller).getCurrentWorkingDirectory()); + ((DesktopController) controller) + .uploadToRemoteServer(droppedFileArray); + drawComponentsForDirectory( + ((DesktopController) controller) + .getCurrentWorkingDirectory()); } catch (SftpException e) { if (e.getMessage().contains("Permission denied")) { - JOptionPane.showMessageDialog(new JFrame(), "Permission denied", "Permission denied", JOptionPane.ERROR_MESSAGE); - return; - } + JOptionPane.showMessageDialog(new JFrame(), + "Permission denied", + "Permission denied", + JOptionPane.ERROR_MESSAGE); + return; + } } } catch (UnsupportedFlavorException | IOException e) { e.printStackTrace(); } - } - dtde.dropComplete(true); - desktopPanel.setBorder(null); - }}); + } + dtde.dropComplete(true); + desktopPanel.setBorder(null); + } + }); } /* * ========== END Constructors ========== */ - - + /* * ========== BEGIN Frame Drawing ========== */ /** - * Draws all the components which need to be drew for a specific - * directory + * Draws all the components which need to be drew for a specific directory + * * @param directory */ public void drawComponentsForDirectory(String directory) { @@ -195,57 +207,67 @@ public class Desktop extends JFrame implements IDesktopFrame { pathTextBox.setText(controller.getCurrentWorkingDirectory()); loadTree(); loadDesktop(); - }catch(Exception ex) { - if(controller.getLastSafeDirectory() == null) { + } catch (Exception ex) { + if (controller.getLastSafeDirectory() == null) { System.exit(ERROR); - } - else { + } else { drawComponentsForDirectory(controller.getLastSafeDirectory()); - controller.setLastSafeDirectory(null); // Prevents infinite re-tries + controller.setLastSafeDirectory(null); // Prevents infinite + // re-tries return; } } controller.setLastSafeDirectory(directory); - + repaint(); revalidate(); } - - /** - * Loads the desktop view - * @throws SftpException - */ + + /** + * Loads the desktop view + * + * @throws SftpException + */ private void loadDesktop() throws SftpException { desktopPanel.removeAll(); - + Image folderIcon = null; Image fileIcon = null; try { - folderIcon = ImageIO.read(getClass().getClassLoader().getResource("folder_icon.png")).getScaledInstance(32, 32, Image.SCALE_DEFAULT); - fileIcon = ImageIO.read(getClass().getClassLoader().getResource("file_icon.png")).getScaledInstance(32, 32, Image.SCALE_DEFAULT); - } catch (IOException e1) {} - + folderIcon = ImageIO + .read(getClass().getClassLoader() + .getResource("folder_icon.png")) + .getScaledInstance(32, 32, Image.SCALE_DEFAULT); + fileIcon = ImageIO + .read(getClass().getClassLoader() + .getResource("file_icon.png")) + .getScaledInstance(32, 32, Image.SCALE_DEFAULT); + } catch (IOException e1) { + } + Vector elementsToDisplay = null; try { elementsToDisplay = controller.getDirectoryElements(); - if(elementsToDisplay == null) { + if (elementsToDisplay == null) { return; } } catch (SftpException e) { if (e.getMessage().contains("Permission denied")) { - JOptionPane.showMessageDialog(new JFrame(), "Permission denied", "Permission denied", JOptionPane.ERROR_MESSAGE); - throw e; - } + JOptionPane.showMessageDialog(new JFrame(), "Permission denied", + "Permission denied", JOptionPane.ERROR_MESSAGE); + throw e; + } } - - for(LsEntry node : elementsToDisplay) { - ImageIcon icon = new ImageIcon( node.getAttrs().isDir()? folderIcon : fileIcon ); + + for (LsEntry node : elementsToDisplay) { + ImageIcon icon = new ImageIcon( + node.getAttrs().isDir() ? folderIcon : fileIcon); JDirectoryNodeButton element = new JDirectoryNodeButton(node); JLabel iconLabel = new JLabel(icon); iconLabel.setVerticalTextPosition(JLabel.BOTTOM); - iconLabel.setHorizontalTextPosition(JLabel.CENTER); - iconLabel.setText(node.getFilename()); - element.add(iconLabel); + iconLabel.setHorizontalTextPosition(JLabel.CENTER); + iconLabel.setText(node.getFilename()); + element.add(iconLabel); element.setBackground(new Color(255, 255, 255)); element.setToolTipText(node.getFilename()); int buttonWidth = 75; @@ -255,157 +277,166 @@ public class Desktop extends JFrame implements IDesktopFrame { element.setMaximumSize(buttonSize); element.setMinimumSize(buttonSize); element.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e){ - desktopElementClick(e); - } + @Override + public void mouseClicked(MouseEvent e) { + desktopElementClick(e); + } }); desktopPanel.add(element); } } - + /** - * Specifies the action to take upon a click on the element - * of a desktop - * @param e A MouseEvent + * Specifies the action to take upon a click on the element of a desktop + * + * @param e + * A MouseEvent */ private void desktopElementClick(MouseEvent e) { JDirectoryNodeButton sender = (JDirectoryNodeButton) e.getSource(); - - // Move into directory - if(e.getClickCount() == 2){ - ImageIcon questionMarkIcon = null; - try { - questionMarkIcon = new ImageIcon( - ImageIO.read(getClass().getClassLoader().getResource("question_mark.png")).getScaledInstance(32, 32, Image.SCALE_SMOOTH)); - } - catch (IOException e1) {} - - // Double click on a directory - if(sender.node.getAttrs().isDir()) { - String newDirectory = Helper.combinePath(controller.getCurrentWorkingDirectory(), sender.node.getFilename()); - drawComponentsForDirectory(newDirectory); - } - - // Double click on a file - else { - String filePath = Helper.combinePath(controller.getCurrentWorkingDirectory(), sender.node.getFilename()); - Object[] options = {"Download", "View", "Cancel"}; - int choice = JOptionPane.showOptionDialog(null, - "What would you like to do with this file?", - Constants.APP_NAME, - JOptionPane.YES_NO_CANCEL_OPTION, - JOptionPane.QUESTION_MESSAGE, - questionMarkIcon, - options, - options[0]); - - switch(choice) { - - // Download - case 0: - - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - int choiceFileChooser = fileChooser.showDialog(this, "Save here"); - - if (choiceFileChooser == JFileChooser.APPROVE_OPTION) { - controller.downloadFile(filePath, fileChooser.getSelectedFile().toString()); - } - break; - - // View - case 1: - controller.openNotepadForFile(filePath); - break; - - // Cancel - case 2: - return; - } - - } - } - + // Move into directory + if (e.getClickCount() == 2) { + ImageIcon questionMarkIcon = null; + try { + questionMarkIcon = new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("question_mark.png")) + .getScaledInstance(32, 32, Image.SCALE_SMOOTH)); + } catch (IOException e1) { + } + + // Double click on a directory + if (sender.node.getAttrs().isDir()) { + String newDirectory = Helper.combinePath( + controller.getCurrentWorkingDirectory(), + sender.node.getFilename()); + drawComponentsForDirectory(newDirectory); + } + + // Double click on a file + else { + String filePath = Helper.combinePath( + controller.getCurrentWorkingDirectory(), + sender.node.getFilename()); + Object[] options = {"Download", "View", "Cancel"}; + + int choice = JOptionPane.showOptionDialog(null, + "What would you like to do with this file?", + Constants.APP_NAME, JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE, questionMarkIcon, options, + options[0]); + + switch (choice) { + + // Download + case 0 : + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileSelectionMode( + JFileChooser.DIRECTORIES_ONLY); + int choiceFileChooser = fileChooser.showDialog(this, + "Save here"); + + if (choiceFileChooser == JFileChooser.APPROVE_OPTION) { + controller.downloadFile(filePath, + fileChooser.getSelectedFile().toString()); + } + break; + + // View + case 1 : + controller.openNotepadForFile(filePath); + break; + + // Cancel + case 2 : + return; + } + + } + } + // Select a node - else if(e.getClickCount() == 1) { - - boolean isControlDown = (e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0; - + else if (e.getClickCount() == 1) { + + boolean isControlDown = (e.getModifiersEx() + & InputEvent.CTRL_DOWN_MASK) != 0; + // If already selected, unselect - if(sender.getSelected()) { - if(!isControlDown) { - unselectNode(sender); + if (sender.getSelected()) { + if (!isControlDown) { + unselectNode(sender); } } - + // If not selected, select else { - if(!isControlDown) { + if (!isControlDown) { // Unselect all the other components unselectAllNodes(); } - + // Select the current component selectNode(sender); - } + } } } - + /** - * Loads the file system tree seen - * on the left + * Loads the file system tree seen on the left */ private void loadTree() { TreeNode root = this.controller.getTree(); DefaultTreeModel model = new DefaultTreeModel(loadTreeAux(root), true); tree = new JTree(model); - + // Click on the tree. Open directory if directory is clicked, // do nothing otherwise. tree.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - TreePath path = tree.getPathForLocation(e.getX(), e.getY()); - if (path != null) { - DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); - if(node.getAllowsChildren()) { // is a directory - String fullPath = getFullPathFromTreeNode(node); - drawComponentsForDirectory(fullPath); - } - else { - // Do nothing. Probably a "What to do?" prompt would - // be nice - } - } - } - } - }); + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + TreePath path = tree.getPathForLocation(e.getX(), e.getY()); + if (path != null) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) path + .getLastPathComponent(); + if (node.getAllowsChildren()) { // is a directory + String fullPath = getFullPathFromTreeNode(node); + drawComponentsForDirectory(fullPath); + } else { + // Do nothing. Probably a "What to do?" prompt would + // be nice + } + } + } + } + }); treePanel.setViewportView(tree); } - + /** - * Auxiliary function which recursively - * creates a tree given its root - * @param node A TreeNode element - * @return A DefaultMutableTreeNode element representing the root - * of the created tree + * Auxiliary function which recursively creates a tree given its root + * + * @param node + * A TreeNode element + * @return A DefaultMutableTreeNode element representing the root of the + * created tree */ private DefaultMutableTreeNode loadTreeAux(TreeNode node) { - - if(node == null) - return null; - - if(node.error != null) - return null; - - DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(node.name, node.type.equals("directory")); - if(node.contents != null) { - for(TreeNode child : node.contents) { - DefaultMutableTreeNode descendants = loadTreeAux(child); - if(descendants != null) { + if (node == null) + return null; + + if (node.error != null) + return null; + + DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(node.name, + node.type.equals("directory")); + + if (node.contents != null) { + for (TreeNode child : node.contents) { + DefaultMutableTreeNode descendants = loadTreeAux(child); + if (descendants != null) { treeNode.add(descendants); } } @@ -413,480 +444,554 @@ public class Desktop extends JFrame implements IDesktopFrame { return treeNode; } - + /** - * Retrieves the full path in the file system of a specified - * tree node - * @param node A DefaultMutableTreeNode element + * Retrieves the full path in the file system of a specified tree node + * + * @param node + * A DefaultMutableTreeNode element * @return Full path of the node */ - private String getFullPathFromTreeNode(DefaultMutableTreeNode node) { - javax.swing.tree.TreeNode[] path = node.getPath(); - StringBuilder fullPath = new StringBuilder(); - for (int i = 0; i < path.length; i++) { - Object userObject = ((DefaultMutableTreeNode) path[i]).getUserObject(); - fullPath.append(userObject.toString()); - if (i != path.length - 1) { - fullPath.append("/"); - } - } - return fullPath.toString(); - } - + private String getFullPathFromTreeNode(DefaultMutableTreeNode node) { + javax.swing.tree.TreeNode[] path = node.getPath(); + StringBuilder fullPath = new StringBuilder(); + for (int i = 0; i < path.length; i++) { + Object userObject = ((DefaultMutableTreeNode) path[i]) + .getUserObject(); + fullPath.append(userObject.toString()); + if (i != path.length - 1) { + fullPath.append("/"); + } + } + return fullPath.toString(); + } + /** * Creates the tool bar */ private void createJToolBar() { JButton backBtn = new JButton(); - + backBtn.setBorderPainted(false); backBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border; backBtn.setToolTipText("Back"); try { - backBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("back_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + backBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("back_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); backBtn.setBorderPainted(false); - }catch(IOException ex) { + } catch (IOException ex) { backBtn.setText("Back"); } backBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - if(controller.getCurrentWorkingDirectory().equals("/")) { + if (controller.getCurrentWorkingDirectory().equals("/")) { return; } - String parentPath = Helper.getParentPath(controller.getCurrentWorkingDirectory()); + String parentPath = Helper + .getParentPath(controller.getCurrentWorkingDirectory()); drawComponentsForDirectory(parentPath); } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(backBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (backBtn.isEnabled()) backBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { backBtn.setBackground(GuifyColors.GRAY); - } + } }); - + cutBtn = new JButton(); cutBtn.setBorderPainted(false); cutBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border; cutBtn.setToolTipText("Cut"); try { - cutBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("cut_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + cutBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("cut_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); cutBtn.setBackground(GuifyColors.GRAY); cutBtn.setBorderPainted(false); cutBtn.setEnabled(false); - }catch(IOException ex) { + } catch (IOException ex) { cutBtn.setText("Cut"); } cutBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - if(cutBtn.isEnabled()) { - controller.cutCopyPasteController.startCuttying(controller.getSelectedNodes(), controller.getCurrentWorkingDirectory()); + if (cutBtn.isEnabled()) { + controller.cutCopyPasteController.startCuttying( + controller.getSelectedNodes(), + controller.getCurrentWorkingDirectory()); pasteBtn.setEnabled(true); } } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(cutBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (cutBtn.isEnabled()) cutBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { cutBtn.setBackground(GuifyColors.GRAY); - } + } }); - + copyBtn = new JButton(); copyBtn.setBorderPainted(false); copyBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border; copyBtn.setToolTipText("Copy"); try { - copyBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("copy_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + copyBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("copy_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); copyBtn.setBackground(GuifyColors.GRAY); copyBtn.setBorderPainted(false); copyBtn.setEnabled(false); - }catch(IOException ex) { + } catch (IOException ex) { copyBtn.setText("Copy"); } copyBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - controller.cutCopyPasteController.startCopying(controller.getSelectedNodes(), controller.getCurrentWorkingDirectory()); + controller.cutCopyPasteController.startCopying( + controller.getSelectedNodes(), + controller.getCurrentWorkingDirectory()); pasteBtn.setEnabled(true); } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(copyBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (copyBtn.isEnabled()) copyBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { copyBtn.setBackground(GuifyColors.GRAY); - } + } }); - + pasteBtn = new JButton(); pasteBtn.setBorderPainted(false); pasteBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border; pasteBtn.setToolTipText("Paste"); try { - pasteBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("paste_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + pasteBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("paste_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); pasteBtn.setBorderPainted(false); pasteBtn.setEnabled(false); - }catch(IOException ex) { + } catch (IOException ex) { pasteBtn.setText("Paste"); } pasteBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - controller.cutCopyPasteController.paste(controller.getCurrentWorkingDirectory()); - drawComponentsForDirectory(controller.getCurrentWorkingDirectory()); + controller.cutCopyPasteController + .paste(controller.getCurrentWorkingDirectory()); + drawComponentsForDirectory( + controller.getCurrentWorkingDirectory()); } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(pasteBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (pasteBtn.isEnabled()) pasteBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { pasteBtn.setBackground(GuifyColors.GRAY); - } + } }); - + renameBtn = new JButton(); renameBtn.setBorderPainted(false); renameBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border; renameBtn.setToolTipText("Rename"); try { - renameBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("rename_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + renameBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("rename_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); renameBtn.setBackground(GuifyColors.GRAY); renameBtn.setBorderPainted(false); renameBtn.setEnabled(false); - }catch(IOException ex) { + } catch (IOException ex) { renameBtn.setText("Rename"); } renameBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - - // Something's off and the rename button shouldn't have been active in the first place - if(controller.getSelectedNodes().size() != 1) { + + // Something's off and the rename button shouldn't have been + // active in the first place + if (controller.getSelectedNodes().size() != 1) { return; } - String oldPath = Helper.combinePath(controller.getCurrentWorkingDirectory(), controller.getSelectedNodes().get(0).getNode().getFilename()); - - String newName = (String)JOptionPane.showInputDialog( - Desktop.this, - "Rename \"" + controller.getSelectedNodes().get(0).getNode().getFilename() + "\"", - "Rename", - JOptionPane.PLAIN_MESSAGE, - null, - null, - null); - - // has closed or canceled - if(newName == null) { + String oldPath = Helper.combinePath( + controller.getCurrentWorkingDirectory(), + controller.getSelectedNodes().get(0).getNode() + .getFilename()); + + String newName = (String) JOptionPane.showInputDialog( + Desktop.this, + "Rename \"" + controller.getSelectedNodes().get(0) + .getNode().getFilename() + "\"", + "Rename", JOptionPane.PLAIN_MESSAGE, null, null, null); + + // has closed or canceled + if (newName == null) { return; } - - String newPath = Helper.combinePath(controller.getCurrentWorkingDirectory(), newName); + + String newPath = Helper.combinePath( + controller.getCurrentWorkingDirectory(), newName); try { controller.rename(oldPath, newPath); } catch (SftpException e1) { if (e1.getMessage().contains("Permission denied")) { - JOptionPane.showMessageDialog(new JFrame(), "Not enough permissions to rename this element", "Permission denied", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(new JFrame(), + "Not enough permissions to rename this element", + "Permission denied", JOptionPane.ERROR_MESSAGE); return; } } - drawComponentsForDirectory(controller.getCurrentWorkingDirectory()); // TODO optimize this + drawComponentsForDirectory( + controller.getCurrentWorkingDirectory()); // TODO + // optimize + // this } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(renameBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (renameBtn.isEnabled()) renameBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { renameBtn.setBackground(GuifyColors.GRAY); - } + } }); - - JButton newBtn = new JButton(); - newBtn.setBorderPainted(false); - newBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border); - newBtn.setToolTipText("New"); + + JButton newBtn = new JButton(); + newBtn.setBorderPainted(false); + newBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border); + newBtn.setToolTipText("New"); try { - newBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("plus_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + newBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("plus_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); newBtn.setBackground(GuifyColors.GRAY); newBtn.setBorderPainted(false); - }catch(IOException ex) { + } catch (IOException ex) { newBtn.setText("New"); } - newBtn.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JPopupMenu menu = new JPopupMenu(); - - JMenuItem newFileMenuItem = new JMenuItem("New file"); + newBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JPopupMenu menu = new JPopupMenu(); + + JMenuItem newFileMenuItem = new JMenuItem("New file"); try { - newFileMenuItem.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("file_icon.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH))); + newFileMenuItem.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("file_icon.png")) + .getScaledInstance(16, 16, Image.SCALE_SMOOTH))); } catch (IOException e1) { - + } - newFileMenuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - - String newFileName = (String)JOptionPane.showInputDialog( - Desktop.this, - "Name:", - "New file", - JOptionPane.PLAIN_MESSAGE, - null, - null, - null); - - String newFilePath = Helper.combinePath(controller.getCurrentWorkingDirectory(), newFileName); - try { - controller.touch(newFilePath); + newFileMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + String newFileName = (String) JOptionPane + .showInputDialog(Desktop.this, "Name:", + "New file", JOptionPane.PLAIN_MESSAGE, + null, null, null); + + String newFilePath = Helper.combinePath( + controller.getCurrentWorkingDirectory(), + newFileName); + try { + controller.touch(newFilePath); } catch (SftpException e1) { if (e1.getMessage().contains("Permission denied")) { - JOptionPane.showMessageDialog(new JFrame(), "Not enough permissions to create a file here", "Permission denied", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(new JFrame(), + "Not enough permissions to create a file here", + "Permission denied", + JOptionPane.ERROR_MESSAGE); return; } } - drawComponentsForDirectory(controller.getCurrentWorkingDirectory()); - } - }); - - JMenuItem newFolderMenuItem = new JMenuItem("New folder"); + drawComponentsForDirectory( + controller.getCurrentWorkingDirectory()); + } + }); + + JMenuItem newFolderMenuItem = new JMenuItem("New folder"); try { - newFolderMenuItem.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("folder_icon.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH))); + newFolderMenuItem.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("folder_icon.png")) + .getScaledInstance(16, 16, Image.SCALE_SMOOTH))); } catch (IOException e1) { - + } newFolderMenuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - - String newFolderName = (String)JOptionPane.showInputDialog( - Desktop.this, - "Name:", - "New folder", - JOptionPane.PLAIN_MESSAGE, - null, - null, - null); - - // User has canceled - if(newFolderName == null) { - return; - } - - String newFolderPath = Helper.combinePath(controller.getCurrentWorkingDirectory(), newFolderName); - try { - controller.mkdir(newFolderPath); + @Override + public void actionPerformed(ActionEvent e) { + + String newFolderName = (String) JOptionPane + .showInputDialog(Desktop.this, "Name:", + "New folder", JOptionPane.PLAIN_MESSAGE, + null, null, null); + + // User has canceled + if (newFolderName == null) { + return; + } + + String newFolderPath = Helper.combinePath( + controller.getCurrentWorkingDirectory(), + newFolderName); + try { + controller.mkdir(newFolderPath); } catch (SftpException e1) { if (e1.getMessage().contains("Permission denied")) { - JOptionPane.showMessageDialog(new JFrame(), "Not enough permissions to create a folder here", "Permission denied", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(new JFrame(), + "Not enough permissions to create a folder here", + "Permission denied", + JOptionPane.ERROR_MESSAGE); return; - } + } } - drawComponentsForDirectory(controller.getCurrentWorkingDirectory()); //TODO: avoid a complete desktop reload - } - }); - - menu.add(newFileMenuItem); - menu.add(newFolderMenuItem); - menu.show(newBtn, 0, newBtn.getHeight()); - } - }); - newBtn.addMouseListener(new MouseAdapter() { + drawComponentsForDirectory( + controller.getCurrentWorkingDirectory()); // TODO: + // avoid + // a + // complete + // desktop + // reload + } + }); + + menu.add(newFileMenuItem); + menu.add(newFolderMenuItem); + menu.show(newBtn, 0, newBtn.getHeight()); + } + }); + newBtn.addMouseListener(new MouseAdapter() { // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(newBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (newBtn.isEnabled()) newBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { newBtn.setBackground(GuifyColors.GRAY); - } + } }); - + deleteBtn = new JButton(); deleteBtn.setBorderPainted(false); deleteBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border); deleteBtn.setToolTipText("Delete"); try { - deleteBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("delete_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + deleteBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("delete_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); deleteBtn.setBackground(GuifyColors.GRAY); deleteBtn.setBorderPainted(false); deleteBtn.setEnabled(false); - }catch(IOException ex) { + } catch (IOException ex) { deleteBtn.setText("Delete"); } deleteBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - ImageIcon deleteIcon = null; - try { - deleteIcon = new ImageIcon( - ImageIO.read(getClass().getClassLoader().getResource("delete_icon.png")).getScaledInstance(32, 32, Image.SCALE_SMOOTH)); - } - catch (IOException e1) {} + ImageIcon deleteIcon = null; + try { + deleteIcon = new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("delete_icon.png")) + .getScaledInstance(32, 32, Image.SCALE_SMOOTH)); + } catch (IOException e1) { + } int choice = JOptionPane.showOptionDialog(null, - "Do you really want to delete the selected items?", - Constants.APP_NAME, - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE, - deleteIcon, - null, - null); - - if(choice == 0) { // yes + "Do you really want to delete the selected items?", + Constants.APP_NAME, JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, deleteIcon, null, null); + + if (choice == 0) { // yes try { controller.deleteSelectedNodes(); } catch (SftpException e1) { if (e1.getMessage().contains("Permission denied")) { - JOptionPane.showMessageDialog(new JFrame(), "Deletion process has encountered an item which cannot be deleted", "Permission denied", JOptionPane.ERROR_MESSAGE); - } + JOptionPane.showMessageDialog(new JFrame(), + "Deletion process has encountered an item which cannot be deleted", + "Permission denied", + JOptionPane.ERROR_MESSAGE); + } } - drawComponentsForDirectory(controller.getCurrentWorkingDirectory()); + drawComponentsForDirectory( + controller.getCurrentWorkingDirectory()); } } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(deleteBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (deleteBtn.isEnabled()) deleteBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { deleteBtn.setBackground(GuifyColors.GRAY); - } + } }); - + downloadBtn = new JButton(); downloadBtn.setBorderPainted(false); - downloadBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border); + downloadBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty + // border); downloadBtn.setToolTipText("Download"); try { - downloadBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("download_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + downloadBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("download_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); downloadBtn.setBorderPainted(false); downloadBtn.setEnabled(false); - }catch(IOException ex) { + } catch (IOException ex) { downloadBtn.setText("Download"); } downloadBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - int choiceFileChooser = fileChooser.showDialog(Desktop.this, "Save here"); - if (choiceFileChooser == JFileChooser.APPROVE_OPTION) { - controller.downloadSelectedNodes(fileChooser.getSelectedFile().toString()); - } + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int choiceFileChooser = fileChooser.showDialog(Desktop.this, + "Save here"); + if (choiceFileChooser == JFileChooser.APPROVE_OPTION) { + controller.downloadSelectedNodes( + fileChooser.getSelectedFile().toString()); + } } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(downloadBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (downloadBtn.isEnabled()) downloadBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { downloadBtn.setBackground(GuifyColors.GRAY); - } + } }); - + JButton uploadBtn = new JButton(); uploadBtn.setBorderPainted(false); uploadBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border); uploadBtn.setToolTipText("Upload here"); try { - uploadBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("upload_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + uploadBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("upload_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); uploadBtn.setBackground(GuifyColors.GRAY); uploadBtn.setBorderPainted(false); uploadBtn.setEnabled(true); - }catch(IOException ex) { + } catch (IOException ex) { uploadBtn.setText("Upload here"); } uploadBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - fileChooser.setMultiSelectionEnabled(true); - int choiceFileChooser = fileChooser.showDialog(Desktop.this, "Upload"); - if (choiceFileChooser == JFileChooser.APPROVE_OPTION && fileChooser.getSelectedFiles().length > 0) { - try { - controller.uploadToRemoteServer(fileChooser.getSelectedFiles()); + fileChooser.setFileSelectionMode( + JFileChooser.FILES_AND_DIRECTORIES); + fileChooser.setMultiSelectionEnabled(true); + int choiceFileChooser = fileChooser.showDialog(Desktop.this, + "Upload"); + if (choiceFileChooser == JFileChooser.APPROVE_OPTION + && fileChooser.getSelectedFiles().length > 0) { + try { + controller.uploadToRemoteServer( + fileChooser.getSelectedFiles()); } catch (SftpException e1) { if (e1.getMessage().contains("Permission denied")) { - JOptionPane.showMessageDialog(new JFrame(), "Not enough permissions to upload in this location", "Permission denied", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(new JFrame(), + "Not enough permissions to upload in this location", + "Permission denied", + JOptionPane.ERROR_MESSAGE); return; } } - drawComponentsForDirectory(controller.getCurrentWorkingDirectory()); - } + drawComponentsForDirectory( + controller.getCurrentWorkingDirectory()); + } } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(uploadBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (uploadBtn.isEnabled()) uploadBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { uploadBtn.setBackground(GuifyColors.GRAY); - } + } }); - + JButton queueBtn = new JButton(); queueBtn.setBorderPainted(false); queueBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border); queueBtn.setToolTipText("Queue"); try { - queueBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("queue_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + queueBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("queue_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); queueBtn.setBackground(GuifyColors.GRAY); queueBtn.setBorderPainted(false); queueBtn.setEnabled(true); - }catch(IOException ex) { + } catch (IOException ex) { queueBtn.setText("Queue"); } queueBtn.addMouseListener(new MouseAdapter() { @@ -895,77 +1000,82 @@ public class Desktop extends JFrame implements IDesktopFrame { QueueController queueController = new QueueController(); queueController.showFrame(true); } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(queueBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (queueBtn.isEnabled()) queueBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { queueBtn.setBackground(GuifyColors.GRAY); - } + } }); - - + pathTextBox = new JTextField(); pathTextBox.setMaximumSize(new Dimension(200, 35)); pathTextBox.setMinimumSize(new Dimension(50, 35)); pathTextBox.setPreferredSize(new Dimension(200, 35)); - Font font = pathTextBox.getFont(); - Font biggerFont = font.deriveFont(font.getSize() + 4f); // Increase font size by 4 - pathTextBox.setFont(biggerFont); - pathTextBox.addFocusListener(new FocusListener() { + Font font = pathTextBox.getFont(); + Font biggerFont = font.deriveFont(font.getSize() + 4f); // Increase font + // size by 4 + pathTextBox.setFont(biggerFont); + pathTextBox.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { - if(pathTextBox != null && !pathTextBox.getText().equals(controller.getCurrentWorkingDirectory())) { + if (pathTextBox != null && !pathTextBox.getText() + .equals(controller.getCurrentWorkingDirectory())) { drawComponentsForDirectory(pathTextBox.getText()); } } @Override - public void focusGained(FocusEvent e) {} - }); + public void focusGained(FocusEvent e) { + } + }); - JButton goToBtn = new JButton(); goToBtn.setBorderPainted(false); goToBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border); goToBtn.setToolTipText("Go"); try { - goToBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("go_to_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + goToBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("go_to_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); goToBtn.setBackground(GuifyColors.GRAY); goToBtn.setBorderPainted(false); goToBtn.setEnabled(true); - }catch(IOException ex) { + } catch (IOException ex) { goToBtn.setText("Go"); } goToBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - if(pathTextBox != null && !pathTextBox.getText().equals(controller.getCurrentWorkingDirectory())) { + if (pathTextBox != null && !pathTextBox.getText() + .equals(controller.getCurrentWorkingDirectory())) { drawComponentsForDirectory(pathTextBox.getText()); } } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(uploadBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (uploadBtn.isEnabled()) goToBtn.setBackground(GuifyColors.GRAY_HOVER); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { goToBtn.setBackground(GuifyColors.GRAY); - } + } }); - + toolBar.add(backBtn); toolBar.add(Box.createHorizontalStrut(15)); toolBar.add(cutBtn); @@ -989,70 +1099,66 @@ public class Desktop extends JFrame implements IDesktopFrame { toolBar.add(pathTextBox); toolBar.add(Box.createHorizontalStrut(5)); toolBar.add(goToBtn); - + } - + /** - * Enables or disables tool bar buttons - * according to these propositions: + * Enables or disables tool bar buttons according to these propositions: * - * 1. At least a selected node is selected <--> cut, copy, delete, download ENABLED - * 2. Only one selected node is selected <--> rename ENABLED - * 3. selectedToolBarOperation is not none <--> paste ENABLED + * 1. At least a selected node is selected <--> cut, copy, delete, download + * ENABLED 2. Only one selected node is selected <--> rename ENABLED 3. + * selectedToolBarOperation is not none <--> paste ENABLED */ private void updateToolBarItems() { - + int selectedNodes = controller.countSelectedNodes(); - int selectedToolBarOperation = controller.cutCopyPasteController.getSelectedOperation(); - - if(selectedToolBarOperation != Constants.Constants_FSOperations.NONE) { + int selectedToolBarOperation = controller.cutCopyPasteController + .getSelectedOperation(); + + if (selectedToolBarOperation != Constants.Constants_FSOperations.NONE) { pasteBtn.setEnabled(true); - } - else { + } else { pasteBtn.setEnabled(false); } - - if(selectedNodes == 1) { + + if (selectedNodes == 1) { renameBtn.setEnabled(true); - } - else { + } else { renameBtn.setEnabled(false); } - - if(selectedNodes > 0) { + + if (selectedNodes > 0) { cutBtn.setEnabled(true); copyBtn.setEnabled(true); deleteBtn.setEnabled(true); downloadBtn.setEnabled(true); - } - else { + } else { cutBtn.setEnabled(false); copyBtn.setEnabled(false); deleteBtn.setEnabled(false); downloadBtn.setEnabled(false); } } - + /* * ========== END Frame Drawing ========== */ - - + /* * ========== BEGIN Node selection/deselection ========== */ - + private void selectNode(JDirectoryNodeButton node) { controller.addSelectedNode(node); - node.setBackground(new Color(204,238,255)); - updateToolBarItems(); + node.setBackground(new Color(204, 238, 255)); + updateToolBarItems(); } - + private void unselectAllNodes() { - controller.clearSelectedNodes(); - // TODO: gotta enhance this for - for(Component component: desktopPanel.getComponents()) { - if(component instanceof JDirectoryNodeButton) { + controller.clearSelectedNodes(); + // TODO: gotta enhance this for + for (Component component : desktopPanel.getComponents()) { + if (component instanceof JDirectoryNodeButton) { component.setBackground(new Color(255, 255, 255)); } } @@ -1068,5 +1174,5 @@ public class Desktop extends JFrame implements IDesktopFrame { /* * ========== END Node selection/deselection ========== */ - + } diff --git a/Guify/src/views/FindAndReplace.java b/Guify/src/views/FindAndReplace.java index 732815e..b61c430 100644 --- a/Guify/src/views/FindAndReplace.java +++ b/Guify/src/views/FindAndReplace.java @@ -12,94 +12,98 @@ import views.interfaces.IFindAndReplaceFrame; public class FindAndReplace extends JFrame implements IFindAndReplaceFrame { - private static final long serialVersionUID = 1L; - - public FindAndReplace(Object controller) { - JLabel lab1 = new JLabel("Find:"); - JLabel lab2 = new JLabel("Replace:"); - JTextField findTextField = new JTextField(30); - JTextField replaceTextField = new JTextField(30); - JButton findNextBtn = new JButton("Find Next"); - findNextBtn.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e){ - ((FindAndReplaceController) controller).findNext(findTextField.getText()); - } - }); - - JButton findPreviousBtn = new JButton("Find Previous"); - findPreviousBtn.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e){ - ((FindAndReplaceController) controller).findPrevious(findTextField.getText()); - } - }); - - JButton replaceNextBtn = new JButton("Replace Next"); - replaceNextBtn.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e){ - ((FindAndReplaceController) controller).replaceNext(findTextField.getText(), replaceTextField.getText()); - } - }); - - JButton replaceAllBtn = new JButton("Replace All"); - replaceAllBtn.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e){ - ((FindAndReplaceController) controller).replaceAll(findTextField.getText(), replaceTextField.getText()); - } - }); - - JButton cancel = new JButton("Cancel"); - cancel.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e){ - dispose(); - } - }); + private static final long serialVersionUID = 1L; - setLayout(null); + public FindAndReplace(Object controller) { + JLabel lab1 = new JLabel("Find:"); + JLabel lab2 = new JLabel("Replace:"); + JTextField findTextField = new JTextField(30); + JTextField replaceTextField = new JTextField(30); + JButton findNextBtn = new JButton("Find Next"); + findNextBtn.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + ((FindAndReplaceController) controller) + .findNext(findTextField.getText()); + } + }); - // Set the width and height of the label - int labWidth = 80; - int labHeight = 20; + JButton findPreviousBtn = new JButton("Find Previous"); + findPreviousBtn.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + ((FindAndReplaceController) controller) + .findPrevious(findTextField.getText()); + } + }); - // Adding labels - lab1.setBounds(10,10, labWidth, labHeight); - add(lab1); - findTextField.setBounds(10+labWidth, 10, 120, 20); - add(findTextField); - lab2.setBounds(10, 10+labHeight+10, labWidth, labHeight); - add(lab2); - replaceTextField.setBounds(10+labWidth, 10+labHeight+10, 120, 20); - add(replaceTextField); + JButton replaceNextBtn = new JButton("Replace Next"); + replaceNextBtn.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + ((FindAndReplaceController) controller).replaceNext( + findTextField.getText(), replaceTextField.getText()); + } + }); - // Adding buttons - findNextBtn.setBounds(225, 6, 115, 20); - add(findNextBtn); + JButton replaceAllBtn = new JButton("Replace All"); + replaceAllBtn.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + ((FindAndReplaceController) controller).replaceAll( + findTextField.getText(), replaceTextField.getText()); + } + }); - findPreviousBtn.setBounds(225, 28, 115, 20); - add(findPreviousBtn); + JButton cancel = new JButton("Cancel"); + cancel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + dispose(); + } + }); - replaceNextBtn.setBounds(225, 50, 115, 20); - add(replaceNextBtn); + setLayout(null); - replaceAllBtn.setBounds(225, 72, 115, 20); - add(replaceAllBtn); + // Set the width and height of the label + int labWidth = 80; + int labHeight = 20; - cancel.setBounds(225, 94, 115, 20); - add(cancel); + // Adding labels + lab1.setBounds(10, 10, labWidth, labHeight); + add(lab1); + findTextField.setBounds(10 + labWidth, 10, 120, 20); + add(findTextField); + lab2.setBounds(10, 10 + labHeight + 10, labWidth, labHeight); + add(lab2); + replaceTextField.setBounds(10 + labWidth, 10 + labHeight + 10, 120, 20); + add(replaceTextField); - // Set the width and height of the window - int width = 360; - int height = 160; + // Adding buttons + findNextBtn.setBounds(225, 6, 115, 20); + add(findNextBtn); - // Set size window - setSize(width, height); - setResizable(false); - setTitle("Find/Replace"); - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - setAlwaysOnTop(true); + findPreviousBtn.setBounds(225, 28, 115, 20); + add(findPreviousBtn); + + replaceNextBtn.setBounds(225, 50, 115, 20); + add(replaceNextBtn); + + replaceAllBtn.setBounds(225, 72, 115, 20); + add(replaceAllBtn); + + cancel.setBounds(225, 94, 115, 20); + add(cancel); + + // Set the width and height of the window + int width = 360; + int height = 160; + + // Set size window + setSize(width, height); + setResizable(false); + setTitle("Find/Replace"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setAlwaysOnTop(true); } } diff --git a/Guify/src/views/Login.java b/Guify/src/views/Login.java index b8f50a1..8f824b0 100644 --- a/Guify/src/views/Login.java +++ b/Guify/src/views/Login.java @@ -24,10 +24,10 @@ public class Login extends JFrame implements ILoginFrame { private JTextField usernameField; private JTextField hostField; private JTextField portField; - + public Login(Object controller) { this.controller = (LoginController) controller; - + setTitle(this.controller.getTitle()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(false); @@ -39,26 +39,26 @@ public class Login extends JFrame implements ILoginFrame { setContentPane(contentPane); contentPane.setLayout(null); - + passwordField = new JPasswordField(); passwordField.setToolTipText("SSH Password"); passwordField.setBounds(10, 159, 139, 20); contentPane.add(passwordField); - + JLabel lblNewLabel = new JLabel("Username"); lblNewLabel.setBounds(10, 78, 139, 14); contentPane.add(lblNewLabel); - + JLabel lblNewLabel_1 = new JLabel("Password"); lblNewLabel_1.setBounds(10, 134, 139, 14); contentPane.add(lblNewLabel_1); - + usernameField = new JTextField(); usernameField.setToolTipText("SSH Username"); usernameField.setBounds(10, 103, 139, 20); contentPane.add(usernameField); usernameField.setColumns(10); - + JButton btnConnect = new JButton("Connect"); btnConnect.setForeground(Color.WHITE); btnConnect.setBackground(GuifyColors.BLUE); @@ -69,29 +69,28 @@ public class Login extends JFrame implements ILoginFrame { }); btnConnect.setBounds(75, 297, 139, 30); contentPane.add(btnConnect); - + JLabel lblNewLabel_2 = new JLabel("Host"); lblNewLabel_2.setBounds(10, 22, 139, 14); contentPane.add(lblNewLabel_2); - + hostField = new JTextField(); hostField.setToolTipText("SSH Host"); hostField.setBounds(10, 47, 139, 20); contentPane.add(hostField); hostField.setColumns(10); - + JLabel lblNewLabel_3 = new JLabel("Port"); lblNewLabel_3.setBounds(10, 190, 139, 14); contentPane.add(lblNewLabel_3); - + portField = new JTextField(); portField.setText("22"); portField.setToolTipText("SSH Port"); portField.setBounds(10, 215, 86, 20); contentPane.add(portField); portField.setColumns(10); - - + } /** @@ -103,20 +102,21 @@ public class Login extends JFrame implements ILoginFrame { String username = usernameField.getText(); String password = String.valueOf(passwordField.getPassword()); String port = portField.getText(); - + // Perform validation try { controller.ValidateInput(host, username, password, port); - } - catch(IllegalArgumentException ex) { - JOptionPane.showMessageDialog(new JFrame(), ex.getMessage(), "Attention required", JOptionPane.ERROR_MESSAGE); + } catch (IllegalArgumentException ex) { + JOptionPane.showMessageDialog(new JFrame(), ex.getMessage(), + "Attention required", JOptionPane.ERROR_MESSAGE); return; } - + // Perform login - if(!controller.Login(host, username, password, port)) { - JOptionPane.showMessageDialog(new JFrame(), "SSH Login failed", "SSH Login failed", JOptionPane.ERROR_MESSAGE); + if (!controller.Login(host, username, password, port)) { + JOptionPane.showMessageDialog(new JFrame(), "SSH Login failed", + "SSH Login failed", JOptionPane.ERROR_MESSAGE); } } - + } diff --git a/Guify/src/views/Notepad.java b/Guify/src/views/Notepad.java index 5c340c5..97112fc 100644 --- a/Guify/src/views/Notepad.java +++ b/Guify/src/views/Notepad.java @@ -27,11 +27,11 @@ import javax.swing.JScrollPane; import javax.swing.JPanel; public class Notepad extends JFrame implements INotepadFrame { - + private static final long serialVersionUID = 1L; private NotepadController controller; private JTextArea textArea; - + public Notepad(Object controller) { this.controller = (NotepadController) controller; setTitle(this.controller.getFilePath()); @@ -41,128 +41,141 @@ public class Notepad extends JFrame implements INotepadFrame { JPanel contentPanel = new JPanel(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(textArea); contentPanel.add(scrollPane, BorderLayout.CENTER); - contentPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); // We want to create a spaced JPanel + contentPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); // We + // want + // to + // create + // a + // spaced + // JPanel getContentPane().add(contentPanel, BorderLayout.CENTER); textArea = new JTextArea(); scrollPane.setViewportView(textArea); textArea.setTabSize(4); textArea.setFont(new Font("Monospaced", Font.PLAIN, 14)); textArea.setCaretPosition(0); - textArea.setText(((NotepadController)controller).getInitialText()); + textArea.setText(((NotepadController) controller).getInitialText()); textArea.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - // Called when text is inserted into the document - handleTextChange(); - } + @Override + public void insertUpdate(DocumentEvent e) { + // Called when text is inserted into the document + handleTextChange(); + } - @Override - public void removeUpdate(DocumentEvent e) { - // Called when text is removed from the document - handleTextChange(); - } + @Override + public void removeUpdate(DocumentEvent e) { + // Called when text is removed from the document + handleTextChange(); + } - @Override - public void changedUpdate(DocumentEvent e) { - // Called when attributes of the document change - // NO OP - } + @Override + public void changedUpdate(DocumentEvent e) { + // Called when attributes of the document change + // NO OP + } + + private void handleTextChange() { + if (!((NotepadController) controller).isUnsaved()) { + ((NotepadController) controller).setUnsaved(true); + setTitle(((NotepadController) controller).getTitle()); + } + } + }); - private void handleTextChange() { - if(!((NotepadController)controller).isUnsaved()) { - ((NotepadController)controller).setUnsaved(true); - setTitle(((NotepadController)controller).getTitle()); - } - } - }); - JButton saveBtn = new JButton(); saveBtn.setBorderPainted(false); saveBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border saveBtn.setToolTipText("Save"); try { - saveBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("save_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + saveBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("save_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); saveBtn.setBackground(new Color(240, 240, 240)); saveBtn.setBorderPainted(false); saveBtn.setEnabled(true); - }catch(IOException ex) { + } catch (IOException ex) { saveBtn.setText("Save"); } saveBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - ((NotepadController)controller).writeOnFile(textArea.getText()); - ((NotepadController)controller).setUnsaved(false); - setTitle(((NotepadController)controller).getTitle()); + ((NotepadController) controller) + .writeOnFile(textArea.getText()); + ((NotepadController) controller).setUnsaved(false); + setTitle(((NotepadController) controller).getTitle()); } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(saveBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (saveBtn.isEnabled()) saveBtn.setBackground(new Color(220, 220, 220)); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { saveBtn.setBackground(new Color(240, 240, 240)); - } + } }); - + JButton searchBtn = new JButton(); searchBtn.setBorderPainted(false); searchBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); // Set empty border; searchBtn.setToolTipText("Serch/Replace"); try { - searchBtn.setIcon(new ImageIcon(ImageIO.read(getClass().getClassLoader().getResource("search_icon.png")).getScaledInstance(25, 25, Image.SCALE_SMOOTH))); + searchBtn.setIcon(new ImageIcon(ImageIO + .read(getClass().getClassLoader() + .getResource("search_icon.png")) + .getScaledInstance(25, 25, Image.SCALE_SMOOTH))); searchBtn.setBackground(new Color(240, 240, 240)); searchBtn.setBorderPainted(false); searchBtn.setEnabled(true); - }catch(IOException ex) { + } catch (IOException ex) { searchBtn.setText("Serch/Replace"); } searchBtn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - ((NotepadController)controller).showFindAndReplace(new JGenericTextArea(textArea)); + ((NotepadController) controller) + .showFindAndReplace(new JGenericTextArea(textArea)); } - + // Hover on @Override - public void mouseEntered(MouseEvent e) { - if(searchBtn.isEnabled()) + public void mouseEntered(MouseEvent e) { + if (searchBtn.isEnabled()) searchBtn.setBackground(new Color(220, 220, 220)); - } + } // Hover off @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(MouseEvent e) { searchBtn.setBackground(new Color(240, 240, 240)); - } + } }); - + JToolBar toolBar = new JToolBar(); toolBar.setFloatable(false); JPanel toolBarPanel = new JPanel(new BorderLayout()); - toolBarPanel.setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 0)); + toolBarPanel.setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 0)); toolBarPanel.add(toolBar, BorderLayout.LINE_START); toolBar.setBackground(new Color(240, 240, 240)); toolBar.add(saveBtn); toolBar.add(Box.createHorizontalStrut(15)); toolBar.add(searchBtn); - + getContentPane().add(toolBarPanel, BorderLayout.NORTH); /** - * Close "Find and Replace" if this window - * gets closed + * Close "Find and Replace" if this window gets closed */ addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - ((NotepadController)controller).disposeFindAndReplaceFrame(); - } - }); + @Override + public void windowClosing(WindowEvent e) { + ((NotepadController) controller).disposeFindAndReplaceFrame(); + } + }); } } diff --git a/Guify/src/views/Queue.java b/Guify/src/views/Queue.java index bc35d96..a513e5b 100644 --- a/Guify/src/views/Queue.java +++ b/Guify/src/views/Queue.java @@ -19,111 +19,131 @@ public class Queue extends JFrame implements IQueueFrame { private static final long serialVersionUID = 1L; private QueueController controller; - + /** * - * Custom cell renderer in order to be able to display - * a progress bar in the JTable + * Custom cell renderer in order to be able to display a progress bar in the + * JTable * */ - public static class ProgressBarTableCellRenderer extends DefaultTableCellRenderer { + public static class ProgressBarTableCellRenderer + extends + DefaultTableCellRenderer { private static final long serialVersionUID = 1L; private JProgressBar progressBar; - - public ProgressBarTableCellRenderer() { - super(); - progressBar = new JProgressBar(); - progressBar.setStringPainted(true); - } - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, - boolean hasFocus, int row, int column) { - if (value instanceof Integer) { - int progressValue = (Integer) value; - progressBar.setValue(progressValue); - progressBar.setString(progressValue + "%"); - } - - progressBar.setStringPainted(true); - progressBar.setForeground(Constants.GuifyColors.BLUE); - progressBar.setBackground(Color.WHITE); - - return progressBar; - } + public ProgressBarTableCellRenderer() { + super(); + progressBar = new JProgressBar(); + progressBar.setStringPainted(true); + } + + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, boolean isSelected, boolean hasFocus, int row, + int column) { + if (value instanceof Integer) { + int progressValue = (Integer) value; + progressBar.setValue(progressValue); + progressBar.setString(progressValue + "%"); + } + + progressBar.setStringPainted(true); + progressBar.setForeground(Constants.GuifyColors.BLUE); + progressBar.setBackground(Color.WHITE); + + return progressBar; + } } - + public DefaultTableModel tableModel; - + public Queue(Object controller) { this.controller = (QueueController) controller; setTitle("Queue"); - String[] columnNames = {"Source", "Destination", "Operation", "Percentage"}; - tableModel = new DefaultTableModel(columnNames, 0); - JTable table = new JTable(tableModel); - table.setEnabled(false); // Prevents user editing - // Show percentage by using a custom cell renderer - TableColumn percentageColumn = table.getColumnModel().getColumn(3); - percentageColumn.setCellRenderer(new ProgressBarTableCellRenderer()); - JScrollPane scrollPane = new JScrollPane(table); - this.getContentPane().add(scrollPane, BorderLayout.CENTER); - this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - this.pack(); + String[] columnNames = {"Source", "Destination", "Operation", + "Percentage"}; + tableModel = new DefaultTableModel(columnNames, 0); + JTable table = new JTable(tableModel); + table.setEnabled(false); // Prevents user editing + // Show percentage by using a custom cell renderer + TableColumn percentageColumn = table.getColumnModel().getColumn(3); + percentageColumn.setCellRenderer(new ProgressBarTableCellRenderer()); + JScrollPane scrollPane = new JScrollPane(table); + this.getContentPane().add(scrollPane, BorderLayout.CENTER); + this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + this.pack(); } - + /** * Adds a row in the JTable + * * @return The index of the inserted row */ - public int addRow(String source, String destination, String operation, int percentage) { - tableModel.addRow(new Object[]{source, destination, operation, percentage}); - return tableModel.getRowCount() - 1; + public int addRow(String source, String destination, String operation, + int percentage) { + tableModel.addRow( + new Object[]{source, destination, operation, percentage}); + return tableModel.getRowCount() - 1; } - + /** - * Given a value (representing the transfer completion percentage) - * and an index representing the 0-based index of the row to update, - * update that row with that value - * @param rowIndex 0-base index of the row to update - * @param percentage The transfer completion percentage to set + * Given a value (representing the transfer completion percentage) and an + * index representing the 0-based index of the row to update, update that + * row with that value + * + * @param rowIndex + * 0-base index of the row to update + * @param percentage + * The transfer completion percentage to set */ public void updateRow(int rowIndex, int percentage) { - if(rowIndex < tableModel.getRowCount()) { + if (rowIndex < tableModel.getRowCount()) { tableModel.setValueAt(percentage, rowIndex, 3); } } - // This method can receive a transferProgress whose status can be INIT, UPDATING + // This method can receive a transferProgress whose status can be INIT, + // UPDATING // or END. - // In all of these cases it is possible that transferProgress is or is not in the HashMap, + // In all of these cases it is possible that transferProgress is or is not + // in the HashMap, // and we'll prove its correctness in all the cases: // - // 1. Init: This method can receive a transferProgress whose status is INIT and - // a. Not present in the HashMap: this can happen either when QueueController receives - // an update() or when it iterates in the constructor over the previously enqueued - // elements. In both cases, the transfer gets correctly put in the table. - // b. Present in the HashMap: despite it's counterintuitive, this can happen when - // a transfer gets initialized after QueueEventManager.getInstance().addObserver(this); - // and before QueueEventManager.getInstance().getQueue(). - // This would lead either update() - // or the QueueController's constructor to call this method over a transferProgress - // already in the HashMap (because inserted by the other one) - // but whose status is INIT. In this case, updateRow() will - // be called, but without any side effects as the percentage would be zero regardless. + // 1. Init: This method can receive a transferProgress whose status is INIT + // and + // a. Not present in the HashMap: this can happen either when + // QueueController receives + // an update() or when it iterates in the constructor over the previously + // enqueued + // elements. In both cases, the transfer gets correctly put in the table. + // b. Present in the HashMap: despite it's counterintuitive, this can happen + // when + // a transfer gets initialized after + // QueueEventManager.getInstance().addObserver(this); + // and before QueueEventManager.getInstance().getQueue(). + // This would lead either update() + // or the QueueController's constructor to call this method over a + // transferProgress + // already in the HashMap (because inserted by the other one) + // but whose status is INIT. In this case, updateRow() will + // be called, but without any side effects as the percentage would be zero + // regardless. // // 2. Updating: - // a. Not present in the HashMap: This can happen when the Queue UI is opened - // while an element is already being transferred. This happens because when - // the transfer had a "INIT" status, this object did not exist yet. - // If it's not present in the HashMap - // then it will be added. - // b. Present in the HashMap: then it will be correctly updated. + // a. Not present in the HashMap: This can happen when the Queue UI is + // opened + // while an element is already being transferred. This happens because when + // the transfer had a "INIT" status, this object did not exist yet. + // If it's not present in the HashMap + // then it will be added. + // b. Present in the HashMap: then it will be correctly updated. // // 3. End: Same case for Updating // - // It's important to note that this method will always operate over the - // last version of the same TransferProgress object as it is updated - // from another thread when any chunk of data is transmitted. + // It's important to note that this method will always operate over the + // last version of the same TransferProgress object as it is updated + // from another thread when any chunk of data is transmitted. // This will not create any inconsistencies, because the only // attribute that can be different is getTransferredBytes which will // be read just once per call, nor race conditions @@ -136,21 +156,25 @@ public class Queue extends JFrame implements IQueueFrame { // will go down (e.g. from 50% to 49%). @Override public void manageTransferProgress(TransferProgress transferProgress) { - - // Remember that when QueueController calls frame.manageTransferProgress(transferProgress), - // here transferProgress might have different attributes than it was originally called on + + // Remember that when QueueController calls + // frame.manageTransferProgress(transferProgress), + // here transferProgress might have different attributes than it was + // originally called on // (as it's updated by a different thread). // We do not need a lock as we do not edit it, but just keep it in mind. - - if(!controller.isTransferProgressInHashMap(transferProgress)) { - controller.putTableIndex(transferProgress, - addRow(transferProgress.getSource(), - transferProgress.getDestination(), - transferProgress.getOperation() == SftpProgressMonitor.GET? "Download" : "Upload", - controller.computePercentage(transferProgress))); - } - else { - updateRow(controller.getTableIndex(transferProgress), controller.computePercentage(transferProgress)); + + if (!controller.isTransferProgressInHashMap(transferProgress)) { + controller.putTableIndex(transferProgress, addRow( + transferProgress.getSource(), + transferProgress.getDestination(), + transferProgress.getOperation() == SftpProgressMonitor.GET + ? "Download" + : "Upload", + controller.computePercentage(transferProgress))); + } else { + updateRow(controller.getTableIndex(transferProgress), + controller.computePercentage(transferProgress)); } } }