我正在使用一個ServerSocket端口來運行我的Java Swing應用程序的一個實例,所以如果用戶試圖打開該程序的另一個實例,我會向他顯示一條警告「另一個實例已經打開」。這工作正常,但沒有顯示此消息,我想設置專注於運行的應用程序本身,就像一些程序(MSN Messenger),即使它被最小化。如何設置焦點已運行的應用程序?
對於各種操作系統,是否有解決方案?
我正在使用一個ServerSocket端口來運行我的Java Swing應用程序的一個實例,所以如果用戶試圖打開該程序的另一個實例,我會向他顯示一條警告「另一個實例已經打開」。這工作正常,但沒有顯示此消息,我想設置專注於運行的應用程序本身,就像一些程序(MSN Messenger),即使它被最小化。如何設置焦點已運行的應用程序?
對於各種操作系統,是否有解決方案?
由於您使用服務器套接字我假設您使用java.net.BindException來檢測您的應用程序已在運行。如果您啓動第二個實例,則可以發送一條控制消息,指示您在退出之前先將應用程序標準化(如果已最小化)。
if (msg == BRING_TO_FRONT) {
frame.setState(Frame.NORMAL);
frame.toFront();
}
我不知道這是絕對正確的,但這裏的最終代碼我用它爲我工作得很好:
public class Loader {
private static final int PORT = 9999;
private static ServerSocket serverSocket = null; // Server
private static Socket socket = null; // CLient
private static final String focusProgram = "FOCUS";
public static void main(String[] args) {
if(!isProgramRunning()) {
Main main = new Main();
main.setVisible(true);
}
else {
System.exit(2);
}
}
private static boolean isProgramRunning() {
try {
serverSocket = new ServerSocket(PORT,0,InetAddress.getByAddress(new byte[] {127,0,0,1})); // Bind to localhost adapter with a zero connection queue.
SwingWorker<String, Void> anotherThread = new SwingWorker<String, Void>() { // Do some code in another normal thread.
@Override
public String doInBackground() { // This method is to execute a long code in the other thread in background.
serverSocketListener();
return "";
}
};
anotherThread.execute(); // Execute the other tread.
}
catch (BindException e) {
System.err.println("Already running.");
clientSocketListener();
return true;
}
catch (IOException e) {
System.err.println("Unexpected error.");
e.printStackTrace();
return true;
}
return false;
}
public static void serverSocketListener() { // Server socket
try {
System.out.println("Listener socket opened to prevent any other program instance.");
socket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
if(in.readLine().equals(focusProgram)) { // Restore the opened instance however you want.
Global.getCurrentFrame().setState(Frame.NORMAL);
Global.getCurrentFrame().toFront();
}
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
public static void clientSocketListener() { // Client socket
try{
socket = new Socket(InetAddress.getByAddress(new byte[] {127,0,0,1}), PORT);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(focusProgram);
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
}
}
我使用BindException但如何獲得「框架」實例? – Brad 2010-05-30 09:00:08
我想這裏的想法是從第二個應用程序實例中打開一個套接字客戶端,將它連接到第一個應用程序實例的套接字服務器,並使用此連接來告訴第一個應用程序將其置於前面。 – jfpoilpret 2010-05-30 10:02:38
正是第二個應用程序建立到第一個應用程序的連接併發送消息。第一個應用程序已經知道它的框架,並可以執行我的答案中提供的代碼片段。您無法以便攜方式枚舉窗口。 – stacker 2010-05-30 13:28:02