2013-12-13 7 views
8

मैं कर्सर को कर्सर में बदलना चाहता हूं। जावाएफएक्स अनुप्रयोग में संभावित लंबे संचालन को निष्पादित करते समय एएआईटी। मैंने सोचा कि Platform.runLater मेरी मदद करेगा:लंबे परिचालनों के लिए जावाएफएक्स अनुप्रयोग में कर्सर बदलना

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

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

लेकिन कर्सर नहीं बदलता है। यह क्यों काम नहीं करता है?

+1

सेट कर्सर को एफएक्स थ्रेड पर बुलाया जाना चाहिए ... – assylias

उत्तर

16

मान लिया जाये कि आप 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 आवेदन धागे पर पहले से ही कर रहे हैं, तो आप इस्तेमाल कर सकते हैं एक Service:

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

यह अपने विवरण जो दृष्टिकोण आपकी समस्या को सबसे अच्छा फिट बैठता है से स्पष्ट नहीं है, लेकिन उम्मीद है कि आप इस पर काम कर सकते हैं।

+0

क्षमा करें, मैंने सोचा कि यह स्पष्ट था कि मैं मुख्य धागे पर था। सेवा निश्चित रूप से जाने का रास्ता है। महान जवाब के लिए धन्यवाद, यह मेरे लिए सोचने का एक नया तरीका खोला। –

+0

@jewelsea ऐसा लगता है कि यह मेरी ज़रूरत के लिए बहुत अच्छा काम कर सकता है लेकिन मुझे अपवाद मिल रहा है। मुझे संभावित रूप से बड़ी संख्या में कस्टम नियंत्रण (50 तक) शुरू करना होगा और उन्हें ग्रिड फलक में पॉप्युलेट करना होगा। शायद आप इसके साथ मेरी मदद कर सकते हैं? कृपया इस पेस्टबिन को देखें: http://pastebin.com/Mh2XZA9x – Will

+0

@Will इस सवाल से भिन्न समस्या की तरह दिखता है, कृपया एक नया प्रश्न पूछें। – jewelsea

संबंधित मुद्दे