mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-23 03:04:07 -04:00
在 Label 文本溢出时安装 Tooltip (#4467)
This commit is contained in:
parent
60ff34a587
commit
6b6276e6e2
@ -80,6 +80,7 @@ import javax.xml.parsers.DocumentBuilder;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@ -113,6 +114,8 @@ public final class FXUtils {
|
|||||||
public static final @Nullable ObservableBooleanValue DARK_MODE;
|
public static final @Nullable ObservableBooleanValue DARK_MODE;
|
||||||
public static final @Nullable Boolean REDUCED_MOTION;
|
public static final @Nullable Boolean REDUCED_MOTION;
|
||||||
|
|
||||||
|
public static final @Nullable MethodHandle TEXT_TRUNCATED_PROPERTY;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
String jfxVersion = System.getProperty("javafx.version");
|
String jfxVersion = System.getProperty("javafx.version");
|
||||||
int majorVersion = -1;
|
int majorVersion = -1;
|
||||||
@ -157,6 +160,20 @@ public final class FXUtils {
|
|||||||
PREFERENCES = preferences;
|
PREFERENCES = preferences;
|
||||||
DARK_MODE = darkMode;
|
DARK_MODE = darkMode;
|
||||||
REDUCED_MOTION = reducedMotion;
|
REDUCED_MOTION = reducedMotion;
|
||||||
|
|
||||||
|
MethodHandle textTruncatedProperty = null;
|
||||||
|
if (JAVAFX_MAJOR_VERSION >= 23) {
|
||||||
|
try {
|
||||||
|
textTruncatedProperty = MethodHandles.publicLookup().findVirtual(
|
||||||
|
Labeled.class,
|
||||||
|
"textTruncatedProperty",
|
||||||
|
MethodType.methodType(ReadOnlyBooleanProperty.class)
|
||||||
|
);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
LOG.warning("Failed to lookup textTruncatedProperty", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TEXT_TRUNCATED_PROPERTY = textTruncatedProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String DEFAULT_MONOSPACE_FONT = OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? "Consolas" : "Monospace";
|
public static final String DEFAULT_MONOSPACE_FONT = OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? "Consolas" : "Monospace";
|
||||||
@ -356,6 +373,22 @@ public final class FXUtils {
|
|||||||
ScrollUtils.addSmoothScrolling(scrollPane);
|
ScrollUtils.addSmoothScrolling(scrollPane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If the current environment is JavaFX 23 or higher, this method returns [Labeled#textTruncatedProperty()];
|
||||||
|
/// Otherwise, it returns `null`.
|
||||||
|
public static @Nullable ReadOnlyBooleanProperty textTruncatedProperty(Labeled labeled) {
|
||||||
|
if (TEXT_TRUNCATED_PROPERTY != null) {
|
||||||
|
try {
|
||||||
|
return (ReadOnlyBooleanProperty) TEXT_TRUNCATED_PROPERTY.invokeExact(labeled);
|
||||||
|
} catch (RuntimeException | Error e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final Duration TOOLTIP_FAST_SHOW_DELAY = Duration.millis(50);
|
private static final Duration TOOLTIP_FAST_SHOW_DELAY = Duration.millis(50);
|
||||||
private static final Duration TOOLTIP_SLOW_SHOW_DELAY = Duration.millis(500);
|
private static final Duration TOOLTIP_SLOW_SHOW_DELAY = Duration.millis(500);
|
||||||
private static final Duration TOOLTIP_SHOW_DURATION = Duration.millis(5000);
|
private static final Duration TOOLTIP_SHOW_DURATION = Duration.millis(5000);
|
||||||
@ -1170,17 +1203,39 @@ public final class FXUtils {
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Label truncatedLabel(String text, int limit) {
|
public static Label newSafeTruncatedLabel(String text) {
|
||||||
Label label = new Label();
|
Label label = new Label(text);
|
||||||
if (text.length() <= limit) {
|
label.setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS);
|
||||||
label.setText(text);
|
showTooltipWhenTruncated(label);
|
||||||
} else {
|
|
||||||
label.setText(StringUtils.truncate(text, limit));
|
|
||||||
installFastTooltip(label, text);
|
|
||||||
}
|
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String LABEL_FULL_TEXT_PROP_KEY = FXUtils.class.getName() + ".LABEL_FULL_TEXT";
|
||||||
|
|
||||||
|
public static void showTooltipWhenTruncated(Labeled labeled) {
|
||||||
|
ReadOnlyBooleanProperty textTruncatedProperty = textTruncatedProperty(labeled);
|
||||||
|
if (textTruncatedProperty != null) {
|
||||||
|
ChangeListener<Boolean> listener = (observable, oldValue, newValue) -> {
|
||||||
|
var label = (Labeled) ((ReadOnlyProperty<?>) observable).getBean();
|
||||||
|
var tooltip = (Tooltip) label.getProperties().get(LABEL_FULL_TEXT_PROP_KEY);
|
||||||
|
|
||||||
|
if (newValue) {
|
||||||
|
if (tooltip == null) {
|
||||||
|
tooltip = new Tooltip();
|
||||||
|
tooltip.textProperty().bind(label.textProperty());
|
||||||
|
label.getProperties().put(LABEL_FULL_TEXT_PROP_KEY, tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
FXUtils.installFastTooltip(label, tooltip);
|
||||||
|
} else if (tooltip != null) {
|
||||||
|
Tooltip.uninstall(label, tooltip);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
listener.changed(textTruncatedProperty, false, textTruncatedProperty.get());
|
||||||
|
textTruncatedProperty.addListener(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void applyDragListener(Node node, FileFilter filter, Consumer<List<File>> callback) {
|
public static void applyDragListener(Node node, FileFilter filter, Consumer<List<File>> callback) {
|
||||||
applyDragListener(node, filter, callback, null);
|
applyDragListener(node, filter, callback, null);
|
||||||
}
|
}
|
||||||
|
@ -180,8 +180,9 @@ public final class JavaInstallPage extends WizardSinglePage {
|
|||||||
|
|
||||||
pane.setLeft(new Label(name));
|
pane.setLeft(new Label(name));
|
||||||
|
|
||||||
Label valueLabel = FXUtils.truncatedLabel(value, 60);
|
Label valueLabel = FXUtils.newSafeTruncatedLabel(value);
|
||||||
FXUtils.copyOnDoubleClick(valueLabel);
|
FXUtils.copyOnDoubleClick(valueLabel);
|
||||||
|
BorderPane.setMargin(valueLabel, new Insets(0, 0, 0, 16));
|
||||||
BorderPane.setAlignment(valueLabel, Pos.CENTER_RIGHT);
|
BorderPane.setAlignment(valueLabel, Pos.CENTER_RIGHT);
|
||||||
pane.setCenter(valueLabel);
|
pane.setCenter(valueLabel);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user