2016-08-19 3 views
0

Как получить разрешение экрана приложения (при изменении размера), но только после того, как мышь была выпущена?JavaFX: ChangeListener, чтобы получить разрешение экрана на мыши.

Я осмотрелся, но ничего не нашел. Я сделал это:

scene.widthProperty().addListener(new ChangeListener<Number>() { 
    @Override 
    public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
     ConfigBusiness.getInstance().setScreenWidth(newValue.intValue()); 
    } 
}); 

scene.heightProperty().addListener(new ChangeListener<Number>() { 
    @Override 
    public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
     ConfigBusiness.getInstance().setScreenHeight(newValue.intValue()); 
    } 
}); 

Но, как вы ожидаете, каждый раз изменения ширины/высоты, она вызывает функцию для сохранения значения (в моем случае, в реестре, что приводит к многократным вызовам).

Есть ли способ получить значение только при отпускании кнопки мыши? Или, может быть, использовать другого слушателя (setOnMouseDragRelease или что-то в этом роде)?

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

Благодаря

EDIT 2: После чуток идею @Tomas Bisciak, я пришел с этой идеей.

 scene.widthProperty().addListener(new ChangeListener<Number>() { 
      @Override 
      public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
       if(!widthHasChanged()){ 
        setWidthChanged(true); 
        System.out.println("Width changed"); 
       } 
      } 
     }); 

     scene.heightProperty().addListener(new ChangeListener<Number>() { 
      @Override 
      public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
       if(!heightHasChanged()){ 
        setHeightChanged(true); 
        System.out.println("Height changed"); 
       } 
      } 
     }); 


     scene.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent event) { 
       if(widthHasChanged()){ 
        ConfigBusiness.getInstance().setScreenWidth(scene.getWidth()); 
        System.out.println("Width changed > release"); 
        setWidthChanged(false); 
       } 

       if(heightHasChanged()){ 
        ConfigBusiness.getInstance().setScreenHeight(scene.getHeight()); 
        System.out.println("Height changed > release"); 
        setHeightChanged(false); 
       } 
      } 
     }); 

Я помечено изменения сделанных во время изменения размера процесса (с помощью widthProperty и heightProperty) и установить их верно, если будет изменен, и при отпускании мышей, я установить значение, если они изменились.

Проблема в том, что последнее событие MOUSE_RELEASED не запускается. Я вижу выход с changeListener с, но не eventFilter. Есть идеи ?

+1

Вы хотите разрешение экрана монитора или из окна приложения? Потому что я вижу, что вы получаете ширину и высоту окна приложения. – GOXR3PLUS

+0

Из окна приложения. Фактически, я просто хочу, чтобы пользователь мог изменить размер окна приложения так, как он хочет, и сохранить эту информацию для дальнейшего использования. – Jacks

ответ

1

я наконец-то нашел способ сделать «более или менее» что я хотел.Вот код для тех, кто ищет, как это сделать.

 ChangeListener<Number> resizeListener = new ChangeListener<Number>() { 
      Timer timer = null; // used to schedule the saving task 
      final long delay = 200; // the delay between 2 changes 
      TimerTask task = null; // the task : saves resolution values 

      @Override 
      public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
       // cancels the old task as a new one has been queried 
       // at every change, we cancel the old task and start a new one 
       if(task != null) task.cancel(); 
       // reset of the timer 
       if(timer == null) timer = new Timer(); 

       task = new TimerTask() { 
        @Override 
        public void run() { 
          ConfigBusiness.getInstance().setScreenWidth(scene.getWidth()); 
          ConfigBusiness.getInstance().setScreenHeight(scene.getHeight()); 
          // stopping the timer once values are set 
          timer.cancel(); 
          timer = null; 
          // stopping the task once values are set 
          task.cancel(); 
          task = null; 
         } 
        }; 

       timer.schedule(task, delay); 
      } 
     }; 

     scene.widthProperty().addListener(resizeListener); 
     scene.heightProperty().addListener(resizeListener); 

Я добавил несколько комментариев, чтобы помочь понять, как это работает. Во время изменения размера таймер планирует задачу для извлечения ширины/высоты окна и запускается.

Если другой изменяет доходы, тогда задача «перезагружается», чтобы получить только последние установленные значения.

После получения значений важно очистить таймер и задачу, иначе потоки продолжатся.

Спасибо всем, кто дал мне подсказки о том, как это сделать, надеюсь, что это поможет!

1

Hook слушатель на сцене Handle mouse event anywhere with JavaFX (используйте MouseEvent.MOUSE_RELEASED) и на значениях записи релиз мыши в setScreenHeight/ширине (на каждом выпуске мыши),

, если вы хотите только записать значения, когда сопротивление было с целью изменить размер, использовать флаг boolean в методах change() «flag = true on change», чтобы указать, что изменение началось, а потом на выводе мыши просто записывать значения везде, где вы хотите, и установить флаг (flag = false).

+0

Можете ли вы прояснить свой второй абзац? «Использовать логический флаг в change()» => Функция «change()» в «changeListener»? Это именно то, что я ищу: запись значений, когда перетаскивание произошло с намерением изменить размер. – Jacks

+0

@Jacks, да, в смене слушателей, каждый раз, когда вы вызываете метод changed(), установите значение true, чтобы вы знали, что кто-то в настоящее время изменяет размер вашей сцены. Теперь в вашем eventHandler, когда мышь освобождается, вы проверяете флаг, если этот флаг является истинным, означает, что до того, как он был выпущен, одно из свойств или оба были изменены, поэтому теперь вы можете сохранить или записать свои значения (а затем установить флаг обратно в false). –

+0

@Jacks, что логический флаг может быть статичным и даже не должен быть изменчивым, поскольку только JFXAT обращается к нему. –

1

Если вы хотите каждый раз, когда мышь отпускается, чтобы получить разрешение экрана монитора вот код:

Если у вас есть код для Stage и Scene вы можете добавить прослушиватель для MouseReleasedEvent как это:

public double screenWidth ; 
public double screenHeight; 

....... 

scene.setOnMouseReleased(m->{ 
    screenWidth = Screen.getPrimary().getBounds().getWidth(); 
    screenHeight = Screen.getPrimary().getBounds().getHeight(); 
}); 

...... 

В случае, если у вас есть непараметризованное окно, в котором вы изменить размер вручную когда мышь дра gged я рекомендую вам с помощью setOnMouseDragged();

Предполагая, что вы делаете выше этого кода для перемещения окна вручную может быть полезным:

public int initialX; 
public int initialY; 
public double screenWidth = Screen.getPrimary().getBounds().getWidth() ; 
public double screenHeight = Screen.getPrimary().getBounds().getHeight(); 

    setOnMousePressed(m -> { 
       if (m.getButton() == MouseButton.PRIMARY) { 
        if (m.getClickCount() == 1) { // one Click 
         setCursor(Cursor.MOVE); 
         if (window.getWidth() < screenWidth) { 
          initialX = (int) (window.getX() - m.getScreenX()); 
          initialY = (int) (window.getY() - m.getScreenY()); 
         } else 
          setFullScreen(false); 
        } else if (m.getClickCount() == 2) // two clicks 
         setFullScreen(true); 

       } 

      }); 

      setOnMouseDragged(m -> { 
       if (window.getWidth() < screenWidth && m.getButton() == MouseButton.PRIMARY) { 
        window.setX(m.getScreenX() + initialX); 
        window.setY(m.getScreenY() + initialY); 
       } 
      }); 

      setOnMouseReleased(m -> setCursor(Cursor.DEFAULT)); 
+0

Вопрос был о окне приложения, извините, я забыл упомянуть об этом четко ... – Jacks

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