Skip to content

Commit 2577ed6

Browse files
author
Paulsen
committed
v1.1.4a
Changed: - PInstance knows and calls a function when another instance with the same port tries to open
1 parent 43d8d1a commit 2577ed6

File tree

2 files changed

+70
-15
lines changed

2 files changed

+70
-15
lines changed

src/ooo/paulsen/demo/Demo.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import java.awt.event.KeyEvent;
1414
import java.awt.event.KeyListener;
1515
import java.io.IOException;
16-
import java.net.BindException;
1716

1817
public class Demo {
1918

@@ -39,13 +38,20 @@ public static void main(String[] args) {
3938
public Demo() {
4039

4140
try {
42-
PInstance p = new PInstance(8123);
43-
} catch (BindException e) {
41+
PInstance p = new PInstance(8123, new Runnable() {
42+
@Override
43+
public void run() {
44+
System.out.println("Focus that thing! Someone tried to open this exact program once again");
45+
f.setVisible(true);
46+
f.setState(JFrame.NORMAL);
47+
f.toFront();
48+
f.requestFocus();
49+
}
50+
});
51+
} catch (IOException e) {
4452
System.out.println("Already runs");
45-
JOptionPane.showMessageDialog(null,"Port 8123 already taken by another Process","Instance already running",JOptionPane.INFORMATION_MESSAGE);
53+
JOptionPane.showMessageDialog(null, "Port 8123 already taken by another Process", "Instance already running", JOptionPane.INFORMATION_MESSAGE);
4654
System.exit(0);
47-
} catch (IOException e) {
48-
throw new RuntimeException(e);
4955
}
5056

5157
frameTitle = "JPL-Demo - " + PSystem.getUserName() + "'s " + PSystem.getOSType() + "-System from " + PSystem.getUserDisplayLocation();

src/ooo/paulsen/utils/PInstance.java

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,87 @@
44
import java.net.BindException;
55
import java.net.InetAddress;
66
import java.net.ServerSocket;
7+
import java.net.Socket;
78

89
/**
910
* Used for singe-instance-Programms <br>
1011
* <a href="https://stackoverflow.com/questions/920386/how-to-allow-running-only-one-instance-of-a-java-program-at-a-time">Source</a>
1112
*/
1213
public class PInstance {
1314

14-
private static int PORT;
15-
private static ServerSocket socket;
15+
private int PORT;
16+
private Runnable connectAction;
17+
private ServerSocket serverSocket;
1618

1719
/**
1820
* Creates/reserves a local Port to indicate that this Program is running.
19-
* @param port has to be in Range and not be allocated by <a href="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml">another program</a>
20-
* @throws BindException if Another Instance already exists
21-
* <br>IOException if the socket failed
21+
*
22+
* @param port has to be in Range and not be allocated by <a href="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml">another program</a>
23+
* @param connectAction is the Function that is called when some program connects to it
24+
* @throws IOException if the socket failed or Another Instance already exists
2225
*/
23-
public PInstance(int port) throws IOException, BindException {
26+
public PInstance(int port, Runnable connectAction) throws IOException {
2427
PORT = port;
28+
this.connectAction = connectAction;
2529

26-
//Bind to localhost adapter with a zero connection queue
27-
socket = new ServerSocket(PORT, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
30+
callServer();
31+
initServer();
32+
}
33+
34+
/**
35+
* Looks for a Server/Process that waits for a connection
36+
*/
37+
private void callServer() {
38+
try {
39+
Socket s = new Socket("127.0.0.1", PORT);
40+
} catch (IOException e) {
41+
// No Other Instance found (or other error)
42+
}
2843
}
2944

3045
/**
46+
* Inits Server
3147
*
48+
* @throws IOException if the socket failed or Another Instance already exists
49+
*/
50+
private void initServer() throws IOException {
51+
52+
//Bind to localhost adapter with a zero connection queue
53+
serverSocket = new ServerSocket(PORT, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
54+
Thread t = new Thread(new Runnable() {
55+
@Override
56+
public void run() {
57+
while (true) {
58+
try {
59+
60+
// look for connection
61+
serverSocket.accept();
62+
63+
// execute Function if some other program connected (to e.g. focus the older UI-Instance)
64+
if (connectAction != null)
65+
connectAction.run();
66+
67+
// close and reopen server
68+
serverSocket.close();
69+
serverSocket = new ServerSocket(PORT, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
70+
} catch (IOException e) {
71+
// Address already in Use
72+
throw new RuntimeException(e);
73+
}
74+
}
75+
}
76+
});
77+
t.start();
78+
}
79+
80+
/**
3281
* @param port
3382
* @return if a local Program, which reserves/uses a Port, is running.
3483
*/
3584
public static boolean isInstanceRunning(int port) {
3685
try {
3786
//Bind to localhost adapter with a zero connection queue
38-
socket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
87+
ServerSocket serverSocket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
3988
} catch (BindException e) {
4089
return true;
4190
} catch (IOException e) {

0 commit comments

Comments
 (0)