2012-08-17 9 views
10

से जावाएफएक्स मैं क्लोजर सीखना शुरू करता हूं, और मैं जीयूआई के लिए जावाएफएक्स को आजमाने की कोशिश करता हूं। मुझे यह आलेख मिला: http://nailthatbug.net/2011/06/clojure-javafx-2-0-simple-app/ , लेकिन मैं इसे तेजी से परीक्षण और सुविधा के लिए प्रतिलिपि के माध्यम से शुरू करना चाहता हूं।क्लोजर प्रति

तो, उदाहरण के लिए, मैं repl इस में लिख सकते हैं और नई विंडो देख सकते हैं:

(defn main-start [] 
    (doto (JFrame. "Window!") 
    (.setSize (java.awt.Dimension. 400 300)) 
    (.setVisible true))) 

वहाँ किसी भी तरह से javafx.application.Application के साथ इस तरह बात करने के लिए है - नए JavaFX विंडो देखने के लिए?

Thx। एंड्रयू।

+0

आप प्रतिलिपि कैसे लॉन्च करते हैं? JavaFX रनटाइम निर्भरता के कारण, jfxrt.jar को क्लासपाथ पर होना चाहिए। क्या आपने लीनिंगेन का उपयोग करके एक प्रोजेक्ट बनाया था? –

उत्तर

8

हालांकि यह अभी भी अपने बचपन में है, मैं Upshot का उपयोग कर आरईपीएल से जावाएफएक्स का उपयोग करने में सक्षम हूं। मुख्य चाल सिर्फ Application को पूरी तरह से अनदेखा करने और सीधे अपना दृश्य बनाने के लिए है। ऐसा करने के लिए आपको केवल रनटाइम को प्रारंभ करने की आवश्यकता है और उदाहरण के लिए core.clj:69 पर देखा जा सकता है। दूसरी चाल यह है कि यह सुनिश्चित करने के लिए कि आप जावाएफएक्स थ्रेड पर चलते हैं, लगभग run-now ब्लॉक में लगभग हर चीज को लपेटना होगा। स्विफ्ट की तुलना में जावाएफएक्स थ्रेडिंग के बारे में ज्यादा पसंद है।

9

यदि आप JavaFX Application class documentation पढ़ते हैं, तो आप देखेंगे कि एप्लिकेशन क्लास एक अमूर्त वर्ग है, जिसे तुरंत तत्काल नहीं किया जा सकता है। इसका मतलब है, आपको कम से कम javafx.application.Aplication का उप-वर्ग बनाना है।

जीवन चक्र

JavaFX अनुप्रयोगों के लिए प्रवेश बिंदु आवेदन वर्ग है। JavaFX क्रम क्रम में, निम्नलिखित करता है, जब भी एक आवेदन शुरू की है:

  1. निर्दिष्ट आवेदन वर्ग
  2. का एक उदाहरण निर्माणों विधि init()
  3. कॉल प्रारंभ (JavaFX कॉल करता है। चरण। चरण) विधि
  4. आवेदन समाप्त होने के लिए प्रतीक्षा करता है, जो तब होता है जब निम्न में से कोई भी होता है: एप्लिकेशन कॉल प्लेटफ़ॉर्म.एक्सिट() को अंतिम विंडो बंद कर दिया गया है और प्लेटफ़ॉर्म पर implicitExit विशेषता सत्य है कॉल करता है 012,रोकें() विधि ध्यान दें कि प्रारंभ विधि सारणी है और ओवरराइड होना चाहिए। आवेदन शुरू करने के लिए सक्षम होने के लिए एक शुरुआत विधि के साथ - जनरल श्रेणी के मैक्रो के रूप में यह ब्लॉग पोस्ट में देखा जा सकता है का उपयोग कर -

इसलिए यदि आप एक वर्ग उत्पन्न करने के लिए की जरूरत है।

संपादित करें: जेन-क्लास दृष्टिकोण का उपयोग कर उदाहरण के लिए लिंक
मैंने Github repository with a simple example JavaFX application in Clojure बनाया है।

(ns jfx.app 
    (:import (javafx.beans.value ChangeListener ObservableValue) 
      (javafx.concurrent Worker$State) 
      (javafx.event ActionEvent EventHandler) 
      (javafx.scene Scene) 
      (javafx.scene.control Button) 
      (javafx.scene.layout StackPane)   
      (javafx.stage Stage) 
      (javafx.scene.web WebView))) 

(gen-class 
:name clj.jfx.App 
:extends javafx.application.Application 
:prefix "app-") 

(defn app-start [app ^Stage stage] 
    (let [root (StackPane.) 
     btn (Button.) 
     web-view (WebView.) 
     state-prop (.stateProperty (.getLoadWorker (.getEngine web-view))) 
     url "http://clojure.org"] 

    ;; Add a WebView (headless browser) 
    (.add (.getChildren root) web-view) 
    ;; Register listener for WebView state changes 
    (.addListener state-prop 
        (proxy [ChangeListener] [] 
        (changed [^ObservableValue ov 
           ^Worker$State old-state 
           ^Worker$State new-state] 
         (println (str "Current state:" (.name new-state))) 
         (if (= new-state Worker$State/SUCCEEDED) 
         (println (str "URL '" url "' load completed!")))))) 
    ;; Load a URL 
    (.load (.getEngine web-view) url) 

    ;; add a Button with a click handler class floating on top of the WebView 
    (.setTitle stage "JavaFX app with Clojure") 
    (.setText btn "Just a button") 
    (.setOnAction btn 
        (proxy [EventHandler] [] 
        (handle [^ActionEvent event] 
         (println "The button was clicked")))) 
    (.add (.getChildren root) btn) 

    ;; Set scene and show stage 
    (.setScene stage (Scene. root 800 600)) 
    (.show stage))) 

(defn app-stop 
    "Stop method is called when the application exits." 
    [app] 
    (println "Exiting application!") 
) 

(defn launch 
    "Launch a JavaFX Application using class clj.jfx.App" 
    [] 
    (javafx.application.Application/launch clj.jfx.App (into-array String []))) 

jfx.app नाम स्थान है, तो आप सीधे आरईपीएल में कोड को चलाने के आवेदन शुरू करने, इस काम नहीं करेगा संकलित किया जाना है: यहाँ Clojure फ़ाइल जनरल स्तरीय दृष्टिकोण पीछा कर रहा है। यदि आप कोड को आजमा देना चाहते हैं, तो project's README.md file में मेवेन और लीनिंगेन के साथ जावाएफएक्स स्थापित करने के लिए निर्देशों का पालन करें।

+0

तो, इसका मतलब है कि JavaFX ऐप को प्रतिलिपि से शुरू करने का कोई तरीका नहीं है, है ना? – Andrew

+0

मुझे लगता है कि आप एप्लिकेशन से प्राप्त होने वाली कक्षा बनाने के लिए 'प्रॉक्सी' का उपयोग कर सकते हैं और उस ऑब्जेक्ट का उपयोग कर सकते हैं – Ankur

+1

मैंने प्रॉक्सी क्लास के साथ प्रयास किया, और यह काम नहीं किया। पुष्टि की कि मैंने एक छोटे से परीक्षण के साथ किया था: जब क्लास कन्स्ट्रक्टर समाप्त होने से पहले अमूर्त विधि को कॉल किया जाता है, तो प्रॉक्सीकृत विधि क्लोजर द्वारा पर्याप्त रूप से उपलब्ध नहीं कराई जाएगी। इसका मतलब है, जीन-क्लास एकमात्र विकल्प है। –

2

Thx बहुत डेव। मुझे javafx.embed.swing के साथ एक समाधान भी मिला है।जेएफएक्स पैनेल:

(ns to-dell3 
    (:import 
    (javafx.application Application Platform) 
    (java.util Date) 
    (javafx.scene Group Scene) 
    (javafx.scene.text Font Text) 
    (javax.swing JFrame SwingUtilities) 
    ChartApp1 
    javafx.scene.paint.Color 
    javafx.embed.swing.JFXPanel)) 



(defn launch-javafx [] (SwingUtilities/invokeLater 
    (proxy [Runnable] [] (run [] 
       (let [frame2 (JFrame. "JFrame") 
         fxPanel2 (JFXPanel.) 
         ] 
        (do 
        (.setSize frame2 500 200) 
        (.setVisible frame2 true) 
        (.setDefaultCloseOperation frame2 JFrame/DISPOSE_ON_CLOSE) 
        (.add frame2 fxPanel2) 
        (Platform/runLater (proxy [Runnable] [] (run [] (let [root2 (Group.) 
               scene2 (Scene. root2 Color/ALICEBLUE) 
               text2 (Text.)] 
              (do 
              (.setX text2 40) 
              (.setY text2 100) 
              (.setFont text2 (Font. 25)) 
              (.setText text2 "Welcome to Clojure + REPL + JavaFX!") 
              (.add (.getChildren root2) text2) 
              (.setScene fxPanel2 scene2) 
              ))))))))))) 

जावाएफएक्स 2.2 आवश्यक है। और इसके लिए, आरईपीएल में: (प्लेटफ़ॉर्म/setImplicitExit झूठा) यह इस कोड का सीधा बंदरगाह है: Integrating JavaFX into Swing Applications इसलिए यह क्लोजर दुनिया में बहुत जरूरी और बेवकूफ, coz Im noob दिखता है, और कोई और अनुभवी हो सकता है, इसे और अधिक में फिर से लिख सकता है क्लोजरिश रास्ता। वैसे भी, यह अब मेरे लिए काम करता है, और मैं दो लॉन्चर्स की अवधारणा के बारे में सोचता हूं: एक प्रतिलिपि आधारित विकास (लॉन्च-जावाफैक्स) के माध्यम से, और प्रकाशित करने के लिए एक: सामान्य javafx.application.Aplication लॉन्चर के माध्यम से। मुझे अभी भी पता नहीं है कि वे एक दूसरे के बराबर हैं (मेरा मतलब है कि javafx.embed.swing.JFXPanel के मामले में पूर्ण जावाएफएक्स एपीआई उपलब्ध है), और यदि ऐसा है, तो यह मेरे लक्ष्य (आरईपीएल के माध्यम से विकास) के लिए उपयुक्त है। और मैं अभी भी अपशॉट कोड की जांच कर रहा हूं - अधिक नरम हो सकता है।