Nano Hash - криптовалюты, майнинг, программирование

Изменение курсора в приложении JavaFX для длительных операций

Я хотел бы изменить курсор на Cursor.WAIT при выполнении потенциально длительных операций в приложении JavaFX. Я думал, что мне поможет Platform.runLater:

this.getStage().getScene().setCursor(Cursor.WAIT);

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        // Do some stuff
        getStage().getScene().setCursor(Cursor.DEFAULT);
    }
});

Но курсор не меняется. Почему это не работает?

13.12.2013

  • setCursor следует вызывать в потоке fx... 13.12.2013

Ответы:


1

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

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        getStage().getScene().setCursor(Cursor.WAIT);
    }
});

// Do some stuff

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        getStage().getScene().setCursor(Cursor.DEFAULT);
    }
});

Или, если вы уже находитесь в потоке приложения JavaFX, вы можете использовать Сервис:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.concurrent.*;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ServiceWithCursorControl extends Application {
    private final Button runButton = new Button("Run");
    private final Label label = new Label();

    private final Service service = new Service() {
        @Override
        protected Task createTask() {
            return new Task<Void>() {
                @Override protected Void call() throws Exception {
                    // do stuff
                    Thread.sleep(5000);
                    return null;
                }
            };
        }
    };

    @Override public void start(Stage stage) {
        VBox layout = createLayout();

        Scene scene = new Scene(layout, 100, 80);
        stage.setScene(scene);

        bindUIandService(stage);

        stage.show();
    }

    private void bindUIandService(Stage stage) {
        label.textProperty()
                .bind(
                        service.stateProperty().asString()
                );

        stage.getScene()
                .getRoot()
                .cursorProperty()
                .bind(
                        Bindings
                            .when(service.runningProperty())
                                .then(Cursor.WAIT)
                                .otherwise(Cursor.DEFAULT)
                );

        runButton
                .disableProperty()
                .bind(
                        service.runningProperty()
                );

        runButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                service.restart();
            }
        });
    }

    private VBox createLayout() {
        VBox layout = new VBox(10);

        layout.getChildren().setAll(runButton, label);
        layout.setPadding(new Insets(10));
        layout.setAlignment(Pos.CENTER);

        return layout;
    }

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

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

13.12.2013
  • Извините, я думал, что было очевидно, что я был в основной теме. Служба, безусловно, путь. Спасибо за отличный ответ, он открыл для меня совершенно новый образ мышления. 13.12.2013
  • @jewelsea Похоже, это может отлично сработать для того, что мне нужно, но я получаю исключение. Мне нужно инициализировать потенциально большое количество пользовательских элементов управления (до 50) и заполнить их на панели сетки. Может быть, вы могли бы помочь мне с этим? см. этот pastebin: pastebin.com/Mh2XZA9x 28.07.2014
  • @Will Похоже, проблема отличается от той, к которой относится этот вопрос, пожалуйста, задайте новый вопрос. 29.07.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..