জাভাএফএক্স: আরম্ভের সময় নিয়ন্ত্রণকারীর কাছ থেকে মঞ্চ কিভাবে পাবেন?


91

আমি আমার নিয়ামক শ্রেণি থেকে মঞ্চ ইভেন্টগুলি (অর্থাত্ লুকানো) পরিচালনা করতে চাই। সুতরাং আমাকে যা করতে হবে তা হ'ল শ্রোতার মাধ্যমে যুক্ত করা

((Stage)myPane.getScene().getWindow()).setOn*whatIwant*(...);

তবে সমস্যাটি হ'ল প্রাথমিকভাবে শুরু হয় ঠিক পরে

Parent root = FXMLLoader.load(getClass().getResource("MyGui.fxml"));

এবং আগে

Scene scene = new Scene(root);
stage.setScene(scene);

এইভাবে .getScene () নাল ফেরায়।

আমি নিজের দ্বারা পাওয়া একমাত্র কাজটি হ'ল মাইপান.সেস্নপ্রোপার্টি () এ শ্রোতাদের যুক্ত করা এবং যখন এটি শূন্য হয় না তখন আমি দৃশ্যটি পাই, এতে যুক্ত করুন ind উইন্ডোপ্রপার্টি () আমার! গডম্যাম! শ্রোতাদের পরিচালনা যা আমি শেষপর্যন্ত পুনরুদ্ধার করি। এবং এটি সমস্ত শেষ পর্যায়ের ইভেন্টগুলিতে কাঙ্ক্ষিত শ্রোতাদের সেট করে শেষ হয়। আমার মনে হয় অনেক শ্রোতা আছে। এটি কি আমার সমস্যা সমাধানের একমাত্র উপায়?

উত্তর:


119

আপনি FXMLLoaderআরম্ভের পরে মাধ্যমে নিয়ামকের উদাহরণটি মাধ্যমে পেতে পারেন তবে স্থির পদ্ধতিগুলি ব্যবহারের পরিবর্তে getController()আপনার ইনস্ট্যান্ট করতে হবে FXMLLoader

আমি পরে load()সরাসরি কন্ট্রোলারে কল করার পরে মঞ্চটি পেরিয়ে যাতাম:

FXMLLoader loader = new FXMLLoader(getClass().getResource("MyGui.fxml"));
Parent root = (Parent)loader.load();
MyController controller = (MyController)loader.getController();
controller.setStageAndSetupListeners(stage); // or what you want to do

4
ভাবছেন আপনি কাস্ট মিস করছেন? মূল মূল =
পল ইডেন

12
এটি কি এটি করার সর্বোত্তম উপায়? এটি সংরক্ষণাগারভুক্ত করার জন্য জাভাএফএক্সের ফ্রেমওয়ার্কের দ্বারা সরবরাহ করা হয়নি?
হ্যানস

4
কোনও কারণে যদি আপনি প্যারামিটার ছাড়াই কনস্ট্রাক্টর ব্যবহার করেন এবং ইউআরএলটিকে load()পদ্ধতিতে হস্ত করেন তবে এটি কাজ করে না । (এছাড়াও, শোনা যাচ্ছে এমন জাভাদকটি getControllerএটি চালু হওয়া উচিত setController))
বোম্বে

4
@ বোম্ব্বে এটি কারণ ইউআরএল প্যারামিটার সহ লোড () পদ্ধতিটি একটি স্ট্যাটিক পদ্ধতি যা আপনি যার উপর কল করছেন সেটির কোনও সেট করে না।
zhujik

@ সেবাস্তিয়ান, প্রকৃতপক্ষে আমার খারাপ।
বোম্বে

112

আপনার কেবলমাত্র AnchorPaneএকটি আইডি দেওয়ার দরকার , এবং তারপরে আপনি এটিটি পেতে পারেন Stage

@FXML private AnchorPane ap;
Stage stage = (Stage) ap.getScene().getWindow();

এখান থেকে, আপনি Listenerযে প্রয়োজন তা যোগ করতে পারেন ।

সম্পাদনা করুন: নীচে আর্থমাইন্ডের বক্তব্য অনুসারে, এটি AnchorPaneউপাদান হতে হবে না ; এটি আপনার সংজ্ঞায়িত যে কোনও উপাদান হতে পারে।


4
স্বল্প ও মধুর. ধন্যবাদ
সেড্রিক

7
লক্ষ্য করুন elementএকটি সঙ্গে কোনো উপাদান হতে পারে fx:idযে উইন্ডোতে: Stage stage = (Stage) element.getScene().getWindow();। উদাহরণস্বরূপ, যদি আপনি শুধুমাত্র একটি আছে Buttonএকটি সঙ্গে fx:idআপনার উইন্ডোজ, যে ব্যবহার পর্যায় জন্য।
আর্থমাইন্ড

29
getScene()এখনও ফিরে null
m0skit0

4
এই উত্তর, ঝরঝরে!
ভাগ্য

12
প্রারম্ভিককরণটি সম্পূর্ণ হওয়ার আগে (যেমন নিয়ন্ত্রণকারী প্রাথমিক পদ্ধতিতে) এটি কাজ করবে না কারণ getScene () বাতিল করে দেয়। মূল পোস্টারটি বোঝায় এটি তাঁর পরিস্থিতি। এক্ষেত্রে নীচে উত্কু dezdemir দ্বারা প্রদত্ত বিকল্প 1 আরও ভাল। আপনার যদি মঞ্চের প্রয়োজন না হয় তবে একজন শ্রোতা যথেষ্ট, আমি এটি একটি চিত্র দেখার জন্য প্রারম্ভিককরণ () এ ব্যবহার করি:bgimage.sceneProperty().addListener((observableScene, oldScene, newScene) -> { if (oldScene == null && newScene != null) { bgimage.fitWidthProperty().bind(newScene.widthProperty()); ... } });
জর্জি

32

আমি জানি এটি আপনি যে উত্তর চান তা নয়, তবে প্রস্তাবিত সমাধানগুলি ভাল নয় (এবং আপনার নিজস্ব উপায়টি) is কেন? কারণ তারা আবেদনের অবস্থার উপর নির্ভর করে। জাভাএফএক্সে একটি নিয়ন্ত্রণ, একটি দৃশ্য এবং একটি মঞ্চ একে অপরের উপর নির্ভর করে না। এর অর্থ একটি দৃশ্যে যুক্ত না হয়ে একটি নিয়ন্ত্রণ বেঁচে থাকতে পারে এবং একটি দৃশ্যের সাথে সংযুক্ত না হয়ে একটি দৃশ্য থাকতে পারে। এবং তারপরে, তাত্ক্ষণিক টি 1, নিয়ন্ত্রণ কোনও দৃশ্যের সাথে সংযুক্ত হয়ে যেতে পারে এবং তাত্ক্ষণিক টি 2 এ, সেই দৃশ্যে একটি দৃশ্যের যোগ করা যেতে পারে (এবং তারা কেন একে অপরের পর্যবেক্ষণযোগ্য বৈশিষ্ট্য তা ব্যাখ্যা করে)।

সুতরাং যে পদ্ধতির মাধ্যমে নিয়ামককে রেফারেন্স পেতে এবং কোনও পদ্ধতিতে অনুরোধ জানানো হয়, পর্যায়টি পেরিয়ে যাওয়া আপনার আবেদনে একটি রাজ্য যুক্ত করে। এর অর্থ আপনি পর্যায়ে তৈরি হওয়ার ঠিক পরে, সঠিক মুহূর্তে আপনাকে সেই পদ্ধতিটি শুরু করতে হবে। অন্য কথায়, আপনাকে এখনই একটি আদেশ অনুসরণ করতে হবে: 1- মঞ্চ তৈরি করুন 2- একটি তৈরি পদ্ধতির মাধ্যমে এই তৈরি পর্যায়টি নিয়ামকের কাছে পৌঁছে দিন।

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

তাহলে সঠিক সমাধান কী? দুটি বিকল্প রয়েছে:

1- আপনার পন্থাটি পেতে নিয়ামক শ্রবণ বৈশিষ্ট্যে আপনার পন্থা। আমি মনে করি এটি সঠিক পন্থা। এটার মত:

pane.sceneProperty().addListener((observableScene, oldScene, newScene) -> {
    if (oldScene == null && newScene != null) {
        // scene is set for the first time. Now its the time to listen stage changes.
        newScene.windowProperty().addListener((observableWindow, oldWindow, newWindow) -> {
            if (oldWindow == null && newWindow != null) {
                // stage is set. now is the right time to do whatever we need to the stage in the controller.
                ((Stage) newWindow).maximizedProperty().addListener((a, b, c) -> {
                    if (c) {
                        System.out.println("I am maximized!");
                    }
                });
            }
        });
    }
});

2- আপনি যেখানে তৈরি করবেন সেখানে যা করতে হবে তা করুন Stage(এবং এটি আপনি চান না):

Stage stage = new Stage();
stage.maximizedProperty().addListener((a, b, c) -> {
            if (c) {
                System.out.println("I am maximized!");
            }
        });
stage.setScene(someScene);
...

4
এটি গ্রহের সবচেয়ে সংক্ষিপ্ত জাভাএফএক্স রেফারেন্স !! ধন্যবাদ, উত্কু!
আরম পারোনিক্যান

এটি দেখার আকর্ষণীয় উপায়। ধন্যবাদ :)
উত্কু dezdemir

আমি এই পদ্ধতির ব্যবহারটি একটি টেবিলভিউ পপুলেশন করার চেষ্টা করছি এবং টেবিলভিউতে একটি প্রগতিশাস্ত্র কেন্দ্রিক শ্রদ্ধা প্রদর্শন করার চেষ্টা করছি তবে দেখা যাচ্ছে যে getX () এবং getY () এর ইভেন্টের মানগুলির মধ্যে একই রকম নয় আপনি যদি সমস্ত আরম্ভের পরে ব্যবহার করেন প্রক্রিয়া সমাপ্তি (একটি বোতামে ক্লিক ইভেন্টের ভিতরে) হয় দৃশ্য এবং মঞ্চের জন্য, এমনকি মঞ্চে getX () এবং getY () ফেরত নাএন, কোনও ধারণা?
লিওবেলিজুইয়েরদো

@leobelizquierdo, এই মুহুর্তে এই getY () সমস্যাটি পেয়েছে, আপনি কি একাকীকরণ খুঁজে পেয়েছেন?
জোনাসআনন

যদি আমি paneএমন একটি দৃশ্যে যোগ করি যা ইতিমধ্যে কোনও মঞ্চের সাথে সংযুক্ত থাকে, তবে এটি কাজ করবে না, তাই না? scenePropertyশ্রোতাদের চেক করা উচিত নয় এবং কেবল stagePropertyমঞ্চটি শূন্য থাকলে শ্রোতাদের যুক্ত করা উচিত? অন্যথায়, এখনই আমার যা প্রয়োজন তা কেবল তাড়াতাড়ি করুন?
আগামীকাল

14

কন্ট্রোলারে স্টেজ অবজেক্ট পাওয়ার সহজ উপায় হ'ল:

  1. নিজস্ব তৈরি কন্ট্রোলার ক্লাসে একটি অতিরিক্ত পদ্ধতি যুক্ত করুন (এটি নিয়ামক শ্রেণিতে মঞ্চ নির্ধারণের জন্য সেটটার পদ্ধতি হবে),

    private Stage myStage;
    public void setStage(Stage stage) {
         myStage = stage;
    }
    
  2. শুরুর পদ্ধতিতে এবং সেট পর্যায়ে নিয়ামক পান

    FXMLLoader loader = new FXMLLoader(getClass().getResource("MyFXML.fxml"));
    OwnController controller = loader.getController();
    controller.setStage(this.stage);
    
  3. এখন আপনি নিয়ামক পর্যায়ে অ্যাক্সেস করতে পারেন


এই ছিল আমার জন্য বিজয়ী। রবার্ট মার্টিনের উত্তর প্রথমে কাজ করেছিল তবে তারপরে একটি ত্রুটি ছুঁড়ে দেওয়া শুরু করে যা আমি stageএরকম হয়ে সমাধান করেছি ।
দামেউল

1

এফএক্স: আইডি নির্ধারণ করুন বা যেকোন নোড / অ্যাঙ্করপেন, বোতাম ইত্যাদিতে ভেরিয়েবল ঘোষণা করুন তারপরে এতে ইভেন্ট হ্যান্ডলার যুক্ত করুন এবং ইভেন্ট হ্যান্ডলারের মধ্যে নীচে প্রদত্ত কোডটি সন্নিবেশ করুন:

Stage stage = (Stage)((Node)((EventObject) eventVariable).getSource()).getScene().getWindow();

আশা করি, এটি আপনার পক্ষে কাজ করে !!


1

প্ল্যাটফর্ম.আরনলটার প্রাথমিককরণ শেষ না হওয়া পর্যন্ত সম্পাদন রোধ করতে কাজ করে। এই ক্ষেত্রে, আমি উইন্ডোটির প্রস্থকে পুনরায় আকার দেওয়ার সময় তালিকার ভিউটি রিফ্রেশ করতে চাই।

Platform.runLater(() -> {
    ((Stage) listView.getScene().getWindow()).widthProperty().addListener((obs, oldVal, newVal) -> {
        listView.refresh();
    });
});

আপনার ক্ষেত্রে

Platform.runLater(()->{
    ((Stage)myPane.getScene().getWindow()).setOn*whatIwant*(...);
});

-3

আপনি node.getSceneযদি সাথে কল না করেন তবে আপনি এটি পেতে পারেন Platform.runLater, ফলাফলটি একটি নাল মান।

নাল মান উদাহরণ:

node.getScene();

উদাহরণ হিসাবে কোন নাল মান:

Platform.runLater(() -> {
    node.getScene().addEventFilter(KeyEvent.KEY_PRESSED, event -> {
               //your event
     });
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.