2015-12-08 7 views
0

Мой код в настоящее время читает мой почтовый ящик Gmail через IMAP (imaps) и javamail, и как только он находит электронное письмо с приложением zip/xap, он отображает сцену (окно), спрашивая, загружать ли файл, да или нет.Запуск нескольких приложений JavaFX в цикле

Я хочу, чтобы сцена закрывалась, когда я делаю выбор, а затем возвращаюсь к месту в цикле, из которого пришел звонок. Моя проблема возникает из-за того, что вы не можете запускать приложение более одного раза, поэтому я читаю here, что должен написать Platform.setImplicitExit(false); в методе start, а затем использовать primartyStage.hide() (?), А затем что-то вроде Platform.runLater(() -> primaryStage.show());, когда мне нужно снова отобразить сцену позже.

Проблемы встречающаяся в настоящее время является то, что поток команды начинается в doit() методе Mail.java, который петли через мой почтовый ящик, и launch(args) происходит в пределах for loop в рамках метода. Это означает, что launch(args) затем вызывает start, чтобы установить сцену и показать сцену. Поскольку существует связанный с ним Controller.java и fxml, класс Controller имеет обработчик событий для кнопок сцены, которые «перехватывают» поток один раз start показали сцену. Поэтому, когда я нажимаю «Да» или «Нет», он скрывает сцену, но затем только висит там. Как будто он не может вернуться к методу start, чтобы продолжить цикл, из которого произошел запуск (args). Как правильно скрыть/показать сцену, когда это необходимо, чтобы цикл продолжался, если нажать или нет.

Это код для Mail.java и Controller.java. Большое спасибо!

Mail.java

[Other variables set here] 
    public static int launchCount = 0;@FXML public Text subjectHolder; 

    public static ReceiveMailImap obj = new ReceiveMailImap(); 

    public static void main(String[] args) throws IOException,  MessagingException { 
     ReceiveMailImap.doit(); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     loader = new FXMLLoader(getClass().getResource("prompts.fxml")); 
     root = loader.load(); 
     controller = loader.getController(); 
     controller.setPrimaryStage(primaryStage); 
     scene = new Scene(root, 450, 250); 
     controller.setPrimaryScene(scene); 
     scene.getStylesheets().add("styleMain.css"); 
     Platform.setImplicitExit(false); 
     primaryStage.setTitle("Download this file?"); 
     primaryStage.initStyle(StageStyle.UNDECORATED); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void doit() throws MessagingException, IOException { 
     Folder inbox = null; 
     Store store = null; 

     try { 
      Properties props = System.getProperties(); 
      Session session = Session.getDefaultInstance(props, null); 
      store = session.getStore("imaps"); 
      store.connect("imap.gmail.com", "[email protected]", "Password"); 
      inbox = store.getFolder("Inbox"); 
      inbox.open(Folder.READ_WRITE); 
      Message[] messages = inbox.getMessages(); 
      FetchProfile fp = new FetchProfile(); 
      fp.add(FetchProfile.Item.ENVELOPE); 
      fp.add(UIDFolder.FetchProfileItem.FLAGS); 
      fp.add(UIDFolder.FetchProfileItem.CONTENT_INFO); 
      fp.add("X-mailer"); 

      inbox.fetch(messages, fp); 
      int doc = 0; 
      int maxDocs = 400; 
      for (int i = messages.length - 1; i >= 0; i--) { 
       Message message = messages[i]; 
       if (doc < maxDocs) { 
        doc++; 
        message.getSubject(); 

        if (!hasAttachments(message)) { 
         continue; 
        } 
        String from = "Sender Unknown"; 
        if (message.getReplyTo().length >= 1) { 
         from = message.getReplyTo()[0].toString(); 
        } else if (message.getFrom().length >= 1) { 
         from = message.getFrom()[0].toString(); 
        } 
        subject = message.getSubject(); 
        if (from.contains("[email protected]")) { 
         saveAttachment(message.getContent()); 
         message.setFlag(Flags.Flag.SEEN, true); 
        } 
       } 
      } 
     } finally { 
      if (inbox != null) { 
       inbox.close(true); 
      } 
      if (store != null) { 
       store.close(); 
      } 
     } 
    } 

    public static boolean hasAttachments(Message msg) throws MessagingException, IOException { 
     if (msg.isMimeType("multipart/mixed")) { 
      Multipart mp = (Multipart) msg.getContent(); 
      if (mp.getCount() > 1) return true; 
     } 
     return false; 
    } 

    public static void saveAttachment(Object content) 
    throws IOException, MessagingException { 
     out = null; in = null; 
     try { 
      if (content instanceof Multipart) { 
       Multipart multi = ((Multipart) content); 
       parts = multi.getCount(); 
       for (int j = 0; j < parts; ++j) { 
        part = (MimeBodyPart) multi.getBodyPart(j); 
        if (part.getContent() instanceof Multipart) { 
         // part-within-a-part, do some recursion... 
         saveAttachment(part.getContent()); 
        } else { 
         int allow = 0; 
         if (part.isMimeType("application/x-silverlight-app")) { 
          extension = "xap"; 
          allow = 1; 
         } else { 
          extension = "zip"; 
          allow = 1; 
         } 
         if (allow == 1) { 
          if (launchCount == 0) { 
           launch(args); 
           launchCount++; 
          } else { 
           Platform.runLater(() -> primaryStage.show()); 
          } 
         } else { 
          continue; 
         } 
        } 
       } 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (in != null) { in .close(); 
      } 
      if (out != null) { 
       out.flush(); 
       out.close(); 
      } 
     } 
    } 

    public static File createFolder(String subject) { 
     JFileChooser fr = new JFileChooser(); 
     FileSystemView myDocs = fr.getFileSystemView(); 
     String myDocuments = myDocs.getDefaultDirectory().toString(); 
     dir = new File(myDocuments + "\\" + subject); 
     savePathNoExtension = dir.toString(); 
     dir.mkdir(); 
     System.out.println("Just created: " + dir); 
     return dir; 
    } 

} 

Controller.java

public class Controller implements Initializable { 

    @FXML 
    private Text subjectHolder; 
    public Button yesButton, noButton; 
    public ReceiveMailImap subject; 

    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     subject= new ReceiveMailImap(); 
     subjectHolder.setText(subject.returnSubject()); 
    } 
    public Stage primaryStage; 
    public Scene scene; 

    @FXML 
    ComboBox<String> fieldCombo; 

    public void setPrimaryStage(Stage stage) { 
     this.primaryStage = stage; 
    } 

    public void setPrimaryScene(Scene scene) { 
     this.scene = scene; 
    } 

    public String buttonPressed(ActionEvent e) throws IOException, MessagingException { 
     Object source = e.getSource(); 
     if(source==yesButton){ 
      System.out.println("How to tell Mail.java that user clicked Yes?"); 
      return "POSITIVE";} 
     else{subject.dlOrNot("no"); 
      System.out.println("How to tell Mail.java that user clicked No?"); 
      primaryStage.hide(); 
      return "NEGATIVE";} 
    } 

} 

ответ

2

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

Причина код висит что Application.launch(...)

не возвращается, пока приложение не покинуло

В общем, вы вроде поняли весь жизненный цикл приложения JavaFX здесь. Вы должны думать о методе start(...) как эквивалент метода main(...) в «традиционном» приложении Java. Единственное, о чем нужно знать, это то, что start(...) выполняется в потоке приложения FX, поэтому, если вам нужно выполнить какой-либо блокирующий код, вам нужно поместить его в фоновый поток.

Метод start(...) передается в качестве примера для удобства, поскольку наиболее распространенной задачей является создание графика сцены и отображение его на сцене. Вы не обязаны использовать этот этап, но можете проигнорировать его и просто создать свои собственные этапы по мере необходимости.

Я думаю, что вы можете в основном структурировать свой код следующим образом (хотя, честно говоря, у меня есть довольно много проблем понимания того, что вы делаете):

public class Mail extends Application { 

    @Override 
    public void start(Stage ignored) throws Exception { 

     Platform.setImplicitExit(false); 

     Message[] messages = /* retrieve messages */ ; 
     for (Message message : messages) { 
      if (/* need to display window */) { 
       showMessage(message); 
      } 
     } 
    } 

    private void showMessage(Message message) { 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("prompts.fxml")); 
     Parent root = loader.load(); 

     Controller controller = loader.getController(); 
     Scene scene = new Scene(root, 450, 250); 
     stage.setScene(scene); 
     stage.initStyle(StageStyle.UNDECORATED); 
     stage.setTitle(...); 

     // showAndWait will block execution until the window is hidden, so 
     // you can query which button was pressed afterwards: 

     stage.showAndWait(); 

     if (controller.wasYesPressed()) { 
      // ... 
     } 
    } 

    // for IDEs that don't support directly launching a JavaFX Application: 
    public static void main(String[] args) { 
     launch(args); 
    } 
} 

Очевидно вашу логику решили ли показать окно более сложное, но это даст вам базовую структуру.

Чтобы проверить, какая кнопка была нажата, используйте showAndWait, как описано выше, а затем в контроллере сделать

public class Controller { 

    @FXML 
    private Button yesButton ; 

    private boolean yesButtonPressed = false ; 

    public boolean wasYesPressed() { 
     return yesButtonPressed ; 
    } 

    // use different handlers for different buttons: 
    @FXML 
    private void yesButtonPressed() { 
     yesButtonPressed = true ; 
     closeWindow(); 
    } 

    @FXML 
    private void noButtonPressed() { 
     yesButtonPressed = false ; // not really needed, but makes things clearer 
     closeWindow(); 
    } 

    private void closeWindow() { 
     // can use any @FXML-injected node here: 
     yesButton.getScene().getWindow().hide(); 
    } 
} 
+0

решаемые !! Джеймс, спасибо большое! Вы предоставили мне достаточно подробностей, чтобы исправить проблемы с моим кодом и ответить на мой главный вопрос. Я многому научился со своего поста. Очень ценим! Береги себя. –

Смежные вопросы