当前位置: 首页 > 知识库问答 >
问题:

将CSS应用于MouseEvent上以编程方式创建的窗格时出现问题

汪晨
2023-03-14

我有一个堆栈窗格,当鼠标进入时,我创建一个窗格,在其中粘贴一些文本,并在鼠标附近显示它。

StatisticsController.java

 stackPane.setOnMouseEntered(event -> {
            Pane pane = new Pane();
            Text text = new Text("Example Text");

            //Add the text to the pane and set it near the mouse
            pane.getChildren().add(text);
            pane.setLayoutY(event.getSceneY() - 50);
            pane.setLayoutX(event.getSceneX() - 100);

            //add the  style class to give it a blueBG background
            pane.getStyleClass().add("blueBG");

            // add it too our root
            getRoot().getChildren().add(pane);
});

如下所示,当我在stackPane(图像中的黑色圆圈和问号)上滚动时,当窗格和文本出现时。

所以:

 //Styles Correctly
 getInfoBox().getChildren().add(pane);

// Adds but does not style
getRoot().getChildren().add(pane);

一些可能值得注意的事情:

1)getInfoBox()是一个静态的getter。我有多个控制器,它们将具有静态实例变量的MasterController扩展到所有控制器都希望能够访问的东西--比如infoBox,以显示信息。

//Create the root
BorderPane root = new BorderPane();

// I've cut it out to save space but this repeats 4 times to set 
//an .fxml file for the top, left, right and bottom of the borderPane ///
FXMLLoader headerLoader = new FXMLLoader(getClass().getResource("/view/header.fxml"));
Parent headerRoot = headerLoader.load();
root.setTop(headerRoot);
//------------------------------------------//

//Set the static reference in the MasterController
MasterController.setRoot(root);

Scene scene = new Scene(root,1366,768);
primaryStage.setScene(scene);
primaryStage.show();

建议:这可能是因为CSS不是为场景或BorderPane本身定义的,它只适用于添加到BorderPane部分中的节点吗?如果是这样,我该如何让进入场景/舞台使用相同的css,这是否会否定向每个.fxml添加css?

编辑:

将此代码添加到main以将CSS应用到场景时:

Scene scene = new Scene(root,1366,768);
        scene.getStylesheets().add(getClass().getResource("/css/main.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();

package sample;

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

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        BorderPane bp = new BorderPane();

        MasterController.setRoot(bp);

        Parent left = FXMLLoader.load(getClass().getResource("left.fxml"));
        Parent right = FXMLLoader.load(getClass().getResource("right.fxml"));

        bp.setLeft(left);
        bp.setRight(right);

        Scene scene = new Scene(bp, 600, 400);
        scene.getStylesheets().add(getClass().getResource("main.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
    }


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

masterController.java

package sample;

import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;

public class MasterController {

    private static VBox rightBox;
    private static BorderPane root;

    public static VBox getRightBox() {
        return rightBox;
    }

    public static void setRightBox(VBox rightBox) {
        MasterController.rightBox = rightBox;
    }

    public static BorderPane getRoot() {
        return root;
    }

    public static void setRoot(BorderPane root) {
        MasterController.root = root;
    }
}

leftController.java

package sample;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;

import java.io.IOException;

public class LeftController extends MasterController {

    @FXML
    public void loadCenter(ActionEvent event) {
        try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("center.fxml"));
                Parent center = loader.load();
            getRoot().setCenter(center);
        } catch (IOException e){
            e.printStackTrace();
        }
    }
}

CenterController.java

package sample;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;

public class CenterController extends MasterController {

@FXML
private VBox center;
    public void initialize() {
        Platform.runLater(this::build);

    }

    public void build() {
        center.getChildren().add(new Text("loaded"));

        StackPane stackPane = new StackPane();
        Text text = new Text("ROLL OVER");

        stackPane.getChildren().add(text);
        center.getChildren().add(stackPane);

        stackPane.setOnMouseEntered(event -> {
            getRightBox().getChildren().clear();

            Pane pane1 = new Pane();
            Text exampleText1 = new Text("Example Text");
            pane1.getStyleClass().add("blueBG");

            Pane pane2 = new Pane();
            Text exampleText2 = new Text("Example Text");
            pane2.getStyleClass().add("blueBG");

            pane1.getChildren().add(exampleText1);
            pane2.getChildren().add(exampleText2);

            pane1.setLayoutY(event.getSceneY() + 40);
            pane1.setLayoutX(event.getSceneX() - 40);

            getRoot().getChildren().add(pane1);
            getRightBox().getChildren().add(pane2);
        });
    }
}
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.layout.VBox;

public class RightController extends MasterController {

@FXML
private VBox rightBox;

    public void initialize() {
        setRightBox(rightBox);

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

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

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.LeftController">
   <children>
      <Button mnemonicParsing="false" onAction="#loadCenter" prefHeight="38.0" prefWidth="200.0" text="Click me to load center" />
   </children>
</VBox>
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.scene.layout.*?>

<VBox fx:id="center" alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="200.0" stylesheets="@main.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.CenterController">
   <children>
      <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Center" />
   </children>
</VBox>
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.scene.layout.*?>

<VBox fx:id="rightBox" alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="200.0" stylesheets="@main.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.RightController">
   <children>
      <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Right Box" />
   </children>
</VBox>
.blueBG {
    -fx-background-color: aqua;
}

您应该得到以下结果。当添加到右侧时,可以看到窗格的样式正确,但当添加到根时,则无法看到该窗格的样式正确。

共有1个答案

史英飙
2023-03-14

BorderPane仅将布局应用于中心子级。但是,布局的父级(如果是根级,则是场景)在布局传递期间设置区域的大小(或者不设置,如本例所示)。

结果是将样式应用于窗格,但窗格的大小仍保持0。您可以通过添加

pane1.resize(100, 100);

设置窗格的大小。

 类似资料:
  • 我试图创建一个从扩展而来的自定义视图,并在代码中应用样式,这样我就不需要在xml中这样做。 风格是: 一切正常,但property。由于某种原因,背景色并没有改变,它有主题的原色。但是,如果我尝试将样式应用于xml中的,它确实会改变颜色。 你知道为什么会这样,或者我怎样才能做到吗?

  • 问题内容: 我有一个与自定义关联的(用于显示弹出窗口等)。我需要开枪的机会。我应该如何以编程方式做到这一点? 问题答案: 您可以创建自己的MouseEvent并遍历所有侦听器并进行调用。 例如:

  • 我正在尝试使用GLFW创建一个窗口。窗口已创建,但经过几次尝试,创建窗口需要很长时间。 https://drive.google.com/file/d/1zq4IEjcSIJxy5wnXWLrGe46ptHMbKM5R/view?usp=sharing 我找不到任何解决办法,也不知道这是由什么引起的。 这是我正在使用的代码: 程序输出为 所以看起来初始化glfw需要很长时间,但我不知道如何修复它。

  • 问题内容: 我一直在尝试以编程方式重做我的应用程序上的工作。(不使用情节提要) 除了手动制作导航控制器外,我几乎完成了。 我一直在做一些研究,但找不到任何手动实现此方法的文档。(我开始将应用程序制作为单视图应用程序) 目前,我只有1个ViewController。当然是appDelegate 导航控制器将在应用程序的所有页面中使用。 如果有人可以帮助我,或发送指向一些适当文档的链接以编程方式进行此

  • 问题内容: 我知道我可以使用Java中的 api 以编程方式创建文件,如下所示: 但是是否有任何 API 可以构建树?(例如Dom之类的api) 我需要这样的东西: 和: 提前致谢。 问题答案: 由于XSLT也是XML,因此您可以简单地使用相同的策略: 等等… 但这不是很优雅。您应该改用库或框架,但应该很容易找到一个谷歌浏览器。

  • 我有一个WS,它返回非常基本的产品数据:代码、价格和图像。我需要用这些基本数据以编程方式创建Hybris产品,然后进行同步,以便在店面上看到这些产品。 创建具有这些基本信息的产品的步骤是什么?有OOTB服务吗?