Я в настоящее время все еще на 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);
}
}
}
Чтобы воссоздать его, вам нужно развернуть рабочую область до полного размера экрана, а затем навести курсор мыши на кнопку в правом нижнем углу, на нижнем правом краю кнопки и затем навести курсор мыши на всплывающую подсказку. Он начнет мигать.
Спасибо за любую помощь