জাভাফএক্স এফএক্সএমএল প্যারামিটারগুলি পাস হচ্ছে


194

জাভাফেক্সে আমি কীভাবে একটি গৌণ উইন্ডোতে প্যারামিটারগুলি পাস করতে পারি? সংশ্লিষ্ট নিয়ামকের সাথে যোগাযোগ করার কোনও উপায় আছে?

উদাহরণস্বরূপ: ব্যবহারকারী একটি থেকে গ্রাহককে বেছে নেয় TableViewএবং একটি নতুন উইন্ডো খোলা হয়, যা গ্রাহকের তথ্য প্রদর্শন করে।

Stage newStage = new Stage();
try 
{
    AnchorPane page = (AnchorPane) FXMLLoader.load(HectorGestion.class.getResource(fxmlResource));
    Scene scene = new Scene(page);
    newStage.setScene(scene);
    newStage.setTitle(windowTitle);
    newStage.setResizable(isResizable);
    if(showRightAway) 
    {
        newStage.show();
    }
}

newStageনতুন উইন্ডো হবে। সমস্যাটি হ'ল, আমি কন্ট্রোলারকে গ্রাহকের তথ্য কোথায় খুঁজতে হবে (প্যারামিটার হিসাবে আইডি পাস করে) বলার উপায় খুঁজে পাচ্ছি না।

কোন ধারনা?


যদি এই কাজ করে দেখতে পরীক্ষা stackoverflow.com/questions/14370183/...
Dynelight

@ আলভারো: আপনি কি সমাধান পেয়েছেন? আপনি কি পরামিতি পাস করতে পারেন? একটি নিয়ামক থেকে অন্য নিয়ামক ফাইল থেকে?
জাভা ম্যান

3
হ্যাঁ. জুয়েলসি একটি বই স্তরের ব্যাখ্যা দিয়েছিল। সে কারণেই আমি তাঁর উত্তরটি গ্রহণ করেছি
আলভোরো

উত্তর:


276

প্রস্তাবিত পদ্ধতির

এই উত্তরটি এফএক্সএমএল নিয়ন্ত্রকদের কাছে পরামিতিগুলি পাস করার জন্য বিভিন্ন প্রক্রিয়া গণনা করে।

ছোট অ্যাপ্লিকেশনগুলির জন্য আমি কলার থেকে নিয়ামকের কাছে সরাসরি পরামিতিগুলি পাস করার সুপারিশ করি - এটি সহজ, সোজা এবং কোনও অতিরিক্ত ফ্রেমওয়ার্কের প্রয়োজন নেই।

বৃহত্তর, আরও জটিল অ্যাপ্লিকেশনগুলির জন্য, আপনি যদি আপনার অ্যাপ্লিকেশনটির মধ্যে নির্ভরতা ইনজেকশন বা ইভেন্ট বাস প্রক্রিয়াটি ব্যবহার করতে চান তবে তা তদন্তযোগ্য হবে worth

কলার থেকে সরাসরি নিয়ন্ত্রকের কাছে প্যারামিটারগুলি পাস করা

এফএক্সএমএল লোডার উদাহরণ থেকে নিয়ামকটি পুনরুদ্ধার করে এবং প্রয়োজনীয় ডেটা মানগুলির সাহায্যে এটি আরম্ভ করার জন্য নিয়ামককে একটি পদ্ধতি কল করে কাস্টম ডেটা একটি এফএক্সএমএল নিয়ামককে দিন Pass

নিম্নলিখিত কোডের মতো কিছু:

public Stage showCustomerDialog(Customer customer) {
  FXMLLoader loader = new FXMLLoader(
    getClass().getResource(
      "customerDialog.fxml"
    )
  );

  Stage stage = new Stage(StageStyle.DECORATED);
  stage.setScene(
    new Scene(
      (Pane) loader.load()
    )
  );

  CustomerDialogController controller = 
    loader.<CustomerDialogController>getController();
  controller.initData(customer);

  stage.show();

  return stage;
}

...

class CustomerDialogController {
  @FXML private Label customerName;
  void initialize() {}
  void initData(Customer customer) {
    customerName.setText(customer.getName());
  }
}

নমুনা কোড যেমন দেখানো হয়েছে তেমন একটি নতুন এফএক্সএমএলএলডার নির্মিত হয়েছে new FXMLLoader(location)। অবস্থানটি একটি ইউআরএল এবং আপনি এফএক্সএমএল উত্স থেকে এই জাতীয় URL তৈরি করতে পারেন:

new FXMLLoader(getClass().getResource("sample.fxml"));

FXMLLoader এ কোনও স্ট্যাটিক লোড ফাংশনটি ব্যবহার না করার বিষয়ে সতর্কতা অবলম্বন করুন বা আপনি নিজের লোডার উদাহরণ থেকে আপনার নিয়ামক পেতে সক্ষম হবেন না।

এফএক্সএমএমএলএলডার দৃষ্টান্তগুলি ডোমেন অবজেক্ট সম্পর্কে নিজেরাই কখনও জানে না। আপনি সরাসরি অ্যাপ্লিকেশন নির্দিষ্ট ডোমেন অবজেক্টগুলিকে FXMLLoader কনস্ট্রাক্টরে পাস করবেন না, পরিবর্তে আপনি:

  1. নির্দিষ্ট জায়গায় fxML মার্কআপের উপর ভিত্তি করে একটি FXMLLoader তৈরি করুন ML
  2. FXMLLoader উদাহরণ থেকে একটি নিয়ামক পান।
  3. ডোমেন অবজেক্টের রেফারেন্স সহ নিয়ামক সরবরাহ করতে পুনরুদ্ধারকৃত নিয়ন্ত্রকের উপর পদ্ধতিগুলি আহ্বান করুন।

এই ব্লগটি (অন্য লেখকের দ্বারা) একটি বিকল্প, তবে অনুরূপ উদাহরণ সরবরাহ করে

FXMLLoader এ একটি নিয়ামক সেট করা হচ্ছে

CustomerDialogController dialogController = 
    new CustomerDialogController(param1, param2);

FXMLLoader loader = new FXMLLoader(
    getClass().getResource(
        "customerDialog.fxml"
    )
);
loader.setController(dialogController);

Pane mainPane = (Pane) loader.load();

আপনি কোডারে একটি নতুন নিয়ামক তৈরি করতে পারেন, আপনার কলারের কাছ থেকে আপনি যে কোনও প্যারামিটারগুলি নিয়ন্ত্রণকারী কনস্ট্রাক্টরে যেতে চান into একবার আপনি একটি নিয়ামক তৈরি করে ফেললে, আপনি উদাহরণ পদ্ধতিটি শুরু করার আগে আপনি এটিকে FXMLLoader এ ইনস্টল করতে পারেন ।load()

কোনও লোডারে একটি কন্ট্রোলার সেট করতে (জাভাএফএক্স 2.x এ) আপনি fx:controllerআপনার এফএক্সএমএল ফাইলটিতে একটি বৈশিষ্ট্যও সংজ্ঞায়িত করতে পারবেন না ।

fx:controllerএফএক্সএমএলে সংজ্ঞাটির সীমাবদ্ধতার কারণে , আমি ব্যক্তিগতভাবে এফএক্সএমএলএলএডার থেকে কন্ট্রোলারকে এফএক্সএমএলএলএডারে সেট করার চেয়ে কন্ট্রোলার পেতে পছন্দ করি।

বাহ্যিক স্ট্যাটিক পদ্ধতি থেকে নিয়ামককে পরামিতিগুলি পুনরুদ্ধার করা

এই পদ্ধতিটি সার্জির জাভাফ্যাক্স ২.০-তে কীভাবে অ্যাপ্লিকেশন.সেটপ্যারামিটারে () একটি নিয়ন্ত্রণেআর জাভা ফাইলে দেওয়া উত্তর দ্বারা উদাহরণস্বরূপ ।

নির্ভরতা ইনজেকশন ব্যবহার করুন

এফএক্সএমএলএলডার গুইস, স্প্রিং বা জাভা ইই সিডিআই এর মতো নির্ভরতা ইনজেকশন সিস্টেমগুলিকে আপনাকে এফএক্সএমএলএলএডারে একটি কাস্টম নিয়ামক কারখানা স্থাপনের অনুমতি দিয়ে সহায়তা করে। এটি একটি কলব্যাক সরবরাহ করে যা আপনি নির্ভরশীল ইনজেকশন সিস্টেম দ্বারা ইনজেকশনের উপর নির্ভরশীল মানগুলির সাথে নিয়ামক উদাহরণ তৈরি করতে ব্যবহার করতে পারেন।

জাভাএফএক্স অ্যাপ্লিকেশন এবং স্প্রিংয়ের সাথে নিয়ন্ত্রক নির্ভরতা ইনজেকশনের একটি উদাহরণ দেওয়া উত্তরে সরবরাহ করা হয়েছে:

একটি সত্যই সুন্দর, পরিষ্কার নির্ভরতা ইনজেকশন পদ্ধতির দৃষ্টান্তস্বরূপ afterburner.fx ফ্রেমওয়ার্ক এটি নমুনা এয়ার হ্যাক অ্যাপ্লিকেশন ব্যবহার করে uses afterburner.fx নির্ভরতা ইনজেকশন সঞ্চালনের জন্য JEE6 javax.inject উপর নির্ভর করে ।

ইভেন্ট বাস ব্যবহার করুন

আসল এফএক্সএমএল স্পেসিফিকেশন স্রষ্টা এবং প্রয়োগকারী গ্রেগ ব্রাউন প্রায়শই এফএক্সএমএল ইনস্ট্যান্টিয়েটেড কন্ট্রোলার এবং অন্যান্য অ্যাপ্লিকেশন যুক্তির মধ্যে যোগাযোগের জন্য গুয়ারা ইভেন্টবাসের মতো ইভেন্ট বাস ব্যবহার করার কথা বিবেচনা করার পরামর্শ দেন ।

ইভেন্টবাস এমন একটি সাধারণ তবে শক্তিশালী প্রকাশ / সাবস্ক্রাইব এপিটি যা এনওটিশনের সাথে পিওজেওগুলিকে একে অপরের সাথে রেফারেন্স না করেই কোনও জেভিএমে একে অপরের সাথে যোগাযোগ করতে দেয়।

প্রশ্নোত্তর অনুসরণ করুন

প্রথম পদ্ধতিতে, আপনি কেন পর্যায়টি ফিরবেন? পদ্ধতিটি অকার্যকরও হতে পারে কারণ আপনি ইতিমধ্যে কমান্ড শো দিয়েছিলেন (); ফিরে আসার ঠিক আগে;। পর্যায়টি ফিরেই আপনি কীভাবে ব্যবহারের পরিকল্পনা করবেন

এটি একটি সমস্যার কার্যকরী সমাধান। কোনও পর্যায়টি showCustomerDialogফাংশন থেকে ফিরে আসে যাতে এটির একটি রেফারেন্স কোনও বাহ্যিক শ্রেণীর দ্বারা সঞ্চয় করা যায় যা কিছু করতে ইচ্ছুক হতে পারে যেমন পরবর্তী সময়ে প্রধান উইন্ডোতে একটি বোতাম ক্লিকের উপর ভিত্তি করে মঞ্চটি আড়াল করে। একটি বিকল্প, অবজেক্ট-ভিত্তিক সমাধান গ্রাহকডায়ালগ অবজেক্টের ভিতরে কার্যকারিতা এবং মঞ্চের রেফারেন্সকে গুপ্ত করতে পারে বা গ্রাহকডায়ালগ প্রসারিত স্টেজ থাকতে পারে। এফএক্সএমএল, নিয়ামক এবং মডেল ডেটা এনক্যাপসুলেটিং কাস্টম সংলাপের কোনও অবজেক্ট-ওরিয়েন্টেড ইন্টারফেসের পুরো উদাহরণ এই উত্তরের ক্ষেত্রের বাইরে নয়, তবে যে কারও পক্ষে এটি তৈরির প্রবণতা সার্থক ব্লগ পোস্ট তৈরি করতে পারে।


@Dzim নামে স্ট্যাকওভারফ্লো ব্যবহারকারী অতিরিক্ত সরবরাহ করেছেন

স্প্রিং বুট নির্ভরতা ইনজেকশন জন্য উদাহরণ

এটি "দ্য স্প্রিং বুট ওয়ে" কীভাবে করবেন তা নিয়ে প্রশ্নটি ছিল জাভাএফএক্স 2 সম্পর্কে, যা আমি সংযুক্ত পারমিলিংকে উত্তর দিয়েছিলাম। পদ্ধতি, এখনও বৈধ এবং মার্চ 2016 সালে পরীক্ষিত উপর স্প্রিং বুট v1.3.3.RELEASE: https://stackoverflow.com/a/36310391/1281217


কখনও কখনও, আপনি কলারের কাছে ফলাফল পুনরায় পাঠাতে চাইতে পারেন, এক্ষেত্রে আপনি সম্পর্কিত প্রশ্নের উত্তর পরীক্ষা করে দেখতে পারেন:


এফএক্সএমএমএলএলডার কনস্ট্রাক্টররা কেবলমাত্র প্যারামিটার হিসাবে ইউআরএল নেয় .. FXMLLoader ইনস্ট্যান্ট করার সঠিক উপায় কী?
আলভারো

1
ইভেন্ট বাস ওয়েবসাইটটি সূচিত হয়েছে, "আপডেট 3/2013: ইভেন্ট ইভেন্ট বাসি গেছে ..."
জে

1
ডেটাএফএক্স কন্ট্রোলার ফ্রেমওয়ার্কগুলি এফএক্সএমএল নিয়ন্ত্রণকারীদের জন্য কিছু ইনজেকশন সহায়তা সরবরাহ করে: guigarage.com/2013/12/datafx-controller-framework-preview
হেন্ড্রিক এবারস

2
@ আনারকি
জহেলসিয়া

7
গড্যাশেকের জন্য জাভাএফএক্সে এই ক্ষুদ্র কাজটি করার সহজ কি কিছু আছে? কনস্ট্রাক্টর এবং জাভাফ্যাক্সে ডেটা পাস করার জন্য এটি খুব সাধারণ বৈশিষ্ট্যটির জন্য কেবল একটি নাম বা একটি মান প্রেরণ করার জন্য সমস্ত কিছু একসাথে এই নরকের প্রয়োজন?
জাহান সাফলোয়া

13

আমি বুঝতে পারি এটি একটি পুরানো পোস্ট এবং এর ইতিমধ্যে কয়েকটি দুর্দান্ত উত্তর রয়েছে, তবে আমি এরকম একটি পদ্ধতির প্রদর্শন করার জন্য একটি নতুন এমসিভিই তৈরি করতে চেয়েছিলাম এবং নতুন কোডারকে ধারণাটি কার্যকরভাবে দেখার জন্য একটি উপায়কে অনুমতি দেওয়া উচিত।

এই উদাহরণে, আমরা 5 টি ফাইল ব্যবহার করব:

  1. মাইন.জাভা - অ্যাপ্লিকেশন শুরু করতে এবং প্রথম নিয়ামককে কল করার জন্য কেবল ব্যবহৃত হয়।
  2. Controller1.java - প্রথম FXML বিন্যাসের জন্য নিয়ামক।
  3. কন্ট্রোলার ২. জাভা - দ্বিতীয় এফএক্সএমএল লেআউটের জন্য নিয়ামক।
  4. Layout1.fxml - প্রথম দৃশ্যের জন্য FXML লেআউট।
  5. Layout2.fxML - দ্বিতীয় দৃশ্যের জন্য FXML লেআউট।

সমস্ত ফাইল এই পোস্টের নীচে তাদের পুরোপুরি তালিকাবদ্ধ রয়েছে।

গোল: থেকে মানগুলি ক্ষণস্থায়ী প্রকট Controller1করতে Controller2এবং তদ্বিপরীত।

প্রোগ্রাম প্রবাহ:

  • প্রথম দৃশ্যে ক TextField, ক Buttonএবং ক রয়েছে Label। যখন Buttonক্লিক করা হয়, দ্বিতীয় উইন্ডোতে লোড এবং টেক্সট প্রবেশ সহ প্রদর্শন করা হয় TextField
  • দ্বিতীয় দৃশ্যের মধ্যে একটি TextField, ক Button, এবং এও রয়েছে LabelLabelপাঠ্যের মধ্যে প্রবেশ প্রদর্শন করা হবে TextFieldপ্রথম দৃশ্যের উপর।
  • দ্বিতীয় দৃশ্যে পাঠ্য প্রবেশ করে TextFieldএবং এটিতে ক্লিক করার পরে প্রবেশ করা পাঠ্যটি দেখানোর জন্য Buttonপ্রথম দৃশ্যের Labelআপডেট করা হয়।

এটি একটি খুব সাধারণ বিক্ষোভ এবং অবশ্যই কিছুটা উন্নতির পক্ষে দাঁড়াতে পারে তবে ধারণাটি খুব স্পষ্ট করে তোলা উচিত।

কোডটি নিজেই কী ঘটছে এবং কীভাবে চলছে তার কিছু বিশদ মন্তব্য করে।

কোড

Main.java:

import javafx.application.Application;
import javafx.stage.Stage;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        // Create the first controller, which loads Layout1.fxml within its own constructor
        Controller1 controller1 = new Controller1();

        // Show the new stage
        controller1.showStage();

    }
}

Controller1.java:

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import java.io.IOException;

public class Controller1 {

    // Holds this controller's Stage
    private final Stage thisStage;

    // Define the nodes from the Layout1.fxml file. This allows them to be referenced within the controller
    @FXML
    private TextField txtToSecondController;
    @FXML
    private Button btnOpenLayout2;
    @FXML
    private Label lblFromController2;

    public Controller1() {

        // Create the new stage
        thisStage = new Stage();

        // Load the FXML file
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout1.fxml"));

            // Set this class as the controller
            loader.setController(this);

            // Load the scene
            thisStage.setScene(new Scene(loader.load()));

            // Setup the window/stage
            thisStage.setTitle("Passing Controllers Example - Layout1");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Show the stage that was loaded in the constructor
     */
    public void showStage() {
        thisStage.showAndWait();
    }

    /**
     * The initialize() method allows you set setup your scene, adding actions, configuring nodes, etc.
     */
    @FXML
    private void initialize() {

        // Add an action for the "Open Layout2" button
        btnOpenLayout2.setOnAction(event -> openLayout2());
    }

    /**
     * Performs the action of loading and showing Layout2
     */
    private void openLayout2() {

        // Create the second controller, which loads its own FXML file. We pass a reference to this controller
        // using the keyword [this]; that allows the second controller to access the methods contained in here.
        Controller2 controller2 = new Controller2(this);

        // Show the new stage/window
        controller2.showStage();

    }

    /**
     * Returns the text entered into txtToSecondController. This allows other controllers/classes to view that data.
     */
    public String getEnteredText() {
        return txtToSecondController.getText();
    }

    /**
     * Allows other controllers to set the text of this layout's Label
     */
    public void setTextFromController2(String text) {
        lblFromController2.setText(text);
    }
}

Controller2.java:

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import java.io.IOException;

public class Controller2 {

    // Holds this controller's Stage
    private Stage thisStage;

    // Will hold a reference to the first controller, allowing us to access the methods found there.
    private final Controller1 controller1;

    // Add references to the controls in Layout2.fxml
    @FXML
    private Label lblFromController1;
    @FXML
    private TextField txtToFirstController;
    @FXML
    private Button btnSetLayout1Text;

    public Controller2(Controller1 controller1) {
        // We received the first controller, now let's make it usable throughout this controller.
        this.controller1 = controller1;

        // Create the new stage
        thisStage = new Stage();

        // Load the FXML file
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout2.fxml"));

            // Set this class as the controller
            loader.setController(this);

            // Load the scene
            thisStage.setScene(new Scene(loader.load()));

            // Setup the window/stage
            thisStage.setTitle("Passing Controllers Example - Layout2");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Show the stage that was loaded in the constructor
     */
    public void showStage() {
        thisStage.showAndWait();
    }

    @FXML
    private void initialize() {

        // Set the label to whatever the text entered on Layout1 is
        lblFromController1.setText(controller1.getEnteredText());

        // Set the action for the button
        btnSetLayout1Text.setOnAction(event -> setTextOnLayout1());
    }

    /**
     * Calls the "setTextFromController2()" method on the first controller to update its Label
     */
    private void setTextOnLayout1() {
        controller1.setTextFromController2(txtToFirstController.getText());
    }

}

Layout1.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
    <VBox alignment="CENTER" spacing="10.0">
        <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
        </padding>
        <Label style="-fx-font-weight: bold;" text="This is Layout1!"/>
        <HBox alignment="CENTER_LEFT" spacing="10.0">
            <Label text="Enter Text:"/>
            <TextField fx:id="txtToSecondController"/>
            <Button fx:id="btnOpenLayout2" mnemonicParsing="false" text="Open Layout2"/>
        </HBox>
        <VBox alignment="CENTER">
            <Label text="Text From Controller2:"/>
            <Label fx:id="lblFromController2" text="Nothing Yet!"/>
        </VBox>
    </VBox>
</AnchorPane>

Layout2.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
    <VBox alignment="CENTER" spacing="10.0">
        <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
        </padding>
        <Label style="-fx-font-weight: bold;" text="Welcome to Layout 2!"/>
        <VBox alignment="CENTER">
            <Label text="Text From Controller1:"/>
            <Label fx:id="lblFromController1" text="Nothing Yet!"/>
        </VBox>
        <HBox alignment="CENTER_LEFT" spacing="10.0">
            <Label text="Enter Text:"/>
            <TextField fx:id="txtToFirstController"/>
            <Button fx:id="btnSetLayout1Text" mnemonicParsing="false" text="Set Text on Layout1"/>
        </HBox>
    </VBox>
</AnchorPane>

1
এফএক্সএমএল ফাইলটিতে কন্ট্রোলার সেট করা সম্ভব? লাইনটি সরিয়ে দেওয়ার কারণ: loader.setController(this)এবং এফএক্সএমএল ফাইলে নিয়ামক যুক্ত করার ফলে অ্যাপ্লিকেশনটি ক্র্যাশ হয়ে যায়
হাফফ্যাচ

1
যদি এফএক্সএমএলটি নিয়ামকের মধ্যে থেকেই লোড হয়। আপনি যদি প্রধান শ্রেণি থেকে FXML লোড করেন, উদাহরণস্বরূপ, আপনি এফএক্সএমএল ফাইলের মধ্যে কন্ট্রোলারটিকে সংজ্ঞায়িত করতে পারেন এবং এটি ব্যবহার করে একটি রেফারেন্স পেতে পারেনloader.getController()
Zephyr

পরিশেষে আমি একটি সমাধান খুঁজে পেতে পরিচালিত, দুর্দান্ত উদাহরণ। আমি এটি আমার প্রকল্পে বাস্তবায়ন করেছি এবং এখন আমি উভয় উইন্ডো একই সাথে খোলা এবং তার মধ্যে প্রথমটি মডেল করার চেষ্টা করছি। দুর্ভাগ্যক্রমে কেবল একটি খোলে। কেউ কি এর সাথে সাহায্য করতে পারে?
জাবা

8

javafx.scene.Node ক্লাসে এক সেট পদ্ধতি সেটআপারডাটা (অবজেক্ট) এবং গেট ইউজারডাটা ()

যা আপনি নোডে আপনার তথ্য যুক্ত করতে ব্যবহার করতে পারেন।

সুতরাং, আপনি পৃষ্ঠা.setUserData (তথ্য) কল করতে পারেন;

এবং নিয়ন্ত্রক যদি তথ্য সেট করা থাকে তবে তা পরীক্ষা করতে পারে। এছাড়াও, প্রয়োজন হলে আপনি ব্যাক-ফরোয়ার্ড ডেটা স্থানান্তর করার জন্য অবজেক্টপ্রোপার্টি ব্যবহার করতে পারেন।

এখানে একটি ডকুমেন্টেশন পর্যবেক্ষণ করুন: http://docs.oracle.com/javafx/2/api/javafx/fxML/doc-files/intrration_to_fxml.html پيداوار_to_fxml.html "প্রথম সংস্করণে, হ্যান্ডেলবটনঅ্যাকশন () @FXML দিয়ে ট্যাগ করা আছে কন্ট্রোলারের ডকুমেন্টে চিহ্নিত মার্কআপটিকে অনুরোধ করার অনুমতি দেওয়ার জন্য। দ্বিতীয় উদাহরণে, বোতাম ক্ষেত্রটি লোডারকে তার মান সেট করার অনুমতি দেওয়ার জন্য টীকায়িত হয় The

সুতরাং, আপনাকে নোডের সাথে একটি নিয়ামক যুক্ত করতে হবে এবং নোডে একটি ব্যবহারকারী ডেটা সেট করতে হবে।


Stage.getScene () -> Scene.getRoot () -> Pender.getChildrenUnmodifiable () এর সাথে পুনরাবৃত্ত অনুসন্ধান। এটি খুব নোংরা উপায়। যদি কেউ স্মিথ আরও ভাল পরামর্শ দিতে পারে - এটি দুর্দান্ত হবে be
আলেকজান্ডার কিরভ

মনে হচ্ছে স্টেজ.জেটসীন ()। GetRoot () সঠিক উপায়! ধন্যবাদ
আলভারা

7

নেমস্পেসের মাধ্যমে কোনও fxML ডকুমেন্টে প্যারামিটারগুলি পাস করার জন্য এখানে একটি উদাহরণ।

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx/null" xmlns:fx="http://javafx.com/fxml/1">
    <BorderPane>
        <center>
            <Label text="$labelText"/>
        </center>
    </BorderPane>
</VBox>

External Textনেমস্পেস ভেরিয়েবলের মান নির্ধারণ করুন labelText:

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

import java.io.IOException;

public class NamespaceParameterExampleApplication extends Application {

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

    @Override
    public void start(Stage primaryStage) throws IOException {
        final FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("namespace-parameter-example.fxml"));

        fxmlLoader.getNamespace()
                  .put("labelText", "External Text");

        final Parent root = fxmlLoader.load();

        primaryStage.setTitle("Namespace Parameter Example");
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }
}

এটা লক্ষনীয় যে কিছু কী অভ্যন্তরীণভাবে ব্যবহৃত হয়: যেমন FXMLLoader.CONTROLLER_KEYWORD, FXMLLoader.LOCATION_KEY, FXMLLoader.RESOURCES_KEYএবং কোন স্ট্রিং এর জন্য মান হিসেবে ব্যবহার fx:idঅ্যাট্রিবিউট।
ফেবিয়ান

এর জন্য ধন্যবাদ, আমার অন্যান্য দৃশ্যটি কেবলমাত্র একটি ধারক যা আমার মূল দৃশ্যে পূর্বে প্রদর্শিত পাঠ্যটি দেখায়। এখন আমার কাছে একটি এফএক্সএমএল থাকতে পারে যা আমি নেমস্পেস ভেরিয়েবলের মাধ্যমে সামগ্রী সূচনা করে একাধিক জায়গায় পুনরায় ব্যবহার করতে পারি। আমার কোনও নতুন পদ্ধতি তৈরি করতে বা আমার কনস্ট্রাক্টর বা ইনিটালাইজারদের পরিবর্তন করতে হয়নি - আমার এফএক্সএমএলে কেবল ভেরিয়েবল যুক্ত করতে হবে এবং প্রধান নিয়ামকটিতে আমার fxmloader কোডে একটি লাইন যুক্ত করতে হবে।
সিস্টেমসইনকোড 21

4

এইটা কাজ করে ..

মনে রাখবেন প্রথমবার যখন আপনি পাসিং মানটি মুদ্রণ করবেন আপনি নালাগুলি পাবেন, আপনি আপনার উইন্ডো লোড করার পরে এটি ব্যবহার করতে পারবেন, অন্য যে কোনও উপাদানগুলির জন্য কোড করতে চান তার জন্য একই।

প্রথম নিয়ামক

try {
    Stage st = new Stage();
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/inty360/free/form/MainOnline.fxml"));

    Parent sceneMain = loader.load();

    MainOnlineController controller = loader.<MainOnlineController>getController();
    controller.initVariable(99L);

    Scene scene = new Scene(sceneMain);
    st.setScene(scene);
    st.setMaximized(true);
    st.setTitle("My App");
    st.show();
} catch (IOException ex) {
    Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
}

আরেকজন নিয়ামক

public void initVariable(Long id_usuario){
    this.id_usuario = id_usuario;
    label_usuario_nombre.setText(id_usuario.toString());
}

1
এই কাজটি যখন আপনি প্রথম নিয়ামক থেকে দ্বিতীয়টিতে প্যারামিটারটি পাস করেন তবে কীভাবে দ্বিতীয় থেকে প্রথম নিয়ন্ত্রকের কাছে প্যারামিটারটি পাস করবেন, মানে ফার্স্ট.এফএক্সএমএল লোড হওয়ার পরে।
মেনাই আলা এডডাইন - আলাদিন

@XlintXms সম্পর্কিত প্রশ্নটি জাভাএফএক্স এফএক্সএমএল প্যারামিটারটি কন্ট্রোলার এ থেকে বি এবং পিছনে যেতে দেখে যা আপনার অতিরিক্ত প্রশ্নের সমাধান করে।
জুয়েলসি

2

আপনাকে একটি কনটেক্সট ক্লাস তৈরি করতে হবে।

public class Context {
    private final static Context instance = new Context();
    public static Context getInstance() {
        return instance;
    }

    private Connection con;
    public void setConnection(Connection con)
    {
        this.con=con;
    }
    public Connection getConnection() {
        return con;
    }

    private TabRoughController tabRough;
    public void setTabRough(TabRoughController tabRough) {
        this.tabRough=tabRough;
    }

    public TabRoughController getTabRough() {
        return tabRough;
    }
}

আপনাকে আরম্ভের মাধ্যমে নিয়ন্ত্রণের উদাহরণ স্থাপন করতে হবে

Context.getInstance().setTabRough(this);

এবং আপনি এটি ব্যবহার করে আপনার পুরো অ্যাপ্লিকেশন থেকে এটি ব্যবহার করতে পারেন

TabRoughController cont=Context.getInstance().getTabRough();

এখন আপনি পুরো অ্যাপ্লিকেশন থেকে যে কোনও নিয়ামকের কাছে প্যারামিটারটি পাস করতে পারেন।


আমরা এই পদ্ধতির ব্যবহার করি এবং এটি দুর্দান্ত কাজ করে। আমি পছন্দ করি যে কন্সট্রাক্টরের ভিতরে বা প্রাথমিক পদ্ধতিতে আমার ডেটাতে অ্যাক্সেস রয়েছে এবং এটি নির্মাণের পরে আমাকে ডেটাটি কন্ট্রোলারে সেট করতে হবে না
বব

1

হ্যা, তুমি পারো.
আপনাকে প্রথম নিয়ামক যুক্ত করতে হবে:

YourController controller = loader.getController();     
controller.setclient(client);

তারপরে দ্বিতীয়টিতে একটি ক্লায়েন্ট ঘোষণা করুন, তারপরে আপনার নিয়ামকের নীচে:

public void setclien(Client c) {
    this.client = c;
}

0

গুইস দ্বারা ইনজেকশনের নিয়ামক ব্যবহারের জন্য এখানে একটি উদাহরণ।

/**
 * Loads a FXML file and injects its controller from the given Guice {@code Provider}
 */
public abstract class GuiceFxmlLoader {

   public GuiceFxmlLoader(Stage stage, Provider<?> provider) {
      mStage = Objects.requireNonNull(stage);
      mProvider = Objects.requireNonNull(provider);
   }

   /**
    * @return the FXML file name
    */
   public abstract String getFileName();

   /**
    * Load FXML, set its controller with given {@code Provider}, and add it to {@code Stage}.
    */
   public void loadView() {
      try {
         FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource(getFileName()));
         loader.setControllerFactory(p -> mProvider.get());
         Node view = loader.load();
         setViewInStage(view);
      }
      catch (IOException ex) {
         LOGGER.error("Failed to load FXML: " + getFileName(), ex);
      }
   }

   private void setViewInStage(Node view) {
      BorderPane pane = (BorderPane)mStage.getScene().getRoot();
      pane.setCenter(view);
   }

   private static final Logger LOGGER = Logger.getLogger(GuiceFxmlLoader.class);

   private final Stage mStage;
   private final Provider<?> mProvider;
}

এখানে লোডার একটি কংক্রিট বাস্তবায়ন:

public class ConcreteViewLoader extends GuiceFxmlLoader {

   @Inject
   public ConcreteViewLoader(Stage stage, Provider<MyController> provider) {
      super(stage, provider);
   }

   @Override
   public String getFileName() {
      return "my_view.fxml";
   }
}

নোট করুন এই উদাহরণটি একটি বোর্ডারপেনের কেন্দ্রে ভিউটি লোড করে যা পর্যায়টির দৃশ্যের মূল। এটি উদাহরণের সাথে অপ্রাসঙ্গিক (আমার নির্দিষ্ট ব্যবহারের ক্ষেত্রে প্রয়োগের বিশদটি) তবে কারও কারও পক্ষে এটি দরকারী হিসাবে এটি রেখে দেওয়ার সিদ্ধান্ত নিয়েছে।


-1

আপনি পাবলিক ডেটা সংরক্ষণ করার জন্য একটি পাবলিক অবজার্ভেবল লিস্ট ব্যবহার করার সিদ্ধান্ত নিতে পারেন, বা কেবল ডেটা সংরক্ষণের জন্য একটি পাবলিক সেটার পদ্ধতি তৈরি করতে এবং সংশ্লিষ্ট নিয়ামকের কাছ থেকে পুনরুদ্ধার করতে পারেন


-3

6 বছরের পুরানো প্রশ্নের উত্তর কেন দেবেন?
যে কোনও প্রোগ্রামিং ভাষার সাথে কাজ করা একটি অন্যতম মৌলিক ধারণা হ'ল কীভাবে একটি (উইন্ডো, ফর্ম বা পৃষ্ঠা) থেকে অন্যটিতে নেভিগেট করা যায়। এছাড়াও এই নেভিগেশনটি করার সময় বিকাশকারী প্রায়শই একটি (উইন্ডো, ফর্ম বা পৃষ্ঠা) থেকে ডেটা পাস করতে এবং পাস করা ডেটা প্রদর্শন বা ব্যবহার করতে চায়
যদিও এখানে বেশিরভাগ উত্তরগুলি কীভাবে এটি সম্পাদন করতে পারে তা চমৎকার উদাহরণগুলিতে ভাল সরবরাহ করে আমরা ভেবেছিলাম আমরা এটিকে লাথি মেরে ফেলব thought একটি খাঁজ বা দুই বা তিন
আমরা তিনটি বলেছিলাম কারণ আমরা তিনটি (উইন্ডো, ফর্ম বা পৃষ্ঠা) এর মধ্যে নেভিগেট করব এবং স্ট্যাটিক ভেরিয়েবলের ধারণাটি (উইন্ডো, ফর্ম বা পৃষ্ঠার) চারপাশে ডেটা পাস করার জন্য ব্যবহার
করব আমরা যখন কিছু সিদ্ধান্ত নেওয়ার কোডও অন্তর্ভুক্ত করব আমরা নেভিগেট

public class Start extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        // This is MAIN Class which runs first
        Parent root = FXMLLoader.load(getClass().getResource("start.fxml"));
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setResizable(false);// This sets the value for all stages
        stage.setTitle("Start Page"); 
        stage.show();
        stage.sizeToScene();
    }

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

নিয়ামক শুরু করুন

public class startController implements Initializable {

@FXML Pane startPane,pageonePane;
@FXML Button btnPageOne;
@FXML TextField txtStartValue;
public Stage stage;
public static int intSETonStartController;
String strSETonStartController;

@FXML
private void toPageOne() throws IOException{

    strSETonStartController = txtStartValue.getText().trim();


        // yourString != null && yourString.trim().length() > 0
        // int L = testText.length();
        // if(L == 0){
        // System.out.println("LENGTH IS "+L);
        // return;
        // }
        /* if (testText.matches("[1-2]") && !testText.matches("^\\s*$")) 
           Second Match is regex for White Space NOT TESTED !
        */

        String testText = txtStartValue.getText().trim();
        // NOTICE IF YOU REMOVE THE * CHARACTER FROM "[1-2]*"
        // NO NEED TO CHECK LENGTH it also permited 12 or 11 as valid entry 
        // =================================================================
        if (testText.matches("[1-2]")) {
            intSETonStartController = Integer.parseInt(strSETonStartController);
        }else{
            txtStartValue.setText("Enter 1 OR 2");
            return;
        }

        System.out.println("You Entered = "+intSETonStartController);
        stage = (Stage)startPane.getScene().getWindow();// pane you are ON
        pageonePane = FXMLLoader.load(getClass().getResource("pageone.fxml"));// pane you are GOING TO
        Scene scene = new Scene(pageonePane);// pane you are GOING TO
        stage.setScene(scene);
        stage.setTitle("Page One"); 
        stage.show();
        stage.sizeToScene();
        stage.centerOnScreen();  
}

private void doGET(){
    // Why this testing ?
    // strSENTbackFROMPageoneController is null because it is set on Pageone
    // =====================================================================
    txtStartValue.setText(strSENTbackFROMPageoneController);
    if(intSETonStartController == 1){
      txtStartValue.setText(str);  
    }
    System.out.println("== doGET WAS RUN ==");
    if(txtStartValue.getText() == null){
       txtStartValue.setText("");   
    }
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    // This Method runs every time startController is LOADED
     doGET();
}    
}

পৃষ্ঠা ওয়ান নিয়ামক

public class PageoneController implements Initializable {

@FXML Pane startPane,pageonePane,pagetwoPane;
@FXML Button btnOne,btnTwo;
@FXML TextField txtPageOneValue;
public static String strSENTbackFROMPageoneController;
public Stage stage;

    @FXML
private void onBTNONE() throws IOException{

        stage = (Stage)pageonePane.getScene().getWindow();// pane you are ON
        pagetwoPane = FXMLLoader.load(getClass().getResource("pagetwo.fxml"));// pane you are GOING TO
        Scene scene = new Scene(pagetwoPane);// pane you are GOING TO
        stage.setScene(scene);
        stage.setTitle("Page Two"); 
        stage.show();
        stage.sizeToScene();
        stage.centerOnScreen();
}

@FXML
private void onBTNTWO() throws IOException{
    if(intSETonStartController == 2){
        Alert alert = new Alert(AlertType.CONFIRMATION);
        alert.setTitle("Alert");
        alert.setHeaderText("YES to change Text Sent Back");
        alert.setResizable(false);
        alert.setContentText("Select YES to send 'Alert YES Pressed' Text Back\n"
                + "\nSelect CANCEL send no Text Back\r");// NOTE this is a Carriage return\r
        ButtonType buttonTypeYes = new ButtonType("YES");
        ButtonType buttonTypeCancel = new ButtonType("CANCEL", ButtonData.CANCEL_CLOSE);

        alert.getButtonTypes().setAll(buttonTypeYes, buttonTypeCancel);

        Optional<ButtonType> result = alert.showAndWait();
        if (result.get() == buttonTypeYes){
            txtPageOneValue.setText("Alert YES Pressed");
        } else {
            System.out.println("canceled");
            txtPageOneValue.setText("");
            onBack();// Optional
        }
    }
}

@FXML
private void onBack() throws IOException{

    strSENTbackFROMPageoneController = txtPageOneValue.getText();
    System.out.println("Text Returned = "+strSENTbackFROMPageoneController);
    stage = (Stage)pageonePane.getScene().getWindow();
    startPane = FXMLLoader.load(getClass().getResource("start.fxml")); 
    Scene scene = new Scene(startPane);
    stage.setScene(scene);
    stage.setTitle("Start Page"); 
    stage.show();
    stage.sizeToScene();
    stage.centerOnScreen(); 
}

private void doTEST(){
    String fromSTART = String.valueOf(intSETonStartController);
    txtPageOneValue.setText("SENT  "+fromSTART);
    if(intSETonStartController == 1){
       btnOne.setVisible(true);
       btnTwo.setVisible(false);
       System.out.println("INTEGER Value Entered = "+intSETonStartController);  
    }else{
       btnOne.setVisible(false);
       btnTwo.setVisible(true);
       System.out.println("INTEGER Value Entered = "+intSETonStartController); 
    }  
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    doTEST();
}    

}

পৃষ্ঠা দুই নিয়ামক

public class PagetwoController implements Initializable {

@FXML Pane startPane,pagetwoPane;
public Stage stage;
public static String str;

@FXML
private void toStart() throws IOException{

    str = "You ON Page Two";
    stage = (Stage)pagetwoPane.getScene().getWindow();// pane you are ON
    startPane = FXMLLoader.load(getClass().getResource("start.fxml"));// pane you are GOING TO
    Scene scene = new Scene(startPane);// pane you are GOING TO
    stage.setScene(scene);
    stage.setTitle("Start Page"); 
    stage.show();
    stage.sizeToScene();
    stage.centerOnScreen();  
}

@Override
public void initialize(URL url, ResourceBundle rb) {

}    

}

নীচে সমস্ত এফএক্সএমএল ফাইল রয়েছে

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane id="AnchorPane" fx:id="pagetwoPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="atwopage.PagetwoController">
   <children>
      <Button layoutX="227.0" layoutY="62.0" mnemonicParsing="false" onAction="#toStart" text="To Start Page">
         <font>
            <Font name="System Bold" size="18.0" />
         </font>
      </Button>
   </children>
</AnchorPane>

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane id="AnchorPane" fx:id="startPane" prefHeight="200.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="atwopage.startController">
   <children>
      <Label focusTraversable="false" layoutX="115.0" layoutY="47.0" text="This is the Start Pane">
         <font>
            <Font size="18.0" />
         </font>
      </Label>
      <Button fx:id="btnPageOne" focusTraversable="false" layoutX="137.0" layoutY="100.0" mnemonicParsing="false" onAction="#toPageOne" text="To Page One">
         <font>
            <Font size="18.0" />
         </font>
      </Button>
      <Label focusTraversable="false" layoutX="26.0" layoutY="150.0" text="Enter 1 OR 2">
         <font>
            <Font size="18.0" />
         </font>
      </Label>
      <TextField fx:id="txtStartValue" layoutX="137.0" layoutY="148.0" prefHeight="28.0" prefWidth="150.0" />
   </children>
</AnchorPane>

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane id="AnchorPane" fx:id="pageonePane" prefHeight="200.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="atwopage.PageoneController">
   <children>
      <Label focusTraversable="false" layoutX="111.0" layoutY="35.0" text="This is Page One Pane">
         <font>
            <Font size="18.0" />
         </font>
      </Label>
      <Button focusTraversable="false" layoutX="167.0" layoutY="97.0" mnemonicParsing="false" onAction="#onBack" text="BACK">
         <font>
            <Font size="18.0" />
         </font></Button>
      <Button fx:id="btnOne" focusTraversable="false" layoutX="19.0" layoutY="97.0" mnemonicParsing="false" onAction="#onBTNONE" text="Button One" visible="false">
         <font>
            <Font size="18.0" />
         </font>
      </Button>
      <Button fx:id="btnTwo" focusTraversable="false" layoutX="267.0" layoutY="97.0" mnemonicParsing="false" onAction="#onBTNTWO" text="Button Two">
         <font>
            <Font size="18.0" />
         </font>
      </Button>
      <Label focusTraversable="false" layoutX="19.0" layoutY="152.0" text="Send Anything BACK">
         <font>
            <Font size="18.0" />
         </font>
      </Label>
      <TextField fx:id="txtPageOneValue" layoutX="195.0" layoutY="150.0" prefHeight="28.0" prefWidth="150.0" />
   </children>
</AnchorPane>


3
আমি দুঃখিত, তবে এটি কী করে বা আপনি কেন এটি করেন সেভাবে কোনও ব্যাখ্যা ছাড়াই একশ লাইনের কোড পোস্ট করা খুব ভাল উত্তর নয়। এছাড়াও, আপনার পোস্ট করা কোডটি খুব খারাপভাবে সংগঠিত এবং অনুসরণ করা শক্ত।
Zephyr

জিজ্ঞাসা করা ব্যক্তির সাথে অভদ্র হওয়ার দরকার নেই। আমরা সকলেই এখানে
শিখিছি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.