2016-05-06 7 views
1

У меня сложный вопрос, для которого я сначала нарисую фон, чтобы сделать вещи более понятными.Как разрешить только один случай .Jar, и позволить ему использовать Args из других попыток?

фон

Я сделал аудиоплеер в Java, которая может быть запущена с командной строкой аргументами, а также без них. Приложение .jar приложения (сделанное с Netbeans) завернуто в файл .exe (сделанный с Launch4j), так что вы можете открыть, например, mp3-файл с .exe, а затем .jar внутри принимает путь к файлу в его строке [] арг.

Проблема с этим подходом (на данный момент) заключается в том, что если вы одновременно выбираете несколько mp3-файлов и открываете их одновременно, все они открываются в отдельных окнах аудиоплеера. Однако я хочу, чтобы все файлы открывались в одном экземпляре приложения.

То, что я тогда попытался, - позволить Launch4j разрешить только один экземпляр .jar/.exe в надежде, что все выбранные файлы будут открыты в одном приложении, это не помогло.

Что я вижу, как решение

Так что я хочу, чтобы иметь возможность выбрать несколько файлов .mp3 в окнах, и что все их Путь к файлам передаются дальше, как аргумент командной строки для одного экземпляра заявление. Или другой подход, имеющий тот же результат. Кто-нибудь знает, как реализовать это в реальном приложении?

Большое спасибо заранее. Я попытаюсь продолжить поиск потенциальных решений и идей.

- редактирует -

Основной метод готов к приему нескольких файлов. Я выполнил кусок кода, который сохраняет все аргументы командной строки приложения в файл .txt, и когда я разрешаю только один экземпляр с файлом Launch4j .exe, в текстовом файле появляется только один аргумент. когда я пытаюсь открыть несколько mp3-файлов.

Если я разрешаю .exe иметь несколько экземпляров, то я просто запускаю приложение .jar несколько раз (один раз для каждого файла, который я пытаюсь открыть).

+0

Ваш метод 'main' готов для получения нескольких путей к файлу в качестве аргументов? – Berger

+0

@Berger Да, main готов принимать несколько путей к файлу в качестве аргументов. Я сделал тестовый файл, чтобы узнать, что такое аргументы, и каждый раз только один путь к файлу показан как аргумент. – ImJustACowLol

+0

Используйте Socket ... – MadProgrammer

ответ

1

Я зафиксировал его, после нескольких часов программирования и с перерывами между ними

package argsbuilder; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.PrintStream; 

public class ArgsBuilder 
{ 

public static void main(String[] args) 
{ 
    checkIfRunning(args); 
} 

private static void checkIfRunning(String[] args) 
{ 
    buildFile(args); 

    ProcessBuilder pb = new ProcessBuilder("core.exe"); //core.exe is a .exe wrapper with the .jar audioplayer in it 
    try 
    { 
     Process p = pb.start(); 
    }catch (IOException f){System.out.println(f);} 
} 

private static void buildFile(String[] args) 
{ 
    try 
    { 
     boolean notdone = true; 
     int i=0; 
     File f; 
     while(notdone) 
     { 
      f = new File("arg" + i + ".txt"); 
      if(f.exists()) 
      { 
       i++; 
      } 
      else 
      { 
       PrintStream out = new PrintStream(new FileOutputStream(new File("Folder Location" + "arg" + i + ".txt"))); 
       System.setOut(out); 
       System.out.println(args[0]); 
       notdone = false; 
      } 
     } 
    }catch(Exception g){System.out.println(g);} 
}} 

Что выше делает Вышеуказанных проверок приложений, если есть и другие файлы аргументы, и если есть это будет продолжайте генерировать новое имя, пока имя не будет бесплатным. Затем он печатает аргумент этого файла. После того, как он напечатал аргумент, он запускает аудиоплеер. В аудиоплеера происходит следующее:

import javafx.embed.swing.JFXPanel; 
import java.net.InetAddress; 
import java.net.ServerSocket; 

public class YourApp { 

public static void main(String[] args) 
{ 
    try 
    { 
    socket = new ServerSocket(PORT,0,InetAddress.getByAddress(new byte[] {127,0,0,1})); 


    //Everything you need to launch the application in the try 
    }catch(Exception g){//Nothing in the catch} 
}} 

Вышеприведенный делает Он пытается претендовать на ServerSocket для себя. Если он уже есть, он не запускает приложение. Таким образом, только один экземпляр будет работать одновременно. (в PORT вы просто заполняете случайное целое число).

Сочетание этих 2, вы можете прочитать текстовые файлы, созданные первым приложением, и интерпретировать их как аргументы во втором приложении.

Как он интерпретирует их как аргументы? Ну, у меня уже был таймер, закрепленный в программе, и я говорю аудиоплееру искать самый первый файл arg (arg0.txt) в указанной папке. Если он находит это, он добавляет его в arraylist вместе со всеми файлами arg + i.txt.

Возможно, это не самый быстрый способ, но он, безусловно, хорошо работает.

2

Я использовал Java RMI (удаленный метод Invokation), чтобы сделать приложение в одного экземпляра.

RMI пытается прослушивать сокет с определенным пользователем номером порта.

При запуске банки.

  • Если никто не обслуживает этот порт, то этот экземпляр является сервером RMI. Установите окно GUI. Вызовите open с основными аргументами.
  • Если уже есть приложение-приложение, отправьте RMI с помощью аргументов main. Затем выйдите нормально, вернитесь с главной.

Код: Непроверено, как вы, вероятно, хотите устроить все по-другому.

public interface OpenRMI extends Remote { 
    void open(String[] args) throws RemoteException; 
} 

public class SingleInstanceApp implements OpenRMI { 

    private static final String RMI_ENTRY = "ImJustACowLolAudioPlayer"; 

    public static void main(String[] args) throws RemoteException, 
      AccessException, NotBoundException { 
     System.out.println("main " + Arrays.toString(args)); 
     if (System.getSecurityManager() == null) { 
      System.setSecurityManager(new SecurityManager()); 
     } 
     Registry registry = LocateRegistry.getRegistry(); 
     OpenRMI openRMI; 
     try { 
      System.out.println("bind with new OpenRMI"); 
      SingleInstanceApp app = new SingleInstanceApp(); 
      openRMI = (OpenRMI) UnicastRemoteObject.exportObject(app, 0); 
      registry.bind(RMI_ENTRY, openRMI); 
      System.out.println("Player bound"); 
      app.create(); // Server. 
     } catch (AlreadyBoundException e2) { 
      System.out.println("lookup as someone else bound before us"); 
      openRMI = (OpenRMI) registry.lookup(RMI_ENTRY); // Client. 
     } 
     openRMI.open(args); 
    } 

    private void create() { 
     new Thread(true) { // Daemon thread, or start GUI 
      @Override 
      public void run() { 
       System.out.println("create " + this); 
       for (int i = 0; i < 10; ++i) { 
        Thread.sleep(1000L); 
       } 
       shutdown(); 
      } 
     } 
    } 

    private void shutdown() throws RemoteException, 
      NotBoundException, AccessException { 
     System.out.println("close " + this); 
     Registry registry = LocateRegistry.getRegistry(); 
     registry.unbind(RMI_ENTRY); 
    } 

    @Override 
    public void open(String[] args) throws RemoteException { 
     System.out.println("open " + this + ": " + Arrays.toString(args)); 
    } 
} 

Я ожидал бы еще более достойных классов.

+0

Я попытаюсь реализовать это. Я дам вам знать, если это сработает :) – ImJustACowLol

+0

Также вы можете показать пример кода того, как вы это сделали? Весь материал в этой теме относится к области, в которой я совершенно новичок. – ImJustACowLol