Мерцание всплывающей подсказки JavaFX с большой видимой продолжительностью - PullRequest
0 голосов
/ 16 января 2019

Я в настоящее время все еще на Java 8 и поэтому использовал обходной путь, который я нашел для установки видимой продолжительности для всплывающих подсказок в JavaFX. Хотя это позволяет мне контролировать, как долго всплывающие подсказки остаются открытыми, возникает проблема, когда всплывающие подсказки отображаются в правом нижнем углу пользовательского интерфейса, а затем пользователь наводит указатель мыши на всплывающую подсказку, он мерцает, пока мышь не закрывается. Я пробовал код ниже с Java 11 / JavaFX 11, но с использованием:

'tooltip.setShowDuration(Duration.minutes(4)); //Some of my custom tooltips in the real application have a lot of detail and the user may need them open for a long time.'

Я использую OnMouseExit для удаления всплывающей подсказки. Это работает в Java 11, и мерцание отсутствует, поскольку подсказка расположена лучше, поэтому наведение мыши (вызывающее мерцание) невозможно.

К сожалению, я еще не совсем в том месте, где могу перейти на Java 11. Есть ли обходной путь для проблемы мерцания, которую я вижу в Java 8 с кодом ниже.

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class TooltipFlicker extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        updateTooltipBehavior(600, Duration.minutes(4).toMillis(), 200, true);
        Tooltip tooltip=new Tooltip("Test the flicker bug!");
        Button button= new Button("Flicker");
        button.setOnMouseEntered(e->{
            Tooltip.install(button, tooltip);
        });
        button.setOnMouseExited(e->{
            Tooltip.uninstall(button, tooltip);
        });
        BorderPane borderPane = new BorderPane();

        borderPane.setRight(button);
        BorderPane bottomPane = new BorderPane();
        bottomPane.setBottom(borderPane);
        Scene scene = new Scene(bottomPane);
        stage.setWidth(450);
        stage.setHeight(500);
        stage.setScene(scene);
        stage.show();

    }

    /**Workaround I found on Stackoverflow to control tooltip behaviour pre-Java 9**/
    private static void updateTooltipBehavior(double openDelay, double visibleDuration,
            double closeDelay, boolean hideOnExit) {
            try {
                // Get the non public field "BEHAVIOR"
                Field fieldBehavior = Tooltip.class.getDeclaredField("BEHAVIOR");
                // Make the field accessible to be able to get and set its value
                fieldBehavior.setAccessible(true);
                // Get the value of the static field
                Object objBehavior = fieldBehavior.get(null);
                // Get the constructor of the private static inner class TooltipBehavior
                Constructor<?> constructor = objBehavior.getClass().getDeclaredConstructor(
                    Duration.class, Duration.class, Duration.class, boolean.class
                );
                // Make the constructor accessible to be able to invoke it
                constructor.setAccessible(true);
                // Create a new instance of the private static inner class TooltipBehavior
                Object tooltipBehavior = constructor.newInstance(
                    new Duration(openDelay), new Duration(visibleDuration),
                    new Duration(closeDelay), hideOnExit
                );
                // Set the new instance of TooltipBehavior
                fieldBehavior.set(null, tooltipBehavior);
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }


}

Чтобы воссоздать его, вам нужно развернуть рабочую область до полного размера экрана, а затем навести курсор мыши на кнопку в правом нижнем углу, на нижнем правом краю кнопки и затем навести курсор мыши на всплывающую подсказку. Он начнет мигать.

Спасибо за любую помощь

...