Scrollbar doesn't appear when scrolling - javafx

I'm using HiddenSidesPane to show and hide scrollbar when needed. Scrollbar appears when I move mouse to the edge of the ScrollPane and hides when I move back. However, I have a problem to show scrollbar when the scrolling is detected. You can find my code below:
FXML:
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.VBox?>
<?import org.controlsfx.control.HiddenSidesPane?>
<?import java.net.URL?>
<ScrollPane xmlns:fx="http://javafx.com/fxml"
fx:controller="hypermap.components.featurespanel.view.properties.PropertiesTab" fx:id="propertyTabRoot"
fitToWidth="true" hbarPolicy="NEVER" vbarPolicy="NEVER">
<stylesheets>
<URL value="#Scrollbar.css"/>
</stylesheets>
<HiddenSidesPane fx:id="hiddenSidesPane" minWidth="280">
<content>
<VBox fx:id="vboxInsideScroll">
<VBox fx:id="groupsContainer"/>
<VBox fx:id="messageContainer"/>
</VBox>
</content>
</HiddenSidesPane>
</ScrollPane>
CSS file:
.scroll-pane{
-fx-focus-color: none;
-fx-background-color: transparent;
}
.scroll-bar > .increment-button, .decrement-button, .increment-arrow, .decrement-arrow{
-fx-pref-height: 0;
}
.scroll-bar:vertical{
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-pref-width: 10;
-fx-padding: 0;
}
.scroll-bar:vertical .thumb{
-fx-background-color: color-dark-slate;
-fx-border-radius: 100;
-fx-padding: 0 4 0 0;
-fx-opacity: 0.2
}
.scroll-bar:vertical .track{
-fx-background-color: transparent;
}
Controller file with method using HiddenSidesPane:
#FXML
private VBox groupsContainer;
#FXML
private VBox messageContainer;
#FXML
private ScrollPane propertyTabRoot;
#FXML
private HiddenSidesPane hiddenSidesPane;
private void makeScrollable(ScrollPane scrollPane) {
final Node scrollbar = scrollPane.lookup(".scroll-bar:vertical");
hiddenSidesPane.setRight(scrollbar);
hiddenSidesPane.setTriggerDistance(40);
hiddenSidesPane.setAnimationDuration(Duration.millis(500));
scrollPane.setOnScroll((event -> {
hiddenSidesPane.setRight(scrollbar);
event.consume();
}));
I would be very grateful for any help. Also, I don't know why the scrollbar's thumb has the same hight all the time, even if the content is so huge that it should be smaller.
Thank you!

Related

how tp set the different font fill text color for selected label in a JFXListView?

I've create a JFXListView in th FXML file :
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<JFXListView fx:id="listName" layoutX="-1.0" layoutY="-5.0" />
</children>
</AnchorPane>
and injected in controller
#FXML
private JFXListView<Label> listName;
then I fill the JFXListView with labels
public void loadListAdsTarget(){
listName.setVerticalGap(7.0);
for (int i = 0; i < 4; i++) {
listName.getItems().add(new Label("name " +i+ " desc : text text text"));
}
listName.getStyleClass().add("mylistview");
listName.depthProperty().set(1);
listName.setExpanded(true);
}
I tried to change the color of the selected label by css, but I did not get a good result by changing the text to white.
.mylistview .label {
-fx-text-fill: #a0a2ab;
}
.mylistview:selected .label:selected {
-fx-text-fill: red;
}
.mylistview:focused .label:selected {
-fx-text-fill: while;
}
.mylistview .list-cell:selected {
-fx-background-color: #2196f3;
}
.mylistview .list-cell {
-fx-background-color: #282d40;
}
Add this section of css to your file and it will change the selected text color
.mylistview .list-cell:selected .label{
-fx-text-fill: rgb(20, 20, 20);
}
You can also remove this section
.mylistview:focused .label:selected {
-fx-text-fill: while;
}

javafx root -fx-font-size and em sizing

I'm trying to resize my layout elements using a root font-size and 'em' values. It looks like whenever I "touch" the -fx-font-size attribute, the root's font size is being reset to the base value (1em = 12px).
For the simple fxml:
<BorderPane fx:id="mainStack" prefWidth="600" prefHeight="400" stylesheets="/style.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<left>
<VBox fx:id="leftPane">
<Button text="btn1"></Button>
<Button text="btn2" styleClass="textBigger"></Button>
<Button text="btn3"></Button>
</VBox>
</left>
</BorderPane>
and css like:
.root {
-fx-font-size: 10px;
-fx-background-color: Lime;
}
#leftPane {
/*-fx-font-size: 10px;*/
-fx-background-color: Green;
-fx-pref-width: 40em;
-fx-spacing: 1em;
}
.button {
-fx-background-color: Yellow;
-fx-pref-height: 5em;
-fx-pref-width: 20em;
}
#leftPane .textBigger {
-fx-font-size: 1.5em;
}
sample 1 is for root -fx-font-size = 10
sample 2 is for root -fx-font-size = 20
Button 1 and 3 as well as overall layout are as expected, but on button 2 pref-width and pref-height are being seized as multiplication of 12 instead of 10 or 20. So button 2 size is always 240x60.
Am I doing something wrong here? Does someone know a solution on how to prevent root -fx-font-size "reset"?
Yes, it is the BUG by the the javafx.scene.CssStyleHelper, look at the the code-line 1388:
boolean isFontProperty = "-fx-font".equals(property) || "-fx-font-size".equals(property);
then 1392:
boolean isRelative = ParsedValueImpl.containsFontRelativeSize(resolved, isFontProperty);
and 1444:
// did we get a fontValue from the preceding block?
// if not, get it from our cacheEntry or choose the default
if (fontForFontRelativeSizes == null) {
if (fontFromCacheEntry != null && fontFromCacheEntry.isRelative() == false) {
fontForFontRelativeSizes = (Font)fontFromCacheEntry.getValue();
} else {
fontForFontRelativeSizes = Font.getDefault();
}
}
It must be fixed under the https://bugreport.java.com/bugreport/submit_start.do, ID: 9055560.
As a workaround - to define -fx-font-size: XXXem; not in a .control-class, but deeply, for example in the .text-class, in your case:
#leftPane .textBigger .text {
-fx-font-size: 1.5em;
}
Then the -fx-font-size: 2em; belongs only to the .text-class and doesn’t influence on the higher .textBigger-class.

CSS and JavaFX - CSS in a TableView

I want to apply css in all of my upper side of the tableview, the following photo show the part I want to apply the css (The part at the side of the column "Estado")
enter image description here
here's my css:
.table-view{
-fx-background-color: transparent;
}
.table-view:focused{
-fx-background-color: transparent;
}
.table-view .column-header-background{
-fx-background-color: linear-gradient(#101010 0%, #424141 100%);
}
.table-view .column-header-background .label{
-fx-background-color: transparent;
-fx-text-fill: white;
}
.table-view .column-header {
-fx-background-color: transparent;
}
.table-view .table-cell{
-fx-text-fill: white;
}
.table-row-cell{
-fx-background-color: -fx-table-cell-border-color, #616161;
-fx-background-insets: 0, 0 0 1 0;
-fx-padding: 0.0em;
}
.table-row-cell:odd{
-fx-background-color: -fx-table-cell-border-color, #424242;
-fx-background-insets: 0, 0 0 1 0;
-fx-padding: 0.0em;
}
.table-row-cell:selected {
-fx-background-color: #005797;
-fx-background-insets: 0;
-fx-background-radius: 1;
}
The part is white because it isn't a column of my tableview, so I want to know how to apply CSS in empty parts (without columns) in the table.
FXML code:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<HBox prefHeight="300.0" prefWidth="773.0"
stylesheets="/iftorrent/gui/menuPrincipal/MenuPrincipalCSS.css"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="iftorrent.gui.menuPrincipal.MenuPrincipalControlador">
<children>
<TableView fx:id="tabela" prefWidth="773.0">
<columns>
<TableColumn fx:id="numero" prefWidth="35.0" text="Nº " />
<TableColumn fx:id="nome" prefWidth="183.0" text="Nome" />
<TableColumn fx:id="tamanho" prefWidth="76.0" text="Tamanho" />
<TableColumn fx:id="velocidade" prefWidth="76.0" text="Velocidade" />
<TableColumn fx:id="tempo_estimado" prefWidth="120.0" text="Tempo Estimado" />
<TableColumn fx:id="estado" prefWidth="283.0" text="Estado" />
<TableColumn fx:id="progresso" prefWidth="283.0" text="Progresso" />
</columns>
</TableView>
</children>
</HBox>
You are looking for the .filler inside the .column-header-background. Add this rule:
.table-view .column-header-background .filler {
-fx-background-color: linear-gradient(#101010 0%, #424141 100%);
}
For reference, you can use the JavaFX CSS Reference, or use the CSS Analyzer tool built into SceneBuilder.

JavaFx2 OutOfMemoryError:Java heap space

I creat a simple JavaFx application with FXML and CSS in order to change UI Theme at runtime.
There are three Button and one Label in the scene. I define different CSS for Label and "-fx-background-image"(PNG format, size 1.23M) for BorderPane in the CSS file.
Application can switch UI Theme by click "Style" Button.
But Mem usage will raise and don't free when I click one of "Style" Button. Application will OutOfMemoryError after switch Theme about 30 times. I don't know how to fix it.Someone can help me?
java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:75)
at java.awt.image.Raster.createPackedRaster(Raster.java:467)
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1032)
at java.awt.image.BufferedImage.<init>(BufferedImage.java:359)
at com.sun.prism.j2d.J2DTexture.<init>(J2DTexture.java:46)
at com.sun.prism.j2d.J2DResourceFactory.createTexture(J2DResourceFactory.java:72)
at com.sun.prism.impl.BaseResourceFactory.createTexture(BaseResourceFactory.java:127)
My environment: jdk1.7.0_51, Windows Server 2003 x86, 3G RAM
I am sorry that I don't know how to post IMG file(background.png) to forum.
Click "AutoSwitch" Button for auto Switching Theme.
Source Code:
Main.Java
public class Main extends Application {
private Stage primaryStage;
public Stage getPrimaryStage() {
return primaryStage;
}
public void setPrimaryStage(Stage primaryStage) {
this.primaryStage = primaryStage;
}
private BorderPane rootPane;
public BorderPane getRootPane() {
return rootPane;
}
#Override
public void start(Stage primaryStage) {
try {
setPrimaryStage(primaryStage);
URL url = new URL(getClass().getResource("AppFrame.fxml").toExternalForm());
FXMLLoader loader =new FXMLLoader(url);
rootPane = (BorderPane)loader.load();
Scene scene = new Scene(rootPane,400,400);
primaryStage.setScene(scene);
//MAX screen
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
primaryStage.setX(bounds.getMinX());
primaryStage.setY(bounds.getMinY());
primaryStage.setWidth(bounds.getWidth());
primaryStage.setHeight(bounds.getHeight());
primaryStage.show();
AppFrameController appFrameController = (AppFrameController)loader.getController();
appFrameController.setAppMain(this);
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
AppFrameController.java
public class AppFrameController {
private String style1Url = getClass().getResource("FxStyle1.css").toExternalForm();
private String style2Url = getClass().getResource("FxStyle2.css").toExternalForm();
#FXML private Label lblSceneTitle;
private Main appMain;
public Main getAppMain() {
return appMain;
}
public void setAppMain(Main appMain) {
this.appMain = appMain;
}
private int switchCount=0;
public AppFrameController()
{
}
public void handleClickStyle1()
{
ObservableList<String> stylesheets = getAppMain().getRootPane().getStylesheets();
stylesheets.remove(style2Url);
if(!stylesheets.contains(style1Url))
{
stylesheets.add(style1Url);
}
}
public void handleClickStyle2()
{
ObservableList<String> stylesheets = getAppMain().getRootPane().getStylesheets();
stylesheets.remove(style1Url);
if(!stylesheets.contains(style2Url))
{
stylesheets.add(style2Url);
}
}
public void handleClickSwitch()
{
SwitchCssTask handleTask = new SwitchCssTask();
new Thread(handleTask).start();
}
private class SwitchCssTask implements Runnable {
#Override
public void run() {
while (true) {
if (switchCount % 2 == 0) {
handleClickStyle1();
} else {
handleClickStyle2();
}
switchCount++;
System.out.println("Switch count=" + switchCount);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
AppFrame.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane prefHeight="362.0" prefWidth="749.3739013671875" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="application.AppFrameController">
<!-- TODO Add Nodes -->
<center>
<BorderPane id="center-pane" prefHeight="-1.0" prefWidth="-1.0" BorderPane.alignment="CENTER">
<center>
<VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" spacing="20.0">
<children>
<Button mnemonicParsing="false" onAction="#handleClickStyle1" prefHeight="70.0" prefWidth="148.0" text="Style1" />
<Button mnemonicParsing="false" onAction="#handleClickStyle2" prefHeight="70.0" prefWidth="148.0" text="Style2" />
<Button mnemonicParsing="false" onAction="#handleClickSwitch" prefHeight="70.0" prefWidth="148.0" text="AutoSwitch" />
</children>
</VBox>
</center>
</BorderPane>
</center>
<stylesheets>
<URL value="#FxStyle2.css" />
</stylesheets>
<top>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="10.0" BorderPane.alignment="CENTER">
<children>
<Label id="scene-title" fx:id="lblSceneTitle" alignment="TOP_CENTER" prefWidth="371.0" text="Test FxStyle" />
</children>
<padding>
<Insets bottom="15.0" left="12.0" right="12.0" top="15.0" />
</padding>
</HBox>
</top>
</BorderPane>
FxStyle1.css
#center-pane {
-fx-background-image: url("background.png");
}
#scene-title {
-fx-font-family: "Tahoma";
-fx-background-insets: 0;
-fx-text-fill: green;
-fx-font-weight: bold;
-fx-font-size: 4em;
-fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.9) , 1, 0.0 , 0 , 1 );
}
FxStyle2.css
#center-pane {
-fx-background-image: url("background.png");
}
#scene-title {
-fx-font-family: "Courier New";
-fx-background-insets: 0;
-fx-text-fill: red;
-fx-font-weight: bold;
-fx-font-size: 4em;
-fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.9) , 1, 0.0 , 0 , 1 );
}
I get answer from Oracle Communtiy.
please see here.

Using both CSS and setStyle

I have an object where I have css stylizing the object. In my program I would like to change specific elements in the styling such as background color. The problem that I have run into was that when I call setStyle(-fx-background-color:red) it will override all the styling elements. Even if I just change background color.
#header {
-fx-background-color: #4d4d4d;
-fx-border-color: #545454;
-fx-border-width: 1px;
-fx-border-style: solid;
}
#header:hover {
-fx-background-color: #9ACD32;
}
You should define your colors in your CSS using "looked up colors".
See the JavaFX CSS reference for details.
Looked-up Colors
With looked-up colors you can refer to any other color property that is set on the current node or any of its parents. This is a very powerful feature, as it allows a generic palette of colors to be specified on the scene then used thoughout the application. If you want to change one of those palette colors you can do so at any level in the scene tree and it will affect that node and all its decendents. Looked-up colors are not looked up until they are applied, so they are live and react to any style changes that might occur, such as replacing a palette color at runtime with the "style" property on a node.
In the following example, all background color of all buttons uses the looked up color "abc".
.root { abc: #f00 }
.button { -fx-background-color: abc }
Sample Application
In the sample application, the key code is the setting of the looked up color value dynamically in code:
headerColorToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
#Override
public void changed(
ObservableValue<? extends Toggle> observableValue,
Toggle oldToggle,
Toggle newToggle
) {
RadioButton radio = (RadioButton) newToggle;
header.setStyle("header-base-color: " + radio.getText());
}
});
Together with the definition of the header-base-color lookup id for the color in the css below:
header-color.css
.root {
header-base-color: #4d4d4d;
}
#header {
-fx-background-color: header-base-color;
-fx-border-color: #545454;
-fx-border-width: 1px;
-fx-border-style: solid;
}
#header:hover {
-fx-background-color: #9ACD32;
}
header-color.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?scenebuilder-stylesheet header-color.css?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import java.net.URL?>
<BorderPane id="BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="HeaderColorController">
<top>
<HBox fx:id="header" prefHeight="-1.0" prefWidth="-1.0">
<children>
<Label text="A really hard to read label" />
</children>
</HBox>
</top>
<center>
<VBox prefHeight="-1.0" prefWidth="-1.0" spacing="10.0" style="-fx-background-color: azure;">
<children>
<RadioButton mnemonicParsing="false" style="-fx-text-fill: forestgreen;" text="forestgreen">
<toggleGroup>
<ToggleGroup fx:id="headerColorToggleGroup" />
</toggleGroup>
</RadioButton>
<RadioButton mnemonicParsing="false" style="-fx-text-fill: firebrick;" text="firebrick" toggleGroup="$headerColorToggleGroup" />
<RadioButton mnemonicParsing="false" selected="true" style="-fx-text-fill: #4d4d4d;" text="#4d4d4d" toggleGroup="$headerColorToggleGroup" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</VBox>
</center>
<stylesheets>
<URL value="#header-color.css" />
</stylesheets>
</BorderPane>
HeaderColorApp.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HeaderColorApp extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("header-color.fxml"));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) { launch(args); }
}
HeaderColorController.java
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.*;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
public class HeaderColorController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private HBox header;
#FXML
private ToggleGroup headerColorToggleGroup;
#FXML
void initialize() {
assert header != null : "fx:id=\"header\" was not injected: check your FXML file 'header-color.fxml'.";
assert headerColorToggleGroup != null : "fx:id=\"headerColorToggleGroup\" was not injected: check your FXML file 'header-color.fxml'.";
headerColorToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
#Override
public void changed(ObservableValue<? extends Toggle> observableValue, Toggle oldToggle, Toggle newToggle) {
RadioButton radio = (RadioButton) newToggle;
header.setStyle("header-base-color: " + radio.getText());
}
});
}
}

Resources