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.
Related
This is my situation:
I have a web app that allow users to change the UI size. (i.e. small, medium or large button)
Users can change how it looks like dynamically during runtime. All text and form input boxes will be resized.
My project is in Vue.js.
What is the best way to solve this? Loading different css when user click?
Load different CSS while user click the button similar to this . Codepen : https://codepen.io/anon/pen/NJEoVM
HTML
<div id="app" :class="size">
<div class="text">Text</div>
<input class="ipt"/><br/><br/>
<button class="btn" #click="change('small')">Small</button>
<button class="btn" #click="change('medium')">Medium</button>
<button class="btn" #click="change('large')">Large</button>
</div>
CSS
.small .ipt{
width: 100px;
height:30px;
}
.small .text{
font-size: 18px;
}
.medium .ipt{
width: 300px;
height:50px;
}
.medium .text{
font-size: 32px;
}
.large .ipt{
width: 600px;
height:100px;
}
.large .text{
font-size: 64px;
}
Javascript
new Vue({
el: '#app',
data:()=>({
size:'small'
}),
methods:{
change(val){
this.size = val
}
}
});
Actually, you can make use of Custom Properties aka CSS variables.
Firstly, define the button CSS styles
/* button.css */
#buttonRef {
--fontSize: 16px;
font-size: var(--fontSize)
}
The overall flow would be something like the following one e.g
methods: {
changeButtonSize: function(size, event) {
event.preventDefault();
/* size might be either of 's', 'm', 'l' */
/* let the button ref is stored in refs */
const buttonRef = this.$refs[“buttonRef”];
let fontSize = 16;
switch(size) {
case 's':
fontSize = 12;
case 'm':
fontSize = 18;
case 'l':
fontSize = 22;
}
/* dynamically change the value for custom property */
buttonRef.style.setProperty("--fontSize", fontSize);
}
}
you can set up 3 classes:
.small {font-size:12px}
.medium {font-size:18px}
.large {font-size:24px}
Then add or remove them to your main parent div onClick.
If you have discreetly set the font-size on the elements, you'll have to target those elements as such:
.small .description { font-size:12px }
.small .title{ font-size:16px }
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;
}
I am currently facing a problem with javafx table. I have a tableview that shows a list of subjects. The background color of each row depends if a subject is able to be enrolled or not. Subjects with green background can be enrolled and subjects with pink background cannot be enrolled. The problem occurs when scrolling the table.
TableView before scrolling
TableView after scrolling down and up
After scrolling, the background color of rows have changed and the subjects with green background might become pink and vice versa. This works perfectly without adding a css to the table.
Code I used to set the background color of rows
tblAvailableSubjects.setRowFactory((TableView<Subject> param) -> {
TableRow<Subject> row = new TableRow<>();
row.emptyProperty().addListener((obs, wasEmpty, isEmpty) -> {
if(isEmpty) {
row.setContextMenu(null);
row.setStyle("-fx-border-color: transparent");
} else {
Subject subject = row.getItem();
if(subject.getSubjectEvaluation().equals(SubjectEvaluation.COMPLETED)) {
row.setStyle("-fx-background: #B2EBF2");
} else if(subject.getSubjectEvaluation().equals(SubjectEvaluation.FAILED)) {
row.setStyle("-fx-background: #FF0000");
row.setContextMenu(tblAvailableContext);
} else if(subject.getSubjectEvaluation().equals(SubjectEvaluation.OKAY)) {
row.setStyle("-fx-background: #8BC34A");
row.setContextMenu(tblAvailableContext);
} else if(subject.getSubjectEvaluation().equals(SubjectEvaluation.ENROLLWITHCOREQ)) {
row.setStyle("-fx-background: #FFEB3B");
row.setContextMenu(tblAvailableContext);
} else if(subject.getSubjectEvaluation().equals(SubjectEvaluation.CANTENROLL)) {
row.setStyle("-fx-background: #FFCDD2");
}
}
});
return row;
});
CSS for table
.table-view {
/* Constants used throughout the tableview. */
-fx-table-header-border-color: transparent;
-fx-table-cell-border-color: -fx-box-border;
/* Horizontal Lines*/
-fx-background-color: transparent;
}
.table-view .filler, .table-view .column-header
{
-fx-size: 40;
-fx-border-style: null;
-fx-border-color: rgb(200.0, 200.0, 200.0);
-fx-border-width: 0 0 1 0;
-fx-background-color: transparent;
}
.table-view .show-hide-columns-button
{
-fx-background-color: transparent;
}
.table-view .column-header .label,
.table-view .column-drag-header .label
{
-fx-alignment: CENTER_LEFT;
}
.table-view .column-header-background
{
-fx-background-color: transparent;
}
.table-row-cell {
-fx-cell-size: 30px;
}
.table-cell {
-fx-border-color: transparent;
-fx-border-width: 1;
}
EDIT: The subject's SubjectEvaluation value doesn't change, it seems that it switches the context menu and background color between rows when scrolling.
I hope someone could help me with this. Thanks.
Consider this switch:
<Switch class="switch" formControlName="answer"></Switch>
If I do this it only works when you haven't activated the switch yet, after that the background-color will always be the same even when the switch is not active:
.switch[checked=true] {
background-color: #FE4A49;
color: #FE4A49;
}
And if I do this:
.switch {
background-color: #FE4A49;
color: #FE4A49;
}
Then the background will always be the same regardless of the state.
What's the correct way of styling a switch when using it with angular's model bindings?
i'm styling an App and this is i'd do.
CSS:
Switch#userStatus[checked=true]{
color:#ff0048 ;
background-color: white;
transform: scale(1.25, 1.25); // This is for change the size when checked
transform: translate(-5,0); // This is for stay the position after scale it
}
Switch#userStatus[checked=false]{
color: gray;
background-color: gray;
}
And this is my XML:
`<Switch id="userStatus" checked="false" />`
I hope this helps!
I had an issue with switch
background-color
and it was not working as expected. Changing the background-color was changing the whole switch (the gray part). So I had to change only the color property:
Switch[checked=true] {
color: #f68533;
}
.switch-notchecked {
background-color: #FE4A49;
color: yellow;
}
.switch-checked {
background-color: blue;
color: green;
}
In your template
<Switch #sw checked="false" (checkedChange)="switchChanged(sw.checked)" [class]="isChecked?'switch-checked':'switch-notchecked'"></Switch>
In your component
isChecked:boolean;
switchChanged(checked) {
this.isChecked = checked;
}
I want to change the background colour of a custom TreeCell using CSS, but setting the style property on the tree cell doesn't work. I can style the tree with alternate yellow and grey cells with a CSS file that looks like this:
.tree-cell:disabled {
-fx-padding: 3 3 3 3;
-fx-background-color: white;
}
.tree-cell:selected {
-fx-background-color: blue;
}
.tree-cell:even {
-fx-background-color: yellow;
}
.tree-cell:odd {
-fx-background-color: grey;
}
.tree-cell:drag-over {
-fx-background-color: plum;
}
and change the fill style of the text with an event handler that looks like this:
onDragEntered = (event: DragEvent) => {
val db = event.getDragboard
if (db.hasContent(customFormat)) {
textFill = Color.DEEPSKYBLUE
style() = "tree-cell:drag-over"
}
event.consume()
}
but the style of the tree cells doesn't change.
I eventually found the answer to my own question. The CSS file now looks like this:
.tree-cell:disabled {
-fx-padding: 3 3 3 3;
-fx-background-color: white;
}
.tree-cell:selected {
-fx-background-color: blue;
}
.tree-cell:filled:even {
-fx-background-color: lightyellow;
}
.tree-cell:filled:odd {
-fx-background-color: lightsteelblue;
}
.tree-cell.drag-over:filled {
-fx-background-color: plum;
}
I now get a plum colour when dragging over a filled cell. Empty cells stay white.
In order to get here I needed to understand the rules of "CSS specificity", although it was eventually possible to simplify the finished CSS file to make each case exactly match one selector.
The ScalaFX code now looks like this:
import scala.collection.JavaConversions._
// Copy the list, so that it isn't modified in place.
var oldStyleClass: util.Collection[String] = styleClass.toList
onDragEntered = (event: DragEvent) => {
val db = event.getDragboard
if (db.hasContent(customFormat)) {
textFill = Color.DEEPSKYBLUE
// Remember the original style by taking a copy.
oldStyleClass = styleClass.toList
// Restyle filled cells with .tree-cell.dragover:filled
// for the duration of the drag
styleClass.add("drag-over")
}
event.consume()
}
onDragExited = (event: DragEvent) => {
val db = event.getDragboard
if (db.hasContent(customFormat)) {
textFill = Color.BLACK
}
// Restore the original style.
styleClass.setAll(oldStyleClass)
event.consume()
}
Somewhere along the way I lost the animation for a failed drop. Otherwise I'm happy (but somewhat lonely in ScalaFX-land.)