JavaFX Node.setOnMouseEntered / Exited的不稳定行为

时间:2016-02-02 08:08:47

标签: java events javafx label mouse

在我的JavaFX项目中,我有一个ModifiedTreeCellextends TreeCell。在那个类中,我有两个函数可以监听鼠标是进入还是退出TreeCell。然而,这些方法似乎非常不可靠。

或者:

A)他们根本没有检测到鼠标进入,也没有弹出窗口。

B)他们一直在呼叫ENTEREDEXITED,所以弹出窗口一遍又一遍地闪烁。

C)他们将检测到Enter,然后立即检测到Exit,即使鼠标仍然在Label的边界内。

我该如何解决这个问题?

如果你想亲眼看看我的意思,我编译了一个我项目的可运行Jar文件:

Here is the repo。下载后,运行D2BT.jar并创建一个新帐户,一个新角色,然后添加Ring之类的项目,点击Magic中的ChoiceBox,然后点击添加项Button。转到查看帐户树Tab,然后将鼠标悬停在其中一个Label(蓝色)中。

好的,在下面的图片中,我知道我的鼠标光标看起来像是在Label的边缘,但是我告诉你,如果你自己尝试过它并不是吗?真的很重要鼠标在哪里。 setOnMouseEntered/Exited命令根本无法正常工作。我知道它似乎是ItemFrame Popup导致问题,但我向您保证即使您发表评论frame.show();frame.hide();也会发生这种情况方法中显示的方法。

Image

以下是ModifiedTreeCell类:

package application;

import javafx.scene.control.Label;
import javafx.scene.control.TreeCell;
import logic.Item;

/**
 * This TreeCell object is for the TreeCellFactory
 * function in the GUI class. The TreeCellFactory
 * function will convert TreeItem objects into
 * ModifiedTreeCell objects which display the 
 * necesary information to the user, such as
 * a Label displaying either the Account name, 
 * Character name, or Item in a readable fashion.
 * @author Kevin
 *
 */
public class ModifiedTreeCell extends TreeCell<TreeViewable>
{
    /**
     * This Label will display the neccesary text related to the item.
     * The Label may have a `on Mouse Hover` listener which will display
     * a ItemFrame_Animated IF the TreeViewable object claims it to be an item.
     */
    private Label displayProperty;

    @Override public void updateItem(TreeViewable value, boolean empty)
    {
        if (!empty)
        {
            setEditable(true);

            // Create the label for this cell.
            displayProperty = new Label(value.getTextProperty());
            displayProperty.getStyleClass().clear();

            // If Value is an Item object...
            if (value instanceof Item)
            {
                // Item Reference.
                Item ref = (Item) value;

                // Create a Popup window of the item hovered over.
                ItemFrame_Animated frame = new ItemFrame_Animated(ref);
                displayProperty.setFont(GUI.diabloFont);
                displayProperty.setTextFill(ref.getQuality().getColor());

                displayProperty.setOnMouseEntered(e ->
                {
                    System.out.println("MOUSE ENTERED THIS LABEL");
                    frame.show(GUI.window);
                });
                displayProperty.setOnMouseExited(e ->
                {
                    System.out.println("MOUSE EXITED THIS LABEL");
                    frame.hide();
                });
            }

            displayProperty.setStyle(GUI.DEBUG_PANE_BORDER);

            // Display a Node for this cell.
            setGraphic(displayProperty);
        }
        else 
        {
            // No cell to be displayed, set to null.
            setText("");
            setGraphic(null);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我终于成功编译了你的项目。 结果并不令人意外 - &gt;通过评论frame.hide()行,弹出窗口保持打开状态。以下是3.

的解决方案

现在你可以申请一些积分来获得一个不会很快变得混乱的超级应用程序。

  1. 为您的Java项目获得一个很好的构建架构。您可以通过将其组织为Maven项目来完成此操作。这只是一个建议,重点是你应该非常自信地获取资源文件(在你的项目中,你通过至少2或3种不同的方法,使用File类和{{1方法。
  2. 在开始编码之前,请仔细考虑您的架构。我很确定你之前没有想过任何模式或任何idioma。考虑一下如何在处理特定逻辑部分的multiples mini-API中拆分应用程序。此外,您的逻辑和GUI之间的差距应该更大,以避免意大利面条代码。
  3. 阅读有关JavaFX的更多教程。您尝试使用Popup实现的目标已经存在,并且称为工具提示,您已经在应用程序中使用它,它可以像任何其他JavaFX组件一样自定义。
  4. 我希望你能成功为所有Diablo2游戏玩家提供一个非常有用的应用程序! :)