2016-12-12 1 views
0

Я хотел бы знать, что именно происходит, когда красный крест нажимается в диалоговых вдовах.JavaFX Реализация по умолчанию для закрытия Windows

У меня есть диалог, который добавляет данные в динамический LineChart и обновляет график с новой точкой. Проблема в том, что при закрытии диалогового окна программно после добавления задания пользовательский интерфейс не обновляется должным образом. Но если я не закрываю его программно и просто нажимаю кнопку по умолчанию, все в порядке.

Мой код закрытия была следующей строки, которая не обновляется интерфейс правильно:

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

и когда я использую Platform.runLater() сделать так, иногда обновления, а иногда нет!

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

Кстати, если вы хотите увидеть, как работа обновление идет, вот она:

У меня есть диалог, который определен в файле FXML и имеет два текстовых поля для получения х и у, а также a Добавить кнопку. Эта кнопка Add имеет метод onAction под названием handleAddButton(), который определен в классе DialogController. Тогда в этом методе, я называю addData() метод из LineChartController класса, как показано ниже:

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(); 
      } 
     }); 
} 

И Это реализация addData() метод в LineChartController классе:

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()); 
     }); 
    } 

Я хотел бы знать, что точно закрытие по умолчанию делает, что держит все в порядке и что не так с моим кодом.

+0

Как вы извлекаете x, y из диалога? – Omid

+0

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

+1

Я не думаю, что проблема связана с методом addData. Правильно ли получены х, у? Можете ли вы добавить код для диалога, как вы его показываете и где вы получаете x и y от него? Без этого вам не поможет. – Omid

ответ

-1

Наконец-то я нашел решение. Кажется, что родная закрывающая кнопка каким-то образом ставит задержку, прежде чем скрывать диалоговое окно и позволяет фоновой работе правильно выполнять работу.

Так теперь, только поставив на этот раз сна в конце метода addData(), все в порядке:

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

Понятно, что добавление этой части в методе handleAddButton() и непосредственно перед кодом закрытия , также работает. Но я вызываю addData() из многих мест, я предпочел поместить его туда.

+1

Я серьезно не понимаю, как это может произойти, если все они работают в потоке приложения. 'addData()' должен завершить свое выполнение до того, как 'hide()' будет достигнуто и выполнено. – Jai

+1

Ваш «обходной путь» указывает на проблему с потоками - значит, в вашем коде есть ошибка. Если вы разместили [mcve], например, @James_D, можно было бы помочь вам больше. – assylias

+0

Это вздор. Как вы можете быть уверены, что 30 миллисекунд всегда будет достаточно? У вас есть что-то принципиально неправильное в коде, который вы нам не показываете: решение заключается в том, чтобы исправить это, а не использовать какой-то произвольный хак. –