2016-12-12 1 views
0

Ich würde gerne wissen, was genau passiert, wenn das rote Kreuz in Dialog Witwen gedrückt wird.JavaFX Standard-Implementierung von Closing Windows

Ich habe einen Dialog, der Daten zu einem dynamischen LineChart hinzufügt und das Diagramm mit dem neuen Punkt aktualisiert. Das Problem ist, dass wenn ich den Dialog programmgesteuert nach dem Hinzufügen von Job, die Benutzeroberfläche nicht ordnungsgemäß aktualisiert. Aber wenn ich es nicht programmgesteuert schließe und nur die Standard Kreuztaste drücke, ist alles in Ordnung.

Mein Schluss Code war die folgende Zeile, die die UI nie richtig aktualisiert:

((Button)actionEvent.getSource()).getScene().getWindow().hide(); 

und wenn ich so verwenden Platform.runLater() zu, ist es manchmal Updates und manchmal nicht!

Platform.runLater(new Runnable() { 
       @Override 
       public void run() { 
        ((Button)actionEvent.getSource()).getScene().getWindow().hide(); 
       } 
      }); 

BTW, wenn Sie sehen möchten, wie die Aktualisierung Job geht, hier ist es:

Ich habe einen Dialog, der in einer fxml-Datei definiert ist und zwei Textfelder für x bekommen und y und auch eine Schaltfläche hinzufügen. Diese Schaltfläche Add hat eine onAction-Methode namens handleAddButton(), die in der DialogController Klasse definiert ist. Dann in diesem Verfahren, nenne ich die addData() Methode aus der LineChartController Klasse wie folgt:

public void handleAddButton(ActionEvent actionEvent) { 

    Number x = new NumberStringConverter().fromString(timeField.getText()); 
    Number y = new NumberStringConverter().fromString(bandWidthField.getText()); 

    lineChartController.addData(x, y); 

    Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 
       ((Button)actionEvent.getSource()).getScene().getWindow().hide(); 
      } 
     }); 
} 

und dies ist die addData() Methode Implementierung in der LineChartController Klasse:

public void addData(Number xValue, Number yValue){ 

     if(xValue.intValue() < 0 || xValue.intValue() > 3000 || 
       yValue.intValue() < 0 || yValue.intValue() > 1000) 
      return; 
     XYChart.Data<Number , Number> data = 
       new XYChart.Data<>(SystemUtil.round(xValue.intValue()), SystemUtil.round(yValue.intValue())); 
     seri.getData().add(data); 

     Node currentNode = data.getNode(); 
     currentNode.setCursor(Cursor.HAND); 
     currentNode.setOnMouseDragged(event -> { 
      Point2D pointInScene = new Point2D(event.getSceneX(), event.getSceneY()); 
      double xPosInAxis = timeAxis.sceneToLocal(new Point2D(pointInScene.getX(), 0)).getX(); 
      double yPosInAxis = bandWidthAxis.sceneToLocal(new Point2D(0, pointInScene.getY())).getY(); 
      int x = timeAxis.getValueForDisplay(xPosInAxis).intValue(); 
      int y = bandWidthAxis.getValueForDisplay(yPosInAxis).intValue(); 
      data.setXValue(SystemUtil.round(x)); 
      data.setYValue(SystemUtil.round(y)); 
     }); 
     currentNode.setOnContextMenuRequested(e -> { 

      if(chartContextMenu.isShowing()) 
       chartContextMenu.hide(); 
      dataContextMenu.setUserData(data); 
      dataContextMenu.show(lineChart1, e.getScreenX(), e.getScreenY()); 
     }); 
    } 

Ich wünschte, ich könnte wissen, was genau das Standard-Schließen tut, was alles in Ordnung hält und was mit meinem Code nicht stimmt.

+0

Wie erhalten Sie x, y aus dem Dialog? – Omid

+0

@omid 'Anzahl x = new NumberStringConverter(). FromString (timeField.getText());' –

+1

Ich glaube nicht, dass das Problem mit der addData-Methode ist. Werden x, y richtig abgerufen? Kannst du bitte den Code für den Dialog hinzufügen, wie du ihn zeigst und woher du x und y bekommst? Ohne das ist es nicht möglich, Ihnen zu helfen. – Omid

Antwort

-1

Schließlich fand ich die Lösung. Es sieht so aus, als ob die native Close-Schaltfläche eine Verzögerung vor dem Ausblenden des Dialogfelds darstellt und die Hintergrundoperation den Job ordnungsgemäß ausführen lässt.

So, jetzt, nur um die Umsetzung diese Einschlafzeit am Ende der addData() Methode, alles ist in Ordnung:

try { 
     Thread.sleep(30); 
} catch (InterruptedException e) { 
     e.printStackTrace(); 
} 

Es ist klar, dass das Hinzufügen dieses Teils in den handleAddButton() Verfahren und kurz vor dem Schlusscode funktioniert auch. Aber weil ich die addData() von vielen Orten aus anrufe, zog ich es vor, es dort zu setzen.

+1

Ich verstehe ernsthaft nicht, wie dies geschehen kann, wenn alle diese auf dem Anwendungsthread ausgeführt werden. 'addData()' soll die Ausführung beenden, bevor 'hide()' erreicht und ausgeführt wird. – Jai

+1

Ihr "Workaround" weist auf ein Threading-Problem hin - es gibt also wahrscheinlich einen Fehler an einer anderen Stelle in Ihrem Code. Wenn Sie einen [mcve] wie @James_D empfohlen haben, wäre es möglich, Ihnen mehr zu helfen. – assylias

+0

Das ist Unsinn. Wie können Sie sicher sein, dass 30 Millisekunden immer ausreichen werden? Sie haben etwas grundsätzlich falsches an dem Code, den Sie uns nicht zeigen: Die Lösung ist, das zu beheben, nicht irgendeinen willkürlichen Hack wie diesen zu verwenden. –