i try to build a Calculator in JavaFX and i want to dynamicly change the Font size when a certain amount of numbers are on the display,so that it will fit.
This works as i want it to when i set the Text Alignment to the Left.
But this does infact not work when i use any Text Alignment on the right side,it buggs out.
To be more specific, look at the following pictures:
This is the size default at startup:
http://www7.pic-upload.de/19.02.14/8xjsfv1awtl1.jpg
Then i change the font size:
http://www7.pic-upload.de/19.02.14/9518liqv4ebw.jpg
You can see the alignment is broken....
But the funny part is when you click into the Textfield it will fix itself and will look like this:(no Link because of reputation limitation crap)
www7.pic-upload.de/19.02.14/5e3ddqyt575o.jpg
Is there a workaround? Here are some examples of my code:
GUI.fxml
<TextField fx:id="display" alignment="BASELINE_RIGHT" cache="false" editable="false" layoutX="18.0" layoutY="17.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onKeyPressed="#keylistener" prefHeight="54.0" prefWidth="206.0" promptText="" styleClass="textcustom, rand, backgroundfield" text="" />
Application.css
.background {
-fx-background-color: #4682B4;
}
.backgroundfield {
-fx-background-color: #F5F5F5;
}
.button {
-fx-background-color: #FFF5EE;
}
.textcustom{
-fx-font: 26px "Serif";
}
.rand{
-fx-border-style: solid;
-fx-border-color: black ;
-fx-border-width: 1px;
}
The Java Code to change the Font:
display.setStyle("-fx-font: 18px Serif;");
It seems to be a bug. The workaround can be to use javafx.scene.control.Label instead of TextField.
Related
I have a container that needs to display two custom components scaled down by 25% aligning them vertically.
I'm using a VBox loaded from this FXML:
<fx:root type="VBox" fx:id="leaderDisplay" xmlns="https://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="MyController"
prefHeight="720.0" prefWidth="200.0" alignment="CENTER">
</fx:root>
And the component is loaded from this FXML:
<fx:root stylesheets="#css/style.css" type="StackPane"
maxHeight="294.0" maxWidth="195.0"
fx:controller="MyOtherController"
xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
<AnchorPane fx:id="cardPane" styleClass="leader-card" prefHeight="294.0" prefWidth="195.0">
<FlowPane fx:id="lcRequirements" layoutX="13.0" layoutY="10.0" />
<Label fx:id="lcVictoryPoints" layoutX="87.0" layoutY="162.0" prefHeight="25.0" prefWidth="20.0" text="0" />
</AnchorPane>
<Pane fx:id="cardBack" styleClass="leader-card-back" maxHeight="294.0" maxWidth="195.0" visible="false" />
</fx:root>
I add the needed components programmatically with this method in the VBox controller:
private void addLeader(LeaderCard newLeader) {
Platform.runLater(() -> {
setStyle("-fx-background-color: grey;");
LeaderCardWidget newWidget = new LeaderCardWidget(newLeader);
System.out.println("Height before: " + newWidget.getMaxHeight());
newWidget.setStyle("-fx-border-color: black;" +
"-fx-border-width: 3");
newWidget.setScaleX(0.75);
newWidget.setScaleY(0.75);
System.out.println("Height after: " + newWidget.getMaxHeight());
leaderDisplay.getChildren().add(newWidget);
leadersAndWidgets.put(newLeader, newWidget);
});
}
The problem is that the components are being scaled down, but the vbox does not display them properly, leaving huge spacing around them (to the right is the same screenshot without scaling for reference):
From the "Visual Bounds versus Layout Bounds" section of the layout documentation:
Node provides the layoutBounds property to define the 'logical'
bounds of the node for layout and boundsInParent to define the visual
bounds once all effects, clipping, and transforms have been applied.
... if a ScaleTransition is used to pulse the size of a button,
that pulse animation will not disturb layout around that button. If an
application wishes to have the effect, clip, or transform factored
into the layout of a node, it should wrap that node in a Group.
In short, transforms, such as scaling, are not factored into the layout calculations of the parent. You can make that happen by wrapping your components in a group. I think you can achieve this in your code with
// leaderDisplay.getChildren().add(newWidget);
leaderDisplay.getChildren().add(new Group(newWidget));
I have a button in JavaFx stylized with CSS, but without "button:hover" clause. The text alignment in css is set to right, but sometimes apears aligned to left. When I put mouse over button, the text alignment change from left to right and I don't have nothing in CSS about onMouseOver (or that I think ). I don't know if is a bug.
CSS:
.button{
-fx-font-size: 1em;
-fx-padding: 0 0 -30 0;
}
.menu, .label{
-fx-font-size: 0.8em;
}
...
#btPlusLargo{
-fx-background-color: transparent;
-fx-background-image: url('../resources/plus.png');
-fx-text-alignment: right;
-fx-background-repeat: no-repeat;
-fx-background-position: left center;
-fx-padding: 0 0 0 0;
}
...
In FXML
<Button id="btPlusLargo" fx:id="btEntregaTodo" layoutX="773.0" layoutY="532.0"
mnemonicParsing="false" onAction="#onClickAgregaTodo" prefHeight="25.0"
prefWidth="150.0" stylesheets="#botones.css" text="%bt.AgregaTodo"
textAlignment="RIGHT" AnchorPane.bottomAnchor="104.0"
AnchorPane.rightAnchor="9.0" />
Without mouse over
With mouse over (It would always have to be like that.)
Edit:
Ok, I see that it depends on the TableView above the button. If I select the Table View, I have the problem, but when I click out of TableView, it's show ok.
Edit2: It shows badly when I click on any other FXML field
Example:
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="HomeController">
<children>
<VBox fx:id="vBoxParent" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity">
<children>
<MenuBar fx:id="menubar" prefHeight="30.0" prefWidth="800.0">
...
With this code, the stage opens fullsize, but the menubar isn´t covering all the lenght. What do I have to add?
If you want the MenuBar to take the full size of VBox, you can replace VBox with MenuBar, placing MenuBar directly in AnchorPane, and giving Anchor Pane Constraints to the MenuBar (to be responsive).
If you want to keep VBox for some reason, you can change the MenuBar properties:
set Vgrow to: allways (allways increase the vertical length)
set Max Width to: MAX_VALUE
I recommend you to use SceneBuilder, to easily find functions and preview changes.
This CSS code changes the text color of the whole text of a MenuItem:
.context-menu .label {
-fx-text-fill: blue;
}
The thing is that I only want to change the Accelerator display text.
The CSS reference of JavaFX was not very helpful: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html#contextmenu
So how can you set the style of the Accelerator display text in a ContextMenu using CSS?
I inspected the skin and found out the accelerator-text class is assigned to the Label that displays the accelerator, which means you can use
.context-menu .accelerator-text {
-fx-text-fill: blue;
}
to style the Label displaying the accelerator.
I just gave a menuItem an id
fxml:
<MenuItem id="menuItem" mnemonicParsing="false" text="Close" accelerator="Shortcut+C"/>
and tried:
css:
#menuItem>Label {
-fx-background-color: #0093ff;
-fx-text-fill: #ffff00;
}
and it worked.
I have a plain CheckBox in an FXML file on the same line as some other controls and labels in a HBox.
The checkBox label text-base is about 6px units lower than ALL the other text and labels on the same line (HBox).
I can manually line things up in SceneBuilder by specifying a padding-bottom value of: 6. I wanted to put that into the CSS so all checkbox labels would be "lined-up", but everthing I've tried is ignored and doesn't show in the CSS Analyzer (too).
I looked through the Checbox default styling as pointed out here:
Styling a checkbox and also:
Checkbox in the UI controls
I had similar issues with ListBox where the control is constructed from a number of components. You have to know which 'thing' is relevant. However, looking through: com/sun/javafx/scene/control/skin/
caspian/caspian.css
I can't pick the component that makes the text label lower than other text on the same line/row. Add to that, the fact that specifying the padding in the SceneBuilder designer layout, will fix the issue on a one-by-one (manual) basis, it just seems strange that it won't work for:
.check-box {
padding-bottom: 6px; /* or just 6 */
}
Does not work on the following FXML mark-up.
<HBox alignment="CENTER_LEFT" >
<children>
<CheckBox fx:id="acknowledged" alignment="TOP_LEFT" styleClass="normal" text="00">
<padding>
<Insets bottom="6.0" left="4.0" right="8.0" />
</padding>
</CheckBox>
<Button fx:id="detailButton" text="%alarm.detail.label" />
<Label fx:id="alarmType" styleClass="normal" text="%alarm.type.value">
<padding>
<Insets left="8.0" right="8.0" />
</padding>
</Label>
</children>
</HBox>
The objective is to define the padding-bottom via CSS rather than have to do it manually in the FXML:
<padding>
<Insets bottom="6.0" left="4.0" right="8.0" />
</padding>
Any ideas?
To be clear, the visual result for this row is that the checkbox itself has a base-line smaller/lower than the other elements (button, label). The CheckBox label is also subsequently "below" the other elements. If we can pad using CSS, then we don't need to manually maintain the layouts.
As a general rule, alignment problems should be solved by the layout (vs. tweaking paddings or such). So first stop to a solution could be the doc of the parent pane, here HBox:
The alignment of the content is controlled by the alignment property,
which defaults to Pos.TOP_LEFT.
That might be consistent with what you are be seeing (can't be 100% certain, though, as you forgot to include a runnable example ;-) If all other components on the line are accidentally being same height or filling the box with the checkbox smaller, it will positioned at the top of the pane.
Assumed solution is to change the pane's alignment to BASELINE_XX, quick check in code works fine for me:
private Parent getContent() {
HBox box = new HBox(new TextField("something"),
new CheckBox("soso"), new Button("hello"));
box.setAlignment(Pos.BASELINE_CENTER);
return box;
}