简体   繁体   English

如何通过JavaFX而不是FXML CSS修改MenuButton箭头颜色?

[英]How to modify MenuButton arrow color by JavaFX not FXML CSS?

i am trying to modify color of MenuButton arrow , using JavaFX code not by CSS . 我试图使用JavaFX代码而不是CSS来修改MenuButton箭头的颜色。

i found it inside caspian.css : 我在caspian.css找到它:

.menu-button > .arrow-button > .arrow {
    -fx-background-insets: 1 0 -1 0, 0;
    -fx-background-color: -fx-mark-highlight-color, -fx-mark-color;
    -fx-padding: 0.25em; /* 3 */
    -fx-shape: "M 0 -3.5 v 7 l 4 -3.5 z";
}

i tried to use something like that : 我试图使用类似的东西:

menubutton.lookup(".arrow");

but it throw NullPointerException 但它抛出NullPointerException

and when i do that : 当我这样做时:

System.out.println(this.getStyleClass().toString());

it out put that only: menu-button only. 它仅显示:仅menu-button

so can any one give me the way to modify it using Java without using CSS ?? 所以任何人都可以给我一种无需使用CSS即可使用Java对其进行修改的方法吗?

This works: 这有效:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class RedMenuButton extends Application {

    @Override
    public void start(Stage primaryStage) {
        final StackPane root = new StackPane();
        final MenuButton menuButton = new MenuButton("Menu");
        menuButton.getItems().addAll(new MenuItem("Item 1"), new MenuItem("Item 2"), new MenuItem("Item 3"));
        root.getChildren().add(menuButton);

        final Scene scene = new Scene(root, 250, 150);
        primaryStage.setScene(scene);
        primaryStage.show();

        menuButton.lookup(".arrow").setStyle("-fx-background-color: red;");
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Update: But this is a better solution (which I probably would have got first time if daylight savings hadn't messed with my sleep ;)). 更新:但这是一个更好的解决方案(如果不节省夏令时,我可能会是第一次;)。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class RedMenuButton extends Application {

    @Override
    public void start(Stage primaryStage) {
        final StackPane root = new StackPane();
        final MenuButton menuButton = new MenuButton("Menu");
        menuButton.getItems().addAll(new MenuItem("Item 1"), new MenuItem("Item 2"), new MenuItem("Item 3"));
        root.getChildren().add(menuButton);

        menuButton.setStyle("-fx-mark-color: red");

        final Scene scene = new Scene(root, 250, 150);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

There are several ways to do this, here are four. 有几种方法可以做到这一点,这里有四种。 The code is Jython with JavaFX. 代码是带有JavaFX的Jython。 You can edit this code to meet your needs. 您可以编辑此代码以满足您的需求。


First, the enum, for context. 首先,枚举,用于上下文。

public enum URLBarArrowConstants {
     //URLBarArrow Constants
     BYCSS_AND_SHAPE,
     BYCSS_AND_NO_SHAPE,
     NOCSS_AND_SHAPE,
     NOCSS_AND_NO_SHAPE;
}

Second, the css files, for context. 其次,css文件,用于上下文。

EG #1 EG#1

/*ComboBox's Arrow is a Region.*/
.combo-box .arrow-button .arrow {
     -fx-shape: "...";
     -fx-scale-shape: true;
     -fx-position-shape: true;
}

EG#2 EG#2

/*ComboBox's Arrow is a Region.*/
.combo-box .arrow-button .arrow {
    /*Setting either of these two will do.*/
     -fx-background-color: transparent; 
     -fx-opacity: 0.0;  
}

/*ComboBox's Arrow Button is a Stack Pane.*/
.combo-box .arrow-button{
    -fx-background-position: center;
    -fx-background-repeat: no-repeat;
    -fx-background-image: url("..<file>.png");
}

The method, in my main file. 该方法在我的主文件中。

def setCustomURLBarArrow(self, url_bar, scene, URLBarArrowConstant):
    from javafx.scene.paint import Paint
    from javafx.scene.shape import Shape, SVGPath, FillRule

Don't configure the ComboBox Arrow by CSS, instead, do it programmatically and change the Regions SVG Shape 不要通过CSS配置ComboBox Arrow,而是以编程方式进行操作并更改Regions SVG Shape

if URLBarArrowConstant == URLBarArrowConstants.NOCSS_AND_SHAPE:

    #SVG Object
    previous_url_bar = SVGPath()

    #SVG Path
    previous_url_bar.setContent("...") # edit this 

    #SVG Fill Rule
    previous_url_bar.setFillRule(FillRule.NON_ZERO)

    #Set Fill -- 
    previous_url_bar.setFill(Paint.valueOf(Color.web("...").toString())) //edit here

    #Apply CSS Sheet
    url_bar.applyCss()

    #Set Region's Shape
    arrow_region = url_bar.lookup(".arrow").setShape(previous_url_bar)

Configure the ComboBox Arrow by CSS and change the Regions SVG Shape 通过CSS配置组合框箭头并更改Region SVG Shape

elif URLBarArrowConstant == URLBarArrowConstants.BYCSS_AND_SHAPE:
    #Apply Stylesheet for URL Bar
    scene.getStylesheets().add(File("..<file>.css").toURI().toString()) //edit here

Configure the ComboBox Arrow by CSS but instead, merely hide the arrow by setting the transparency/opacity values and set a background. 通过CSS配置ComboBox箭头,但只能通过设置透明度/不透明度值并设置背景来隐藏箭头。

elif URLBarArrowConstant == URLBarArrowConstants.BYCSS_AND_NO_SHAPE:
    #Apply Stylesheet for URL Bar
    scene.getStylesheets().add(File("..<file>.css").toURI().toString()) //edit here

Don't configure the ComboBox Arrow by CSS, instead, do it programmatically and merely hide the arrow by setting the transparency/opacity values and set a background. 不要通过CSS配置ComboBox Arrow,而是以编程方式进行操作,而只需通过设置透明度/不透明度值并设置背景来隐藏箭头即可。

elif URLBarArrowConstant == URLBarArrowConstants.NOCSS_AND_NO_SHAPE:

    from javafx.scene.paint import Paint
    from javafx.scene.layout import CornerRadii
    from javafx.scene.layout import Background, BackgroundSize, BackgroundImage, BackgroundPosition, BackgroundRepeat, BackgroundFill

    #Apply CSS Sheet
    url_bar.applyCss()

    #Grab Arrow(Region), ArrowButton(StackPane) ComboBox properties
    arrow_region = url_bar.lookup(".arrow")
    arrow_button = url_bar.lookup(".arrow-button")

    #Either Set Opacity to 0 or set background color to transparent.
    arrow_region.setOpacity(0.0)
    arrow_region.setBackground( Background( array(BackgroundFill, [BackgroundFill( Paint.valueOf(Color.TRANSPARENT.toString()), CornerRadii.EMPTY, Insets.EMPTY)]) ) )

    #Set a Background Image for the .arrow-button StackPane.
    arrow_button.setBackground(Background( array(BackgroundImage, [BackgroundImage( Image( String(File('..<file>.png').toURI().toString()), True) , BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, BackgroundSize.DEFAULT)] ) ) )       //if you want, edit this

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM