当前位置: 首页 > 知识库问答 >
问题:

保持工具提示打开,只要鼠标在上面

范麒
2023-03-14

我通过fxmlTableColumn标题创建工具提示,如下所示:

<TableColumn>
    <cellValueFactory>
        <PropertyValueFactory property="someProperty" />
    </cellValueFactory>
    <graphic>
        <Label text="Column 1">
            <tooltip>
                <Tooltip text="Tooltip text" />
            </tooltip>
        </Label>
    </graphic>
</TableColumn>

如果将鼠标移到工具提示上,我希望工具提示保持打开状态。最终,我希望工具提示文本中有可点击的链接(就像Eclipse JavaDoc工具提示一样)。可能吗?

编辑:考虑到答案,我现在尝试以下方法:

Label label = new Label();
label.setText("test text");
DelayedTooltip beakerTip = new DelayedTooltip();
beakerTip.setDuration(3000);
beakerTip.setText("Science from Base: 12");
beakerTip.isHoveringTarget(label);
Tooltip tooltip = new Tooltip();
tooltip.setText("test tooltip text");
label.setTooltip(beakerTip);
myTableColumn.setGraphic(label);

这里的问题是label与工具提示不同。因此,如果鼠标在工具提示上而不是在label上,则工具提示是隐藏的。我不能将工具提示本身作为悬停目标传递,因为它不是Node


共有3个答案

娄德运
2023-03-14

以下是破解工具提示行为的方法:

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.control.Tooltip;
import javafx.util.Duration;

import java.lang.reflect.Field;

/**
 * @author rdeardorff
 */
public class TooltipDelay {

    public static void hackTooltipActivationTimer( Tooltip tooltip, int delay ) {
        hackTooltipTiming( tooltip, delay, "activationTimer" );
    }

    public static void hackTooltipHideTimer( Tooltip tooltip, int delay ) {
        hackTooltipTiming( tooltip, delay, "hideTimer" );
    }

    private static void hackTooltipTiming( Tooltip tooltip, int delay, String property ) {
        try {
            Field fieldBehavior = tooltip.getClass().getDeclaredField( "BEHAVIOR" );
            fieldBehavior.setAccessible( true );
            Object objBehavior = fieldBehavior.get( tooltip );

            Field fieldTimer = objBehavior.getClass().getDeclaredField( property );
            fieldTimer.setAccessible( true );
            Timeline objTimer = (Timeline) fieldTimer.get( objBehavior );

            objTimer.getKeyFrames().clear();
            objTimer.getKeyFrames().add( new KeyFrame( new Duration( delay ) ) );
        }
        catch ( Exception e ) {
            e.printStackTrace();
        }
    }
}
姜建德
2023-03-14

我现在使用这个类,它按预期工作:

public class HoveringTooltip extends Tooltip {

    private Timer timer = new Timer();
    private Map<Object, Boolean> mapHoveringTarget2Hovering = new ConcurrentHashMap<>();
    private final int duration;

    public HoveringTooltip(int duration) {
        super.setAutoHide(false);
        this.duration = duration;
    }

    public void addHoveringTarget(Node object) {

        mapHoveringTarget2Hovering.put(object, false);
        object.setOnMouseEntered(e -> {
            onMouseEntered(object);
        });
        object.setOnMouseExited(e -> {
            onMouseExited(object);
        });
    }

    public void addHoveringTarget(Scene object) {

        mapHoveringTarget2Hovering.put(object, false);
        object.setOnMouseEntered(e -> {
            onMouseEntered(object);
        });
        object.setOnMouseExited(e -> {
            onMouseExited(object);
        });
    }

    @Override
    public void hide() {

        // super.hide();
    }

    public boolean isHovering() {

        return isHoveringProperty().get();
    }

    public BooleanProperty isHoveringProperty() {

        synchronized(mapHoveringTarget2Hovering) {
            for(Entry<Object, Boolean> e : mapHoveringTarget2Hovering.entrySet()) {
                if(e.getValue()) {
                    // if one hovering target is hovering, return true
                    return new ReadOnlyBooleanWrapper(true);
                }
            }
            // no hovering on any target, return false
            return new ReadOnlyBooleanWrapper(false);
        }
    }

    private synchronized void onMouseEntered(Object object) {

        // System.err.println("Mouse entered for " + object + ", canelling timer");
        // stop a potentially running hide timer
        timer.cancel();
        mapHoveringTarget2Hovering.put(object, true);
    }

    private synchronized void onMouseExited(Object object) {

        // System.err.println("Mouse exit for " + object + ", starting timer");
        mapHoveringTarget2Hovering.put(object, false);
        startTimer();
    }

    private void startTimer() {

        timer.cancel();
        timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {

                Platform.runLater(new Runnable() {

                    @Override
                    public void run() {

                        if(!isHovering())
                            HoveringTooltip.super.hide();
                    }
                });
            }
        }, duration);
    }
}
融唯
2023-03-14

的确,这是可能的,但它基本上需要删除工具提示的大部分基本功能。我就是这样实现同样的事情的:

首先,我根据基本工具提示制作了一个自定义工具提示(此代码是对类似问题的修改

public class DelayedTooltip extends Tooltip {

    private int duration = 0;
    private BooleanProperty isHoveringPrimary = new SimpleBooleanProperty(false);
    private BooleanProperty isHoveringSecondary = new SimpleBooleanProperty(false);

    public void setDuration(int d) {
        duration = d;
    }

    public BooleanProperty isHoveringPrimaryProperty()
    {
        return isHoveringPrimary;
    }

    public BooleanProperty isHoveringSecondaryProperty()
    {
        return isHoveringSecondary;
    }

    public void isHoveringTargetPrimary(Node node){
        node.setOnMouseEntered(e -> isHoveringPrimary.set(true));
        node.setOnMouseExited(e -> isHoveringPrimary.set(false));
    }

       //Usually you will use the tooltip here so enter tooltip.getGraphic() for the node.
    public void isHoveringTargetSecondary(Node node){
        node.setOnMouseEntered(e -> isHoveringTooltip.set(true)):
        node.setOnMouseExited(e -> isHoveringTooltip.set(false));
    }

    @Override
    public void hide() {
        if(isHoveringPrimary.get()==true || isHoveringTooltip.get()==true)
        {
            Timeline timeline = new Timeline();
            KeyFrame key = new KeyFrame(Duration.millis(duration));
            timeline.getKeyFrames().add(key);
            timeline.setOnFinished(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent t) {
                    DelayedTooltip.super.hide();
                }
            });
            timeline.play();
        }
        else
        {
            DelayedTooltip.super.hide();
        }
    }
}

这就是我安装工具提示的方式

    DelayedTooltip beakerTip = new DelayedTooltip();
    beakerTip.setDuration(999999);
    beakerTip.setText("Science from Base: 12");
    beakerTip.isHoveringTargetPrimary(beakerView);
        beakerTip.isHoveringTargetSecondary(beakerTip.geoGraphic());

如果愿意,您可以编辑它,并将其变成一个具有多个参数的方法,但如果不这样做,这确实有效。

 类似资料:
  • 我想用鼠标在表格中的图像上显示工具提示。请找到小提琴样品http://jsfiddle.net/FpBu4/42/我想用鼠标在图像的右上方显示工具提示。下面是示例脚本: 请建议如何在图像上的鼠标上显示图像附近的工具提示。谢谢

  • 我在使用mousemove事件显示工具提示时遇到了一些麻烦。基本上,当我的鼠标指针在图片框的某些区域上时,我想显示一个工具提示。我试图使用mousemove事件来完成此操作,确定阉羊指针位于最佳位置,并(如果是这样)使用settools tip设置工具提示。 这是我的mousemove事件(我注意到,当显示工具提示时,mousemove会持续触发,我会检查位置是否真的发生了变化) 这工作正常,除了

  • 我正在用chart.js实现一些点图。没有问题,但我想做的是有一个工具提示,不只是附加到给定的数据点。现在,您可以创建一个工具提示,它将在图表上给定数据点附近显示一个弹出窗口。例如,如果我有数据点[1,5]、[2,6]和[3,7],它将很高兴地显示这三个数据点。 但我想要的是,当我在1,5到2,6之间时,看看我在x轴上的确切位置。1.5,1.6等。 但这是x和y在画布上的位置,与实际的x和y图形坐

  • 我希望鼠标悬停在节点上时,工具提示显示在鼠标旁边。我尝试了我在上找到的解决方案,但到目前为止,只有Boxun的解决方案起到了作用,尽管这并不是我想要的(D3.js:使用元素位置来定位工具提示,而不是鼠标位置?)。 我想知道为什么在我的听众功能中, ,功能 或者 显示在svg的顶部,而不是鼠标所在的位置。 通过阅读上面链接的答案,我认为我必须以某种方式转换坐标,但我无法使其工作。

  • 如果我的标签包含文本太长,并且当我用鼠标悬停在标签上时,我想要一个显示整个标签文本的工具提示。是否可以在 SceneBuilder 中执行此操作,或者我必须以编程方式对所有标注执行此操作?

  • 我试图在qtip中的图像上显示jQuery UI工具提示。现在,工具提示显示在工具提示后面。你知道怎么把它展示在它面前吗? 小提琴在这里:http://jsfiddle.net/wYM2Q/ 将鼠标移到文本“bind qtip to this”上。然后将鼠标悬停在qtip内的图像上。你会看到qtip后面显示的工具提示,我想在它前面显示。