#java #css #javafx
#java #css #javafx
Вопрос:
Я хочу добавлять стили к ярлыку в зависимости от условий. Когда я пытаюсь это сделать, он перезаписывает предыдущий стиль. Есть ли лучший способ объединить стили?
Label lbl = new Label(labelDescription.getLabelText());
if (labelDescription.getLabelStyling() == LabelStyling.BOLD) {
lbl.setStyle("-fx-font-weight: bold;");
}
if (labelDescription.getLabelStyling() == LabelStyling.ITALIC) {
lbl.setStyle("-fx-font-style: italic;");
}
if (labelDescription.getTextSize() != null) {
lbl.setStyle("-fx-font-size: " labelDescription.getTextSize() "px;");
}
Комментарии:
1. Для подобных задач я рекомендую использовать классы стилей , основанные на классах, определенных в таблицах стилей CSS (или псевдоклассах, если вы хотите немного пофантазировать), а не использовать прямые строки стиля. Одним из преимуществ классов стилей перед строками стилей является то, что классы можно добавлять и удалять из коллекции, поэтому добавление нескольких классов стилей не перезаписывает предыдущие классы стилей.
Ответ №1:
Я думаю, что в вашем случае было бы проще немного реорганизовать логику стиля, например, так:
Label lbl = new Label(labelDescription.getLabelText());
String style = "";
if (labelDescription.getLabelStyling() == LabelStyling.BOLD) {
style = "-fx-font-weight: bold;";
}
if (labelDescription.getLabelStyling() == LabelStyling.ITALIC) {
style = "-fx-font-style: italic;";
}
if (labelDescription.getTextSize() != null) {
style = "-fx-font-size: " labelDescription.getTextSize() "px;";
}
lbl.setStyle(style);
Хотя это может быть довольно неэффективно, если установлено более этих 3 значений, вам следует рассмотреть возможность использования StringBuilder
Надеюсь, это помогло!
Ответ №2:
Обратите внимание, что вы можете просто установить шрифт программно, вообще не используя CSS:
Label lbl = new Label(labelDescription.getLabelText());
// get defaults:
Font font = lbl.getFont();
String family = font.getFamily();
double size = font.getSize();
FontPosture posture = FontPosture.REGULAR ;
FontWeight weight = FontWeight.NORMAL ;
if (labelDescription.getLabelStyling() == LabelStyling.BOLD) {
weight = FontWeight.BOLD ;
}
if (labelDescription.getLabelStyling() == LabelStyling.ITALIC) {
posture = FontPosture.ITALIC ;
}
if (labelDescription.getTextSize() != null) {
size = labelDescription.getTextSize();
}
lbl.setFont(Font.font(family, weight, posture, size));
Если вы действительно хотите использовать CSS, вы можете либо создать стиль с помощью конкатенации строк, либо для веса шрифта и стиля использовать внешнюю таблицу стилей и пользовательские псевдоклассы CSS.
Например.:
label-style.css
:
/*
Note that you have to use a font which supports
bold, italic, and bold-italic on the system.
*/
#my-label {
-fx-font-family: "Arial" ;
}
#my-label:important {
-fx-font-weight: bold ;
}
#my-label:emphasized {
-fx-font-style: italic ;
}
Я обычно предпочитаю этот подход, поскольку он упрощает программное изменение стилей в ответ на изменения состояния в приложении логическим образом. Для цветов вы можете использовать «просмотренные цвета». Единственным недостатком является то, что я не знаю способа изменить размеры шрифта, поэтому их все равно нужно выполнять с помощью встроенных стилей.
Вот полный пример использования этого, который устанавливает псевдоклассы в соответствии с пользовательским вводом:
import javafx.application.Application;
import javafx.css.PseudoClass;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class LabelStyleTest extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
VBox root = new VBox(5);
root.setAlignment(Pos.CENTER);
CheckBox important = new CheckBox("Important");
CheckBox emphasized = new CheckBox("Emphasized");
Spinner<Integer> size = new Spinner<>(4, 36, 12);
HBox sizeBox = new HBox(2, new Label("Size:"), size);
sizeBox.setAlignment(Pos.CENTER);
Label label = new Label("A label");
label.setId("my-label");
PseudoClass importantPC = PseudoClass.getPseudoClass("important");
PseudoClass emphasizedPC = PseudoClass.getPseudoClass("emphasized");
important.selectedProperty().addListener((obs, wasSelected, isNowSelected) ->
label.pseudoClassStateChanged(importantPC, isNowSelected));
emphasized.selectedProperty().addListener((obs, wasSelected, isNowSelected) ->
label.pseudoClassStateChanged(emphasizedPC, isNowSelected));
size.valueProperty().addListener((obs, oldSize, newSize) ->
label.setStyle("-fx-font-size: " newSize " px;"));
root.getChildren().addAll(important, emphasized, sizeBox, label);
Scene scene = new Scene(root, 800, 500);
scene.getStylesheets().add("label-style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
}
В вашем примере вы бы сделали что-то вроде:
Label lbl = new Label(labelDescription.getLabelText());
lbl.setId("my-label");
PseudoClass importantPC = PseudoClass.getPseudoClass("important");
PseudoClass emphasizedPC = PseudoClass.getPseudoClass("emphasized");
lbl.pseudoClassStateChanged(importantPC,
labelDescription.getLabelStyling() == LabelStyling.BOLD));
lbl.pseudoClassStateChanged(emphasizedPC,
labelDescription.getLabelStyling() == LabelStyling.ITALIC);
if (labelDescription.getTextSize() != null) {
lbl.setStyle("-fx-font-size: " labelDescription.getTextSize() "px;");
}