首页 \ 问答 \ JavaFX:未在自定义组件上调用initialize()方法(JavaFX: initialize() method not being called on custom component)

JavaFX:未在自定义组件上调用initialize()方法(JavaFX: initialize() method not being called on custom component)

我正在尝试使用FXML标记创建自己的自定义JavaFX组件以及扩展HBox的控制器。 无论出于何种原因,都没有调用initialize()方法(我看不到调试输出)。 这仅适用于我的自定义组件,我的所有其他控制器都按预期运行,并且始终在初始化。 我不知道出了什么问题 - 这是我的代码。

NotificationItem.fxml(标记)

<fx:root type="javafx.scene.layout.HBox" xmlns:fx="http://javafx.com/fxml" spacing="5">
  <ImageView fx:id="image" preserveRatio="true" fitWidth="60" />
  <VBox alignment="center">
    <Text text="notification" />
    <Label fx:id="title" />
    <Label fx:id="content" />
    <Label fx:id="timestamp" />
  </VBox>
</fx:root>

NotificationItem.java(控制器)

public class NotificationItem extends HBox {
    public static final String FXML_FILENAME = "NotificationItem.fxml";

    @FXML private ResourceBundle resources;  
    @FXML private ImageView image;
    @FXML private Label title;
    @FXML private Label content;
    @FXML private Label timestamp;

    private Notification notification; 
    private AbstractModel associatedModel;

    public NotificationItem(Notification notification) {
        this.notification = notification;
        this.associatedModel = notification.getAssociatedModel();

        FXMLHelper.loadFxml("/com/github/norbo11/topbuilders/fxml/" + FXML_FILENAME, this, this);
    }

    @FXML
    public void initialize() {      
        System.out.println(notification.getType());

        switch (notification.getType()) {
            case ASSIGNMENT_CLOSE_TO_END:
                break;
            case EMPLOYEE_ASSIGNMENT_COMPLETE:
                break;
            case NEW_ASSIGNMENT:
                break;
            case NEW_MESSAGE:
                Message message = (Message) associatedModel;
                title.setText(resources.getString("home.notifications.new_message"));
                content.setText(resources.getString("messages.sender") + ": " + message.getSender());
                break;
            case NEW_QUOTE_REQUEST:
                break;
        }

        timestamp.setText(Util.formatDate(notification.getDate()));
    }
}

用于加载FXML的过程(忽略返回值,在这种情况下不使用)

public static LoadedFXML loadFxml(String filename, Object root, Object controller) {
        Log.info("Loading FXML: " + filename);
        Parent loadedRoot = null;
        AbstractController loadedController = null;

        try {
            FXMLLoader loader = new FXMLLoader(Main.getApp().getClass().getResource(filename));
            if (root != null) loader.setRoot(root);
            if (controller != null) loader.setController(controller);

            if (!filename.equals(LoginScene.getAbsoluteFxmlFilename())) {
                Employee user = Employee.getCurrentEmployee();

                //If the user is logged in
                if (user != null) {
                    Locale locale = Employee.getCurrentEmployee().getSettings().getLocale();
                    loader.setResources(ResourceBundle.getBundle("lang.lang", locale, ClassLoader.getSystemClassLoader()));
                }
            }

            if (root == null) loadedRoot = loader.load();
            if (controller == null) loadedController = loader.getController();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new LoadedFXML(loadedRoot, loadedController);
    }

I am trying to create my own custom JavaFX component using FXML markup as well as a controller which extends HBox. For whatever reason, the initialize() method is simply not being called (I can see no debug output). This only occurs for my custom component, all my other controllers behave as expected and are always being initialized. I have no clue what is wrong - here is my code.

NotificationItem.fxml (markup)

<fx:root type="javafx.scene.layout.HBox" xmlns:fx="http://javafx.com/fxml" spacing="5">
  <ImageView fx:id="image" preserveRatio="true" fitWidth="60" />
  <VBox alignment="center">
    <Text text="notification" />
    <Label fx:id="title" />
    <Label fx:id="content" />
    <Label fx:id="timestamp" />
  </VBox>
</fx:root>

NotificationItem.java (controller)

public class NotificationItem extends HBox {
    public static final String FXML_FILENAME = "NotificationItem.fxml";

    @FXML private ResourceBundle resources;  
    @FXML private ImageView image;
    @FXML private Label title;
    @FXML private Label content;
    @FXML private Label timestamp;

    private Notification notification; 
    private AbstractModel associatedModel;

    public NotificationItem(Notification notification) {
        this.notification = notification;
        this.associatedModel = notification.getAssociatedModel();

        FXMLHelper.loadFxml("/com/github/norbo11/topbuilders/fxml/" + FXML_FILENAME, this, this);
    }

    @FXML
    public void initialize() {      
        System.out.println(notification.getType());

        switch (notification.getType()) {
            case ASSIGNMENT_CLOSE_TO_END:
                break;
            case EMPLOYEE_ASSIGNMENT_COMPLETE:
                break;
            case NEW_ASSIGNMENT:
                break;
            case NEW_MESSAGE:
                Message message = (Message) associatedModel;
                title.setText(resources.getString("home.notifications.new_message"));
                content.setText(resources.getString("messages.sender") + ": " + message.getSender());
                break;
            case NEW_QUOTE_REQUEST:
                break;
        }

        timestamp.setText(Util.formatDate(notification.getDate()));
    }
}

Procedure used to load my FXML (ignore the return value, that isn't used in this case)

public static LoadedFXML loadFxml(String filename, Object root, Object controller) {
        Log.info("Loading FXML: " + filename);
        Parent loadedRoot = null;
        AbstractController loadedController = null;

        try {
            FXMLLoader loader = new FXMLLoader(Main.getApp().getClass().getResource(filename));
            if (root != null) loader.setRoot(root);
            if (controller != null) loader.setController(controller);

            if (!filename.equals(LoginScene.getAbsoluteFxmlFilename())) {
                Employee user = Employee.getCurrentEmployee();

                //If the user is logged in
                if (user != null) {
                    Locale locale = Employee.getCurrentEmployee().getSettings().getLocale();
                    loader.setResources(ResourceBundle.getBundle("lang.lang", locale, ClassLoader.getSystemClassLoader()));
                }
            }

            if (root == null) loadedRoot = loader.load();
            if (controller == null) loadedController = loader.getController();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new LoadedFXML(loadedRoot, loadedController);
    }

原文:https://stackoverflow.com/questions/27806953
更新时间:2022-03-15 09:03

最满意答案

所以,我的问题是,为什么即使在删除对象后我仍然可以调用Go_XXX_Your_Self()和Identify_Your_Self()?

由于未定义的行为

这是它在C ++中的工作原理吗? (甚至在你删除它之后呢?)

由于未定义的行为 。 无法保证它在其他实现中的工作方式相同。 再次, 未定义的行为

还可以检查一下它是否存在? (我知道理论上是不可能的,但我很想知道那里有什么方法)

delete MC1;
MC1 = nullptr;

通过在delete指针后将指针设置为nullptr ,运行时最有可能检测到您正在访问无效的,您没有权利的位置。 此外,通过努力为所有适用的指针执行此操作,您可以检查对象是否有效(如果非nullptr则有效)。

if(my_ptr) {
   // my_ptr is most possibly valid (though you can still go wrong)
   // use my_ptr
}

类似地,当它们尚未初始化为某个有效地址时,您还应该将原始指针设置为nullptr

MyClass* some_ptr = nullptr;
...

但同样,如果您可以访问现代C ++ 11工具,最好不要使用原始指针,只需使用std::unique_ptrstd::shared_ptr (取决于您所需的语义)。 在未来的C ++标准版本中,您可能还想使用建议的std::exempt_ptr ,它是一个非拥有的,仅观察指针包装器。


So, my question is, why I'm still able to call Go_XXX_Your_Self() and Identify_Your_Self() even after the object was deleted?

Because of undefined behavior.

Is this how it works in C++? (is there even after you delete it?)

Because of undefined behavior. There is no guarantee that it will work the same on other implementations. Again, undefined behavior.

Also can you check to see if it's not there? (I know theoretically is not possible but I'm curious to see what methods are out there)

delete MC1;
MC1 = nullptr;

By setting the pointer to nullptr after deleteing it, the runtime is most likely to detect that you are accessing an invalid, you-have-no-right-to-use location. Also, by diligently doing this for all applicable pointers, you have the ability to check if the object is valid or not (valid if non-nullptr).

if(my_ptr) {
   // my_ptr is most possibly valid (though you can still go wrong)
   // use my_ptr
}

Similarly, you should also set raw pointers to nullptr when they aren't yet initialized to some valid address.

MyClass* some_ptr = nullptr;
...

But again, if you have access to modern C++11 facilities, it's much better not to use raw pointers at all, and just use std::unique_ptr or std::shared_ptr (depending on your required semantics). And on future C++ standard revisions, you may also want to use the proposed std::exempt_ptr which is a non-owning, observe-only pointer wrapper.

相关问答

更多

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)