2011-12-08 10 views
30

मुझे इस विषय पर कोई सामग्री नहीं मिल रही है। एक और ठोस उदाहरण देने के लिए, मान लीजिए कि मैं एक साधारण घटक बनाना चाहता हूं जो चेकबॉक्स और लेबल को जोड़ती है। फिर, इस कस्टम घटक के उदाहरणों के साथ एक सूची दृश्य देखें।FXML का उपयोग कर JavaFX 2.0 में कस्टम घटक कैसे बनाएं?

अद्यतन: एक अप-टू-डेट ट्यूटोरियल, कृपया, परामर्श the official documentation के लिए: पूरा कोड

अद्यतन 2 के लिए मेरा उत्तर देखें। बहुत सारे new stuff थे जो 2.2 में जोड़े गए थे। अंत में, Introduction to FXML में FXML के बारे में जानने के लिए आपको जो कुछ भी चाहिए, वह बहुत अधिक शामिल है।

अद्यतन 3: हेन्ड्रिक एब्बर ने कस्टम UI नियंत्रणों के बारे में एक बेहद उपयोगी blog post बनाया।

+0

आपके 'आधिकारिक दस्तावेज' लिंक में कस्टम नियंत्रण उदाहरण टूटा हुआ है। ऐसी दो विधियां हैं जो एपीआई का हिस्सा नहीं हैं। –

+0

@danLeon पहले, यह मेरा "आधिकारिक दस्तावेज" नहीं है। यह ओरेकल कर्मचारियों द्वारा लिखित "आधिकारिक दस्तावेज" है जो जावाएफएक्स पर काम कर रहे हैं। दूसरा, जिस कोड से मैं लिंक कर रहा हूं वह जावाफैक्स 2.2 में कस्टम घटकों को बनाने का एक उदाहरण है। सबसे अधिक संभावना है कि आपके पास पुराना संस्करण पुराना है, इसलिए गायब तरीके हैं। यहां उस पृष्ठ से एक हाइलाइट दिया गया है: "शुरू करने से पहले, सुनिश्चित करें कि नेटबीन आईडीई का संस्करण जिसका उपयोग आप कर रहे हैं JavaFX 2.2 का समर्थन करता है" – Andrey

+0

आप सही! मेरा आईडीई जावाएफएक्स 2.1 के तहत था, टिप्पणी के लिए धन्यवाद। अब 2.2 से अधिक, मैंने अपने कंप्यूटर में पिछले जावा संस्करण को हटा दिया है। –

उत्तर

28

अद्यतन: एक अप-टू-डेट ट्यूटोरियल, कृपया, परामर्श the official documentation लिए। बहुत सारे new stuff थे जो 2.2 में जोड़े गए थे। इसके अलावा, Introduction to FXML में FXML के बारे में जानने के लिए आपको जो कुछ भी चाहिए, वह बहुत अधिक शामिल है। अंत में, कस्टम यूआई नियंत्रणों के बारे में हेन्ड्रिक एब्बर ने blog post को बेहद सहायक बना दिया।


API चारों ओर देख रही है और कुछ डॉक्स (Intro to FXML, Getting started with FXMLProperty binding, Future of FXML) मैं एक काफी समझदार समाधान के साथ आए हैं के माध्यम से पढ़ने के कुछ दिनों के बाद। इस छोटे प्रयोग से मैंने जो जानकारी सीखी, वह कम से कम सीधे-आगे का टुकड़ा था कि एक नियंत्रक का उदाहरण (एफएक्सएमएल में एफएक्स: नियंत्रक के साथ घोषित) FXMLLoader द्वारा आयोजित किया गया है जो FXML फ़ाइल लोड करता है ... सबसे खराब, यह महत्वपूर्ण है तथ्य यह है केवल सभी डॉक्स में one place में बताया गया है मैंने देखा:

एक नियंत्रक आम तौर पर, केवल FXML लोडर कि बनाता है यह

तो, याद करने के लिए दिख रहा है क्रम में करने के लिए प्रोग्राम के रूप में (से जावा कोड) fx:controllerके साथ FXML में घोषित नियंत्रक के उदाहरण का संदर्भ प्राप्त करें(पूर्ण उदाहरण के लिए नीचे चॉइससेल वर्ग के कार्यान्वयन का संदर्भ लें)।

ध्यान देने योग्य एक और बात यह है कि Property.bindBiderctional() कॉलिंग प्रॉपर्टी का मूल्य तर्क के रूप में पारित संपत्ति के मूल्य पर सेट करेगा। 0 बूलियन गुण target (मूल रूप से false पर सेट) और source (प्रारंभ में true पर सेट) target.bindBidirectional(source) पर कॉल करने से targettrue का मान निर्धारित किया जाएगा।जाहिर है, या तो संपत्ति को बाद में किसी भी परिवर्तन अन्य संपत्ति के मूल्य बदल जाएगा (target.set(false)false पर सेट होने के source का मूल्य का कारण होगा):

BooleanProperty target = new SimpleBooleanProperty();//value is false 
BooleanProperty source = new SimpleBooleanProperty(true);//value is true 
target.bindBidirectional(source);//target.get() will now return true 
target.set(false);//both values are now false 
source.set(true);//both values are now true 

वैसे भी, यहाँ पूरा कोड है कि दर्शाता है कि कैसे FXML और जावा कर सकते है

com.example.javafx.choice 
    ChoiceCell.java 
    ChoiceController.java 
    ChoiceModel.java 
    ChoiceView.fxml 
com.example.javafx.mvc 
    FxmlMvcPatternDemo.java 
    MainController.java 
    MainView.fxml 
    MainView.properties 

FxmlMvcPatternDemo.java

+०१२३५१६४१०६१: एक साथ (और साथ ही कुछ अन्य उपयोगी चीजें)

पैकेज संरचना काम

package com.example.javafx.mvc; 

import java.util.ResourceBundle; 
import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class FxmlMvcPatternDemo extends Application 
{ 
    public static void main(String[] args) throws ClassNotFoundException 
    { 
     Application.launch(FxmlMvcPatternDemo.class, args); 
    } 

    @Override 
    public void start(Stage stage) throws Exception 
    { 
     Parent root = FXMLLoader.load 
     (
      FxmlMvcPatternDemo.class.getResource("MainView.fxml"), 
      ResourceBundle.getBundle(FxmlMvcPatternDemo.class.getPackage().getName()+".MainView")/*properties file*/ 
     ); 

     stage.setScene(new Scene(root)); 
     stage.show(); 
    } 
} 

MainView.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<VBox 
    xmlns:fx="http://javafx.com/fxml" 
    fx:controller="com.example.javafx.mvc.MainController" 

    prefWidth="300" 
    prefHeight="400" 
    fillWidth="false" 
> 
    <children> 
     <Label text="%title" /> 
     <ListView fx:id="choicesView" /> 
     <Button text="Force Change" onAction="#handleForceChange" /> 
    </children> 
</VBox> 

MainView.properties

title=JavaFX 2.0 FXML MVC demo 

MainController.java

package com.example.javafx.mvc; 

import com.example.javafx.choice.ChoiceCell; 
import com.example.javafx.choice.ChoiceModel; 
import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.collections.FXCollections; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.ListCell; 
import javafx.scene.control.ListView; 
import javafx.util.Callback; 

public class MainController implements Initializable 
{ 
    @FXML 
    private ListView<ChoiceModel> choicesView; 

    @Override 
    public void initialize(URL url, ResourceBundle rb) 
    { 
     choicesView.setCellFactory(new Callback<ListView<ChoiceModel>, ListCell<ChoiceModel>>() 
     { 
      public ListCell<ChoiceModel> call(ListView<ChoiceModel> p) 
      { 
       return new ChoiceCell(); 
      } 
     }); 
     choicesView.setItems(FXCollections.observableArrayList 
     (
      new ChoiceModel("Tiger", true), 
      new ChoiceModel("Shark", false), 
      new ChoiceModel("Bear", false), 
      new ChoiceModel("Wolf", true) 
     )); 
    } 

    @FXML 
    private void handleForceChange(ActionEvent event) 
    { 
     if(choicesView != null && choicesView.getItems().size() > 0) 
     { 
      boolean isSelected = choicesView.getItems().get(0).isSelected(); 
      choicesView.getItems().get(0).setSelected(!isSelected); 
     } 
    } 
} 

ChoiceView.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<HBox 
    xmlns:fx="http://javafx.com/fxml" 

    fx:controller="com.example.javafx.choice.ChoiceController" 
> 
    <children> 
     <CheckBox fx:id="isSelectedView" /> 
     <Label fx:id="labelView" /> 
    </children> 
</HBox> 

ChoiceController.java

package com.example.javafx.choice; 

import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.CheckBox; 
import javafx.scene.control.Label; 

public class ChoiceController 
{ 
    private final ChangeListener<String> LABEL_CHANGE_LISTENER = new ChangeListener<String>() 
    { 
     public void changed(ObservableValue<? extends String> property, String oldValue, String newValue) 
     { 
      updateLabelView(newValue); 
     } 
    }; 

    private final ChangeListener<Boolean> IS_SELECTED_CHANGE_LISTENER = new ChangeListener<Boolean>() 
    { 
     public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean newValue) 
     { 
      updateIsSelectedView(newValue); 
     } 
    }; 

    @FXML 
    private Label labelView; 

    @FXML 
    private CheckBox isSelectedView; 

    private ChoiceModel model; 

    public ChoiceModel getModel() 
    { 
     return model; 
    } 

    public void setModel(ChoiceModel model) 
    { 
     if(this.model != null) 
      removeModelListeners(); 
     this.model = model; 
     setupModelListeners(); 
     updateView(); 
    } 

    private void removeModelListeners() 
    { 
     model.labelProperty().removeListener(LABEL_CHANGE_LISTENER); 
     model.isSelectedProperty().removeListener(IS_SELECTED_CHANGE_LISTENER); 
     isSelectedView.selectedProperty().unbindBidirectional(model.isSelectedProperty()) 
    } 

    private void setupModelListeners() 
    { 
     model.labelProperty().addListener(LABEL_CHANGE_LISTENER); 
     model.isSelectedProperty().addListener(IS_SELECTED_CHANGE_LISTENER); 
     isSelectedView.selectedProperty().bindBidirectional(model.isSelectedProperty()); 
    } 

    private void updateView() 
    { 
     updateLabelView(); 
     updateIsSelectedView(); 
    } 

    private void updateLabelView(){ updateLabelView(model.getLabel()); } 
    private void updateLabelView(String newValue) 
    { 
     labelView.setText(newValue); 
    } 

    private void updateIsSelectedView(){ updateIsSelectedView(model.isSelected()); } 
    private void updateIsSelectedView(boolean newValue) 
    { 
     isSelectedView.setSelected(newValue); 
    } 
} 

ChoiceModel.java

package com.example.javafx.choice; 

import javafx.beans.property.BooleanProperty; 
import javafx.beans.property.SimpleBooleanProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 

public class ChoiceModel 
{ 
    private final StringProperty label; 
    private final BooleanProperty isSelected; 

    public ChoiceModel() 
    { 
     this(null, false); 
    } 

    public ChoiceModel(String label) 
    { 
     this(label, false); 
    } 

    public ChoiceModel(String label, boolean isSelected) 
    { 
     this.label = new SimpleStringProperty(label); 
     this.isSelected = new SimpleBooleanProperty(isSelected); 
    } 

    public String getLabel(){ return label.get(); } 
    public void setLabel(String label){ this.label.set(label); } 
    public StringProperty labelProperty(){ return label; } 

    public boolean isSelected(){ return isSelected.get(); } 
    public void setSelected(boolean isSelected){ this.isSelected.set(isSelected); } 
    public BooleanProperty isSelectedProperty(){ return isSelected; } 
} 

ChoiceCell.java

package com.example.javafx.choice; 

import java.io.IOException; 
import java.net.URL; 
import javafx.fxml.FXMLLoader; 
import javafx.fxml.JavaFXBuilderFactory; 
import javafx.scene.Node; 
import javafx.scene.control.ListCell; 

public class ChoiceCell extends ListCell<ChoiceModel> 
{ 
    @Override 
    protected void updateItem(ChoiceModel model, boolean bln) 
    { 
     super.updateItem(model, bln); 

     if(model != null) 
     { 
      URL location = ChoiceController.class.getResource("ChoiceView.fxml"); 

      FXMLLoader fxmlLoader = new FXMLLoader(); 
      fxmlLoader.setLocation(location); 
      fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory()); 

      try 
      { 
       Node root = (Node)fxmlLoader.load(location.openStream()); 
       ChoiceController controller = (ChoiceController)fxmlLoader.getController(); 
       controller.setModel(model); 
       setGraphic(root); 
      } 
      catch(IOException ioe) 
      { 
       throw new IllegalStateException(ioe); 
      } 
     } 
    } 
} 
+0

अब मुझे यह मिल गया है। बहुत बहुत धन्यवाद। – glasspill

+0

मदद करने में खुशी हुई। हालांकि, सुनिश्चित करें कि आप अपडेट में दिए गए लिंक पर नज़र डालें। 2.2 – Andrey

2

त्वरित उत्तर < एफएक्स: > टैग शामिल है, हालांकि, आपको कंट्रोलर क्लास में चॉइसमोडेल सेट करने की आवश्यकता होगी।

<VBox 
    xmlns:fx="http://javafx.com/fxml" 

    fx:controller="fxmltestinclude.ChoiceDemo" 
> 
    <children> 
    **<fx:include source="Choice.fxml" />** 
    <ListView fx:id="choices" /> 
    </children> 
</VBox> 
+0

इसके अलावा, इस दस्तावेज़ को देखें http://fxexperience.com/wp-content/uploads/2011/08/Introducing-FXML.pdf – JimClarke

+0

ठीक है, लेकिन मैं प्रत्येक विकल्प को 'विकल्प' में प्रस्तुत करने के लिए Choice.fxml का उपयोग कैसे करूं? सूची? – Andrey

4

JavaFX 2.1 के लिए, आप इस तरह से एक कस्टम FXML नियंत्रण घटक बना सकते हैं:

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 
<?import customcontrolexample.myCommponent.*?> 

<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="customcontrolexample.FXML1Controller"> 
    <children> 
     <MyComponent welcome="1234"/> 
    </children> 
</VBox> 

घटक कोड:

MyComponent.java

package customcontrolexample.myCommponent; 

import java.io.IOException; 
import javafx.beans.property.StringProperty; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Node; 
import javafx.scene.layout.Pane; 
import javafx.util.Callback; 

public class MyComponent extends Pane { 

    private Node view; 
    private MyComponentController controller; 

    public MyComponent() { 
     FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myComponent.fxml")); 
     fxmlLoader.setControllerFactory(new Callback<Class<?>, Object>() { 
      @Override 
      public Object call(Class<?> param) { 
       return controller = new MyComponentController(); 
      } 
     }); 
     try { 
      view = (Node) fxmlLoader.load(); 

     } catch (IOException ex) { 
     } 
     getChildren().add(view); 
    } 

    public void setWelcome(String str) { 
     controller.textField.setText(str); 
    } 

    public String getWelcome() { 
     return controller.textField.getText(); 
    } 

    public StringProperty welcomeProperty() { 
     return controller.textField.textProperty(); 
    } 
} 

MyComponentController.java

package customcontrolexample.myCommponent; 

import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.TextField; 

public class MyComponentController implements Initializable { 

    int i = 0; 
    @FXML 
    TextField textField; 

    @FXML 
    protected void doSomething() { 
     textField.setText("The button was clicked #" + ++i); 
    } 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
     textField.setText("Just click the button!"); 
    } 
} 

myComponent.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="customcontrolexample.myCommponent.MyComponentController"> 
    <children> 
    <TextField fx:id="textField" prefWidth="200.0" /> 
    <Button mnemonicParsing="false" onAction="#doSomething" text="B" /> 
    </children> 
</VBox> 

इस कोड को अगर कोई स्मृति है की जाँच करने की जरूरत है रिसाव।

+1

में बहुत सी नई चीज़ें शामिल की गईं बहुत बहुत धन्यवाद, इससे मदद मिली। – ShaggyInjun

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