Java Fx – 在不覆盖的情况下以编程方式为标签添加样式

huangapple go评论89阅读模式
英文:

Java Fx - Adding Styles to label programattically without overwriting

问题

我想根据条件向标签添加样式。当我尝试这样做时,它会覆盖先前的样式。有没有更好的方法来连接这些样式?

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;");
}
英文:

I want to add styles to a label depending on conditions. When i try this, it overwrites the previous style. Is there a better way to concat the styles ?

    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

得分: 4

我认为对于你的情况,重新调整一下样式逻辑可能会更容易,就像这样:

Label lbl = new Label(labelDescription.getLabelText());

StringBuilder style = new StringBuilder();
if (labelDescription.getLabelStyling() == LabelStyling.BOLD) {
    style.append("-fx-font-weight: bold;");
}

if (labelDescription.getLabelStyling() == LabelStyling.ITALIC) {
    style.append("-fx-font-style: italic;");
}

if (labelDescription.getTextSize() != null) {
    style.append("-fx-font-size: ").append(labelDescription.getTextSize()).append("px;");
}

lbl.setStyle(style.toString());

尽管如果设置了超过这3个值,这可能会相当低效,你应该考虑使用StringBuilder

希望对你有所帮助!

英文:

I think it could be easier for your case to refactor a little the styling logic, like this:

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);

Although this could be pretty inefficient if more than these 3 values are set, you should consider using StringBuilder

Hope it helped!

答案2

得分: 3

注意,您可以在程序中进行字体设置,而无需使用CSS:

Label lbl = new Label(labelDescription.getLabelText());

// 获取默认值:
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

/*
请注意,您必须使用系统支持粗体、斜体和粗斜体的字体。
*/

#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.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;");
}
英文:

Note you can just set the font programmatically, without using CSS at all:

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));

If you really want to use CSS, you can either build the style via string concatenation, or for the font weight and style use an external style sheet and custom CSS pseudoclasses.

E.g.:

label-style.css:

<!-- language: lang-css -->

/*
Note that you have to use a font which supports
bold, italic, and bold-italic on the system.
*/
#my-label {
-fx-font-family: &quot;Arial&quot; ;
}
#my-label:important {
-fx-font-weight: bold ;
}
#my-label:emphasized {
-fx-font-style: italic ;
}

I generally prefer this approach, as it makes it easier to programmatically change styles in responses to changes in state in the application in a logical way. For colors you can use "looked-up colors". The only downside is that I know of no way to change font sizes, so those still need to be done via inline styles.

Here's a complete example using this, which sets the pseudoclasses according to user input:

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(&quot;Important&quot;);
CheckBox emphasized = new CheckBox(&quot;Emphasized&quot;);
Spinner&lt;Integer&gt; size = new Spinner&lt;&gt;(4, 36, 12);
HBox sizeBox = new HBox(2, new Label(&quot;Size:&quot;), size);
sizeBox.setAlignment(Pos.CENTER);
Label label = new Label(&quot;A label&quot;);
label.setId(&quot;my-label&quot;);
PseudoClass importantPC = PseudoClass.getPseudoClass(&quot;important&quot;);
PseudoClass emphasizedPC = PseudoClass.getPseudoClass(&quot;emphasized&quot;);
important.selectedProperty().addListener((obs, wasSelected, isNowSelected) -&gt; 
label.pseudoClassStateChanged(importantPC, isNowSelected));
emphasized.selectedProperty().addListener((obs, wasSelected, isNowSelected) -&gt; 
label.pseudoClassStateChanged(emphasizedPC, isNowSelected));
size.valueProperty().addListener((obs, oldSize, newSize) -&gt; 
label.setStyle(&quot;-fx-font-size: &quot;+newSize+&quot; px;&quot;));
root.getChildren().addAll(important, emphasized, sizeBox, label);
Scene scene = new Scene(root, 800, 500);
scene.getStylesheets().add(&quot;label-style.css&quot;);
primaryStage.setScene(scene);
primaryStage.show();
}
}

In your sample you would do something like:

Label lbl = new Label(labelDescription.getLabelText());
lbl.setId(&quot;my-label&quot;);
PseudoClass importantPC = PseudoClass.getPseudoClass(&quot;important&quot;);
PseudoClass emphasizedPC = PseudoClass.getPseudoClass(&quot;emphasized&quot;);
lbl.pseudoClassStateChanged(importantPC, 
labelDescription.getLabelStyling() == LabelStyling.BOLD));
lbl.pseudoClassStateChanged(emphasizedPC, 
labelDescription.getLabelStyling() == LabelStyling.ITALIC);
if (labelDescription.getTextSize() != null) {
lbl.setStyle(&quot;-fx-font-size: &quot; + labelDescription.getTextSize() + &quot;px;&quot;);
}

huangapple
  • 本文由 发表于 2020年8月26日 20:29:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63597707.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定