تمرير المعلمات JavaFX FXML




parameters dependency-injection (5)

كيف يمكنني تمرير المعلمات إلى نافذة ثانوية في javafx؟ هل هناك طريقة للتواصل مع وحدة التحكم المقابلة؟

على سبيل المثال: يختار المستخدم عميلًا من 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 هو النافذة الجديدة. المشكلة ، لا أستطيع إيجاد طريقة لإعلام وحدة التحكم أين تبحث عن معلومات العميل (عن طريق تمرير معرف كمعلمة).

أيه أفكار؟


في ما يلي مثال على تمرير المعلمات إلى مستند 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 متغير مساحة الاسم 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();
    }
}

هنا مثال على استخدام وحدة تحكم حقنها Guice.

/**
 * 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";
   }
}

لاحظ أن هذا المثال يحمّل العرض في وسط BoarderPane وهو جذر المشهد في Stage. هذا لا علاقة له بالمثال (تفاصيل تنفيذ حالة الاستخدام المحددة الخاصة بي) ولكنه قرر تركه كما قد يجد البعض أنه مفيد.


يحتوي javafx.scene.Node فئة زوج من أساليب setUserData (كائن) و getUserData كائن ()

التي يمكنك استخدامها لإضافة معلوماتك إلى العقدة.

لذلك ، يمكنك الاتصال page.setUserData (معلومات) ؛

ويمكن التحقق من وحدة تحكم ، إذا تم تعيين المعلومات. أيضاً ، يمكنك استخدام ObjectProperty من أجل نقل البيانات إلى الأمام ، إذا لزم الأمر.

راقب مستندًا هنا: http://docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html قبل العبارة "في الإصدار الأول ، يتم وضع علامة على handleButtonAction () بـFXML للسماح بالعلامات التي تم تعريفها في مستند وحدة التحكم لاستدعاءها .في المثال الثاني ، يتم إضافة تعليق على حقل الزر للسماح للمحمل بتعيين قيمته ، كما يتم وضع طريقة التهيئة () بشكل مشابه. "

لذلك ، تحتاج إلى إقران وحدة تحكم مع عقدة ، وتعيين بيانات المستخدم إلى العقدة.


يمكنك أن تقرر استخدام قائمة يمكن مراقبتها بشكل عام لتخزين البيانات العامة ، أو مجرد إنشاء طريقة عامة لتخزين البيانات واستردادها من وحدة التحكم المقابلة


هذا يعمل ..

تذكر في المرة الأولى التي تقوم فيها بطباعة القيمة الممررة التي ستحصل عليها فارغة ، يمكنك استخدامها بعد تحميل Windows ، وهو نفسه لكل ما تريد أن تكتبه لأي مكون آخر.

المراقب الأول

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

    }