From b036b13a62467f0d23baf530d8cb0c16899cd2e0 Mon Sep 17 00:00:00 2001 From: ATnayan Date: Sun, 5 Apr 2020 21:32:39 +0300 Subject: [PATCH] [Single-Instance] Opening a jar from OS opens a tab in currently opened instance --- pom.xml | 2 +- src/us/deathmarine/luyten/Luyten.java | 77 ++++++++++++++++++++---- src/us/deathmarine/luyten/LuytenOsx.java | 3 +- 3 files changed, 68 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 42f9bfe..35fb2b6 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 us.deathmarine luyten - 0.6.0 + 0.7.0 com.fifesoft diff --git a/src/us/deathmarine/luyten/Luyten.java b/src/us/deathmarine/luyten/Luyten.java index e0495d2..6c5bd7b 100644 --- a/src/us/deathmarine/luyten/Luyten.java +++ b/src/us/deathmarine/luyten/Luyten.java @@ -7,13 +7,11 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; import java.net.URI; +import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; import java.util.List; import java.util.ArrayList; @@ -40,8 +38,20 @@ public class Luyten { private static final AtomicReference mainWindowRef = new AtomicReference<>(); private static final List pendingFiles = new ArrayList<>(); + private static ServerSocket lockSocket = null; - public static void main(String[] args) { + public static void main(final String[] args) { + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + @Override + public void run() { + try { + if (lockSocket != null) { + lockSocket.close(); + } + } catch (IOException e) { + } + } + })); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); @@ -55,12 +65,41 @@ public class Luyten { // .zip or .jar) final File fileFromCommandLine = getFileFromCommandLine(args); + try { + launchMainInstance(fileFromCommandLine); + } catch (Exception e) { + // Instance already exists. Open new file in running instance + try { + Socket socket = new Socket("localhost", 3456); + DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); + dos.writeUTF(args[0]); + dos.flush(); + dos.close(); + socket.close(); + } catch (IOException ex) { + showExceptionDialog("Exception", e); + } + } + } + + private static void launchMainInstance(final File fileFromCommandLine) throws IOException { + lockSocket = new ServerSocket(3456); + launchSession(fileFromCommandLine); + new Thread(new Runnable() { + @Override + public void run() { + launchServer(); + } + }).start(); + } + + private static void launchSession(final File fileFromCommandLine) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (!mainWindowRef.compareAndSet(null, new MainWindow(fileFromCommandLine))) { // Already set - so add the files to open - openFileInInstance(fileFromCommandLine); + addToPendingFiles(fileFromCommandLine); } processPendingFiles(); mainWindowRef.get().setVisible(true); @@ -68,9 +107,24 @@ public class Luyten { }); } + private static void launchServer() { + try { // Server + while (true) { + Socket socket = lockSocket.accept(); + DataInputStream dis = new DataInputStream(socket.getInputStream()); + addToPendingFiles(getFileFromCommandLine(dis.readUTF())); + processPendingFiles(); + dis.close(); + socket.close(); + } + } catch (IOException e) { // Client + showExceptionDialog("Exception", e); + } + } + // Private function which processes all pending files - synchronized on the // list of pending files - private static void processPendingFiles() { + public static void processPendingFiles() { final MainWindow mainWindow = mainWindowRef.get(); if (mainWindow != null) { synchronized (pendingFiles) { @@ -84,13 +138,12 @@ public class Luyten { // Function which opens the given file in the instance, if it's running - // and if not, it processes the files - public static void openFileInInstance(File fileToOpen) { + public static void addToPendingFiles(File fileToOpen) { synchronized (pendingFiles) { if (fileToOpen != null) { pendingFiles.add(fileToOpen); } } - processPendingFiles(); } // Function which exits the application if it's running @@ -101,7 +154,7 @@ public class Luyten { } } - public static File getFileFromCommandLine(String[] args) { + public static File getFileFromCommandLine(String... args) { File fileFromCommandLine = null; try { if (args.length > 0) { diff --git a/src/us/deathmarine/luyten/LuytenOsx.java b/src/us/deathmarine/luyten/LuytenOsx.java index 46670ae..3ba653d 100644 --- a/src/us/deathmarine/luyten/LuytenOsx.java +++ b/src/us/deathmarine/luyten/LuytenOsx.java @@ -16,7 +16,8 @@ public class LuytenOsx extends Luyten { Application app = new Application(); app.addApplicationListener(new ApplicationAdapter() { public void handleOpenFile(ApplicationEvent e) { - Luyten.openFileInInstance(new File(e.getFilename())); + Luyten.addToPendingFiles(new File(e.getFilename())); + Luyten.processPendingFiles(); } public void handleQuit(ApplicationEvent e) {