如何使用CSS设置JavaFX ContextMenu的样式? [英] How do you set the style for a JavaFX ContextMenu using css?

查看:105
本文介绍了如何使用CSS设置JavaFX ContextMenu的样式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用单独的CSS文件更改ContextMenu项目的样式.我查看了caspian.css部分,发现以下定义:

I am trying to change the style of a ContextMenu item using a seperate CSS file. I looked at the caspian.css section and found the following definitions:

  • .context菜单
  • .context-menu .separator
  • .context-menu .scroll-arrow
  • .context-menu .scroll-arrow:hover
  • .context-menu:show-mnemonics .mnemonic-underline

我将这些内容完全复制到了我的css文件中,并仅更改了背景色值作为测试:

I copied those over exactly to my css file and changed just the background color values as a test:

.context-menu {
    -fx-skin: "com.sun.javafx.scene.control.skin.ContextMenuSkin";
    -fx-background-color: #006699;
    -fx-background-insets: 0, 1, 2;
    -fx-background-radius: 0 6 6 6, 0 5 5 5, 0 4 4 4;
/*    -fx-padding: 0.666667em 0.083333em 0.666667em 0.083333em;  8 1 8 1 */
    -fx-padding: 0.333333em 0.083333em 0.666667em 0.083333em; /* 4 1 8 1 */
}

.context-menu .separator {
    -fx-padding: 0.0em 0.333333em 0.0em 0.333333em; /* 0 4 0 4 */
}

.context-menu .scroll-arrow {
    -fx-padding: 0.416667em 0.416667em 0.416667em 0.416667em; /* 5 */
    -fx-background-color: #006699;
}

.context-menu .scroll-arrow:hover {
    -fx-background: -fx-accent;
    -fx-background-color: #006699;
    -fx-text-fill: -fx-selection-bar-text;
}

.context-menu:show-mnemonics .mnemonic-underline {
    -fx-stroke: -fx-text-fill;
}

这显然行不通,否则我将不在这里.无论我更改什么值,这似乎都没有效果.

This obviously does not work or I would not be here. It seems to have no effect no matter what values I change.

我打开了JavaFX Scene Builder进行查看(旁注,我将其作为最后的手段,因为我觉得它使用起来很笨拙).我在上下文菜单的css部分的可样式化的部分"下注意到了,列表CSSBridge[context-menu]似乎很奇怪.标签之类的其他内容还有Label[label].

I opened up JavaFX Scene Builder to take a look (side note I used this as a last resort, as I find it pretty clumsy to use). I noticed under the Styleable Parts of the css section for the context menu that is lists CSSBridge[context-menu] which seems odd. Other things like Label have Label[label].

有人会向我解释这里发生了什么,因为它似乎忽略了上下文菜单的css文件并使用了caspian.css中的默认值?

附加示例FXML文件,css和Java代码以运行.

Attaching sample FXML file, css and java code to run.

Sample.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>

<AnchorPane fx:id="myroot" xmlns:fx="http://javafx.com/fxml">
  <children>
    <Label text="Right click for options">
      <contextMenu>
        <ContextMenu>
          <items>
            <MenuItem text="Help" />
            <MenuItem text="Me" />
          </items>
        </ContextMenu>
      </contextMenu>
    </Label>
  </children>
  <stylesheets>
    <URL value="@contextcolor.css" />
  </stylesheets>
</AnchorPane>

contextcolor.css

.root {
  -fx-background-color: cornsilk; 
  -fx-padding: 10;
}

.context-menu {
  -fx-background-color: #006699;
  -fx-text-fill: white;
}

.menu-item .label {
  -fx-text-fill: yellow;
}

.menu-item:focused .label {
  -fx-text-fill: white;
}

Test.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Test extends Application {

    public static void main(String[] args) {
        Application.launch(Test.class, args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        System.out.println(com.sun.javafx.runtime.VersionInfo.getVersion());

        Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));

        stage.setScene(new Scene(root));
        stage.show();
    }
}

推荐答案

以下是通过css设置JavaFX上下文菜单样式的简单示例.

Here is a simple example of styling a JavaFX context menu via css.

在WinXPsp3,Jdk7u6b14ea,JavaFX 2.2b12上进行了测试.

Tested on WinXPsp3, Jdk7u6b14ea, JavaFX 2.2b12.

java应用

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;

public class ContextColor extends Application {
  public static void main(String[] args) { launch(args); }
  @Override public void start(Stage stage) {
    Label label = new Label("Right click for options");
    label.setContextMenu(new ContextMenu(new MenuItem("Help"), new MenuItem("Me")));
    Scene scene = new Scene(label);
    scene.getStylesheets().add(ContextColor.class.getResource("contextcolor.css").toExternalForm());
    stage.setScene(scene);
    stage.show();
  }
}

css样式表

/** contextcolor.css
 *   place in same folder as ContextColor.java
 *   ensure your build system copies this file to the ContextColor.class output directory on build
 */
.root {
  -fx-background-color: cornsilk; 
  -fx-padding: 10;
}

.context-menu {
  -fx-background-color: #006699;
  -fx-text-fill: white;
}

.menu-item .label {
  -fx-text-fill: yellow;
}

.menu-item:focused .label {
  -fx-text-fill: white;
}

我无法告诉您CSS样式无法按预期运行的确切原因. 一些可能的原因是:

I couldn't tell you the exact reason why your css styling did not function as you expect. Some possible reasons are:

  1. 您没有正确加载它.
  2. 您的css文件未复制到您的输出路径.
  3. 您的css文件在其他方面已损坏或在语法上不正确.
  4. 您正在使用JavaFX的早期版本,该版本无法从CSS样式化上下文菜单.

更新

看看您的问题中通过fxml加载css文件的完整代码,我可以重现未设置上下文菜单样式的问题.如果我不是在fxml中设置样式表,而是在代码中(如在我的测试应用程序中)在代码中设置了样式表 ,那么一切正常.

Looking at the complete code in your question where the css file is loaded via fxml, I can reproduce your issue where the context menu is not styled. If, instead of setting the stylesheet in the fxml, I set the stylesheet on the scene in code (as in my test app), then it all works fine.

通过fxml设置css的区别在于fxml不在场景上设置样式表,而是在场景的父根节点上设置样式表.如果在代码中我将样式表添加到父项而不是场景中,那么我最终会在代码实现中得到与fxml相同的行为.因此,这实际上并不是fxml的问题,而是JavaFX 2.2 css处理的继承规则有问题. IMO,css处理是错误的-无论是在场景上还是在场景的根节点上设置样式表,样式都应该相同.

The difference when the css is set via fxml is that the fxml is not setting the stylesheet on the scene, but instead on the parent root node of the scene. If in the code I add the stylesheet to the parent rather than the scene, then I end up with the same behaviour from the code implementation as the fxml. So this is not really an issue with fxml per se, but rather it is in issue with the inheritance rules of the JavaFX 2.2 css processing. IMO, the css processing is wrong - the styling should be the same whether the stylesheet has been set on the scene or on the root node of the scene.

我建议在 http://javafx-jira.kenai.com 上针对JavaFX运行时控件提交错误. a>包含您的测试用例以及指向该StackOverflow问题的链接,JavaFX团队将在适当的时候解决该问题.

I advise filing a bug against the JavaFX runtime controls at http://javafx-jira.kenai.com with your test case and a link back to this StackOverflow question and the JavaFX team will resolve the issue in due time.

作为一种解决方法,现在只需在代码中在场景中设置样式表即可.

As a workaround, just set your stylesheet on the scene in code for now.

更新

此问题的根本原因似乎是 RT-19435:弹出控件的样式不是父级的样式表声明.

Root cause for this issue appears to be RT-19435: popup control not styled be parent's style sheet declarations.

这篇关于如何使用CSS设置JavaFX ContextMenu的样式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆