Skip to content

Commit 42d1581

Browse files
authored
fix: 可输入的 combobox 内容没有与不可输入的对齐 (#5635)
1 parent 995a23c commit 42d1581

2 files changed

Lines changed: 277 additions & 1 deletion

File tree

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
//
2+
// Source code recreated from a .class file by IntelliJ IDEA
3+
// (powered by Fernflower decompiler)
4+
//
5+
6+
package com.jfoenix.skins;
7+
8+
import com.jfoenix.adapters.skins.ComboBoxListViewSkin;
9+
import com.jfoenix.concurrency.JFXUtilities;
10+
import com.jfoenix.controls.JFXComboBox;
11+
import com.jfoenix.transitions.CachedTransition;
12+
import javafx.animation.*;
13+
import javafx.application.Platform;
14+
import javafx.beans.binding.Bindings;
15+
import javafx.beans.binding.BooleanBinding;
16+
import javafx.beans.property.ObjectProperty;
17+
import javafx.beans.property.SimpleObjectProperty;
18+
import javafx.geometry.Insets;
19+
import javafx.geometry.Pos;
20+
import javafx.scene.control.ComboBoxBase;
21+
import javafx.scene.layout.*;
22+
import javafx.scene.paint.Color;
23+
import javafx.scene.paint.Paint;
24+
import javafx.scene.text.Text;
25+
import javafx.scene.transform.Scale;
26+
import javafx.util.Duration;
27+
28+
public class JFXComboBoxListViewSkin<T> extends ComboBoxListViewSkin<T> {
29+
protected final ObjectProperty<Paint> promptTextFill;
30+
private boolean invalid = true;
31+
private final StackPane customPane;
32+
private final StackPane line = new StackPane();
33+
private final StackPane focusedLine = new StackPane();
34+
private final Text promptText = new Text();
35+
private final double initScale = 0.05;
36+
private final Scale scale;
37+
private final Timeline linesAnimation;
38+
private ParallelTransition transition;
39+
private CachedTransition promptTextUpTransition;
40+
private CachedTransition promptTextDownTransition;
41+
private CachedTransition promptTextColorTransition;
42+
private final Scale promptTextScale;
43+
private Paint oldPromptTextFill;
44+
private final BooleanBinding usePromptText;
45+
46+
public JFXComboBoxListViewSkin(JFXComboBox<T> comboBox) {
47+
super(comboBox);
48+
this.scale = new Scale(this.initScale, 1.0F);
49+
this.linesAnimation = new Timeline(new KeyFrame(Duration.ZERO, new KeyValue(this.scale.xProperty(), this.initScale, Interpolator.EASE_BOTH), new KeyValue(this.focusedLine.opacityProperty(), 0, Interpolator.EASE_BOTH)), new KeyFrame(Duration.millis(1.0F), new KeyValue(this.focusedLine.opacityProperty(), 1, Interpolator.EASE_BOTH)), new KeyFrame(Duration.millis(160.0F), new KeyValue(this.scale.xProperty(), 1, Interpolator.EASE_BOTH)));
50+
this.promptTextScale = new Scale(1.0F, 1.0F, 0.0F, 0.0F);
51+
this.promptTextFill = new SimpleObjectProperty(Color.valueOf("#B2B2B2"));
52+
this.usePromptText = Bindings.createBooleanBinding(this::usePromptText, ((JFXComboBox) this.getSkinnable()).valueProperty(), this.getSkinnable().promptTextProperty());
53+
this.getArrowButton().setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, null, null)));
54+
this.promptText.textProperty().bind(comboBox.promptTextProperty());
55+
this.promptText.fillProperty().bind(this.promptTextFill);
56+
this.promptText.getStyleClass().addAll("text", "prompt-text");
57+
this.promptText.getTransforms().add(this.promptTextScale);
58+
if (!comboBox.isLabelFloat()) {
59+
this.promptText.visibleProperty().bind(this.usePromptText);
60+
}
61+
62+
this.customPane = new StackPane();
63+
this.customPane.setMouseTransparent(true);
64+
this.customPane.getStyleClass().add("combo-box-button-container");
65+
this.customPane.backgroundProperty().bindBidirectional(this.getSkinnable().backgroundProperty());
66+
this.customPane.setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, null, null)));
67+
this.customPane.getChildren().add(this.promptText);
68+
this.getChildren().add(0, this.customPane);
69+
StackPane.setAlignment(this.promptText, Pos.CENTER_LEFT);
70+
this.line.getStyleClass().add("input-line");
71+
this.focusedLine.getStyleClass().add("input-focused-line");
72+
this.getChildren().add(this.line);
73+
this.getChildren().add(this.focusedLine);
74+
this.line.setPrefHeight(1.0F);
75+
this.line.setTranslateY(1.0F);
76+
this.line.setManaged(false);
77+
this.line.setBackground(new Background(new BackgroundFill(((JFXComboBox) this.getSkinnable()).getUnFocusColor(), CornerRadii.EMPTY, Insets.EMPTY)));
78+
if (this.getSkinnable().isDisabled()) {
79+
this.line.setBorder(new Border(new BorderStroke(((JFXComboBox) this.getSkinnable()).getUnFocusColor(), BorderStrokeStyle.DASHED, CornerRadii.EMPTY, new BorderWidths(1.0F))));
80+
this.line.setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)));
81+
}
82+
83+
this.focusedLine.setPrefHeight(2.0F);
84+
this.focusedLine.setTranslateY(0.0F);
85+
this.focusedLine.setBackground(new Background(new BackgroundFill(((JFXComboBox) this.getSkinnable()).getFocusColor(), CornerRadii.EMPTY, Insets.EMPTY)));
86+
this.focusedLine.setOpacity(0.0F);
87+
this.focusedLine.getTransforms().add(this.scale);
88+
this.focusedLine.setManaged(false);
89+
if (comboBox.isEditable()) {
90+
comboBox.getEditor().setStyle("-fx-background-color:TRANSPARENT;-fx-padding: 4 8 4 8");
91+
comboBox.getEditor().promptTextProperty().unbind();
92+
comboBox.getEditor().setPromptText(null);
93+
comboBox.getEditor().textProperty().addListener((o, oldVal, newVal) -> {
94+
this.usePromptText.invalidate();
95+
comboBox.setValue(this.getConverter().fromString(newVal));
96+
});
97+
}
98+
99+
comboBox.labelFloatProperty().addListener((o, oldVal, newVal) -> {
100+
if (newVal) {
101+
this.promptText.visibleProperty().unbind();
102+
JFXUtilities.runInFX(() -> this.createFloatingAnimation());
103+
} else {
104+
this.promptText.visibleProperty().bind(this.usePromptText);
105+
}
106+
107+
this.createFocusTransition();
108+
});
109+
comboBox.focusColorProperty().addListener((o, oldVal, newVal) -> {
110+
if (newVal != null) {
111+
this.focusedLine.setBackground(new Background(new BackgroundFill(newVal, CornerRadii.EMPTY, Insets.EMPTY)));
112+
if (((JFXComboBox) this.getSkinnable()).isLabelFloat()) {
113+
this.promptTextColorTransition = new CachedTransition(this.customPane, new Timeline(new KeyFrame(Duration.millis(1300.0F), new KeyValue(this.promptTextFill, newVal, Interpolator.EASE_BOTH)))) {
114+
{
115+
this.setDelay(Duration.millis(0.0F));
116+
this.setCycleDuration(Duration.millis(160.0F));
117+
}
118+
119+
protected void starting() {
120+
super.starting();
121+
JFXComboBoxListViewSkin.this.oldPromptTextFill = JFXComboBoxListViewSkin.this.promptTextFill.get();
122+
}
123+
};
124+
this.transition = null;
125+
}
126+
}
127+
128+
});
129+
comboBox.unFocusColorProperty().addListener((o, oldVal, newVal) -> {
130+
if (newVal != null) {
131+
this.line.setBackground(new Background(new BackgroundFill(newVal, CornerRadii.EMPTY, Insets.EMPTY)));
132+
}
133+
134+
});
135+
comboBox.disabledProperty().addListener((o, oldVal, newVal) -> {
136+
this.line.setBorder(newVal ? new Border(new BorderStroke(((JFXComboBox) this.getSkinnable()).getUnFocusColor(), BorderStrokeStyle.DASHED, CornerRadii.EMPTY, new BorderWidths(this.line.getHeight()))) : Border.EMPTY);
137+
this.line.setBackground(new Background(new BackgroundFill(newVal ? Color.TRANSPARENT : ((JFXComboBox) this.getSkinnable()).getUnFocusColor(), CornerRadii.EMPTY, Insets.EMPTY)));
138+
});
139+
comboBox.focusedProperty().addListener((o, oldVal, newVal) -> {
140+
if (newVal) {
141+
this.focus();
142+
} else {
143+
this.unFocus();
144+
}
145+
146+
});
147+
comboBox.valueProperty().addListener((o, oldVal, newVal) -> {
148+
if (((JFXComboBox) this.getSkinnable()).isLabelFloat()) {
149+
this.animateFloatingLabel(newVal != null && !newVal.toString().isEmpty());
150+
}
151+
152+
});
153+
}
154+
155+
protected void layoutChildren(double x, double y, double w, double h) {
156+
super.layoutChildren(x, y, w, h);
157+
this.customPane.resizeRelocate(x, y, w, h);
158+
if (this.invalid) {
159+
this.invalid = false;
160+
if (!this.getSkinnable().isEditable()) {
161+
Text javaPromptText = (Text) super.getDisplayNode().lookup(".text");
162+
if (javaPromptText != null) {
163+
this.promptTextFill.set(javaPromptText.getFill());
164+
}
165+
}
166+
167+
this.createFloatingAnimation();
168+
if (((ComboBoxBase) this.getSkinnable()).getValue() != null) {
169+
this.animateFloatingLabel(true);
170+
}
171+
}
172+
173+
this.focusedLine.resizeRelocate(x, this.getSkinnable().getHeight(), w, this.focusedLine.prefHeight(-1.0F));
174+
this.line.resizeRelocate(x, this.getSkinnable().getHeight(), w, this.line.prefHeight(-1.0F));
175+
this.scale.setPivotX(w / (double) 2.0F);
176+
}
177+
178+
private void createFloatingAnimation() {
179+
this.promptTextUpTransition = new CachedTransition(this.customPane, new Timeline(new KeyFrame(Duration.millis(1300.0F), new KeyValue(this.promptText.translateYProperty(), -this.customPane.getHeight() + 6.05, Interpolator.EASE_BOTH), new KeyValue(this.promptTextScale.xProperty(), 0.85, Interpolator.EASE_BOTH), new KeyValue(this.promptTextScale.yProperty(), 0.85, Interpolator.EASE_BOTH)))) {
180+
{
181+
this.setDelay(Duration.millis(0.0F));
182+
this.setCycleDuration(Duration.millis(240.0F));
183+
}
184+
};
185+
this.promptTextColorTransition = new CachedTransition(this.customPane, new Timeline(new KeyFrame(Duration.millis(1300.0F), new KeyValue(this.promptTextFill, ((JFXComboBox) this.getSkinnable()).getFocusColor(), Interpolator.EASE_BOTH)))) {
186+
{
187+
this.setDelay(Duration.millis(0.0F));
188+
this.setCycleDuration(Duration.millis(160.0F));
189+
}
190+
191+
protected void starting() {
192+
super.starting();
193+
JFXComboBoxListViewSkin.this.oldPromptTextFill = JFXComboBoxListViewSkin.this.promptTextFill.get();
194+
}
195+
};
196+
this.promptTextDownTransition = new CachedTransition(this.customPane, new Timeline(new KeyFrame(Duration.millis(1300.0F), new KeyValue(this.promptText.translateYProperty(), 0, Interpolator.EASE_BOTH), new KeyValue(this.promptTextScale.xProperty(), 1, Interpolator.EASE_BOTH), new KeyValue(this.promptTextScale.yProperty(), 1, Interpolator.EASE_BOTH)))) {
197+
{
198+
this.setDelay(Duration.millis(0.0F));
199+
this.setCycleDuration(Duration.millis(240.0F));
200+
}
201+
};
202+
this.promptTextDownTransition.setOnFinished((finish) -> {
203+
this.promptText.setTranslateY(0.0F);
204+
this.promptTextScale.setX(1.0F);
205+
this.promptTextScale.setY(1.0F);
206+
});
207+
}
208+
209+
private void focus() {
210+
if (this.transition == null) {
211+
this.createFocusTransition();
212+
}
213+
214+
this.transition.play();
215+
}
216+
217+
private void animateFloatingLabel(boolean up) {
218+
if (this.promptText == null) {
219+
Platform.runLater(() -> this.animateFloatingLabel(up));
220+
} else {
221+
if (this.transition != null) {
222+
this.transition.stop();
223+
this.transition.getChildren().remove(this.promptTextUpTransition);
224+
this.transition.getChildren().remove(this.promptTextColorTransition);
225+
this.transition = null;
226+
}
227+
228+
if (up && this.promptText.getTranslateY() == (double) 0.0F) {
229+
this.promptTextDownTransition.stop();
230+
this.promptTextUpTransition.play();
231+
if (this.getSkinnable().isFocused()) {
232+
this.promptTextColorTransition.play();
233+
}
234+
} else if (!up) {
235+
this.promptTextUpTransition.stop();
236+
if (this.getSkinnable().isFocused()) {
237+
this.promptTextFill.set(this.oldPromptTextFill);
238+
}
239+
240+
this.promptTextDownTransition.play();
241+
}
242+
}
243+
244+
}
245+
246+
private void createFocusTransition() {
247+
this.transition = new ParallelTransition();
248+
if (((JFXComboBox) this.getSkinnable()).isLabelFloat()) {
249+
this.transition.getChildren().add(this.promptTextUpTransition);
250+
this.transition.getChildren().add(this.promptTextColorTransition);
251+
}
252+
253+
this.transition.getChildren().add(this.linesAnimation);
254+
}
255+
256+
private void unFocus() {
257+
if (this.transition != null) {
258+
this.transition.stop();
259+
}
260+
261+
this.scale.setX(this.initScale);
262+
this.focusedLine.setOpacity(0.0F);
263+
if (((JFXComboBox) this.getSkinnable()).isLabelFloat() && this.oldPromptTextFill != null) {
264+
this.promptTextFill.set(this.oldPromptTextFill);
265+
if (this.usePromptText()) {
266+
this.promptTextDownTransition.play();
267+
}
268+
}
269+
270+
}
271+
272+
private boolean usePromptText() {
273+
Object txt = ((JFXComboBox) this.getSkinnable()).getValue();
274+
String promptTxt = this.getSkinnable().getPromptText();
275+
return (txt == null || txt.toString().isEmpty()) && promptTxt != null && !promptTxt.isEmpty() && !this.promptTextFill.get().equals(Color.TRANSPARENT);
276+
}
277+
}

HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,6 @@ public VersionSettingsPage(boolean globalSetting) {
351351
cboWindowsSize.setPrefWidth(150);
352352
right.setLeft(cboWindowsSize);
353353
cboWindowsSize.setEditable(true);
354-
cboWindowsSize.setStyle("-fx-padding: 4 4 4 16");
355354
cboWindowsSize.setPromptText("854x480");
356355
cboWindowsSize.getItems().setAll(getSupportedResolutions());
357356

0 commit comments

Comments
 (0)