Проблема с применением CSS для программно созданной панели на MouseEvent - PullRequest
0 голосов
/ 06 июня 2018

У меня есть панель стека, которая при входе мыши создает панель, вставляет в нее текст и отображает ее рядом с мышью.

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

Как вы можете видеть ниже, когда панель и текст появляются, когда я переворачиваю панель стека (черный круг и вопросительный знак на изображении).

enter image description here

Однако у него нет синего фона, который я ищу.

То, что я нахожу странным, это то, что вместо добавления его в корневой каталог и добавления его к существующему Vbox стиль корректно отображается (здесь я переворачиваю ту же панель стека):

enter image description here

Итак:

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

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

Некоторые вещи, на которые стоит обратить внимание:

1) getInfoBox () - статический метод получения.У меня есть несколько контроллеров, которые расширяют MasterController, который имеет статические переменные экземпляра, для вещей, к которым все контроллеры хотели бы иметь доступ - например, для infoBox, для отображения информации.

2) Корнем является BorderPane, созданный в Mainкласс:

Main.java

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

3) Все файлы css объявлены в файлах .fxml с помощью Scene Builder.Все верхние, нижние, левые и правые файлы .fxml имеют одинаковые css (main.css).То же относится и к stat.fxml, который загружается по нажатию кнопки в центр (вы можете видеть на изображении)

Предложение: может быть потому, что CSS не определен для самой сцены или BorderPane, он применяется толькок узлам, добавленным в разделы borderPane?Если да, то как бы мне позволить разрешить входной сцене / сцене использовать один и тот же css, и это сведет на нет добавление в css к каждому .fxml?

Edit:

При добавлении этого кода вГлавное, чтобы применить CSS к сцене:

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

Я получаю это:

enter image description here

Итак, CSS для текстасейчас работает, но не для панели?Я понятия не имею, почему это может произойти.

// ---- ВОСПРОИЗВОДСТВО - //

Main.java

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

RightController.java пример пакета;

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

    }
}

left.fxml

<?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>

center.fxml

<?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>

right.fxml

<?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>

main.css

.blueBG {
    -fx-background-color: aqua;
}

Вы должны получить следующий результат.Вы можете видеть, что панель правильно оформляется при добавлении справа, но не при добавлении слишком корня.

enter image description here

1 Ответ

0 голосов
/ 06 июня 2018

BorderPane применяет макет только к дочерним элементам center, left, right, top и bottom.Однако это родитель макета (или сцены в случае корня), который устанавливает размер Region во время прохода макета (или нет, как в этом случае).

В результате получается, чтостиль применяется к Pane, но размер Pane остается 0.В этом можно убедиться, добавив

pane1.resize(100, 100);

в обработчик событий, чтобы установить размер панели.

Вам необходимо использовать другой тип макета в качестве родительского для pane1.размер, чтобы стать непустым или изменить его размер самостоятельно.

...