【问题标题】:How to modify MenuButton arrow color by JavaFX not FXML CSS?如何通过 JavaFX 而不是 FXML CSS 修改 MenuButton 箭头颜色?
【发布时间】:2014-03-10 11:47:34
【问题描述】:

我正在尝试使用JavaFX 代码而不是CSS 修改MenuButton 箭头的颜色。

我在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";
}

我尝试使用类似的东西:

menubutton.lookup(".arrow");

但它会抛出NullPointerException

当我这样做时:

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

仅输出:menu-button only。

那么任何人都可以给我使用Java而不使用CSS来修改它的方法吗??

【问题讨论】:

  • 你试过用“.arrow”查找吗?
  • 大声笑,对不起,我已经试过了,是的,但是没有用
  • 您什么时候进行查找?仅在应用 css 后查找才会起作用,这通常是在显示菜单之后。
  • 如果语句menubutton.lookup("arrow") 抛出 NullPointerException 意味着menubuttonnull。可能是您在加载 FXML 并初始化内容之前 执行此代码。你能显示更多的代码,特别是调用这一行的地方吗?
  • @Jason4Ever, @James_D:我注意到lookup() 如果调用 after primaryStage.show()(即来自 James_D 的答案)确实会返回正确的内容,但确实如此如果之前调用过,则返回 null

标签: java javafx javafx-2 javafx-8 fxml


【解决方案1】:

这行得通:

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

更新:但这是一个更好的解决方案(如果夏令时没有影响我的睡眠,我可能会第一次得到它;))。

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

【讨论】:

    【解决方案2】:

    有几种方法可以做到这一点,这里有四种。代码是带有 JavaFX 的 Jython。您可以编辑此代码以满足您的需要。


    首先是枚举,用于上下文。

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

    第二,css文件,用于上下文。

    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

    /*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");
    }
    

    方法,在我的主文件中。

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

    不要通过 CSS 配置组合框箭头,而是以编程方式进行并更改区域 SVG 形状

    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)
    

    通过 CSS 配置组合框箭头并更改区域 SVG 形状

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

    通过 CSS 配置组合框箭头,但只是通过设置透明度/不透明度值并设置背景来隐藏箭头。

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

    不要通过 CSS 配置 ComboBox 箭头,而是以编程方式进行,仅通过设置透明度/不透明度值并设置背景来隐藏箭头。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-20
      • 2015-09-08
      • 2015-05-28
      • 1970-01-01
      • 2020-10-08
      相关资源
      最近更新 更多