I have this deck in a Firefox sidebar (XUL):
<deck id="mydeck" selectedIndex="0">
<vbox id="myscreen1">
...
</vbox>
<vbox id="myscreen2">
<vbox flex="3" minheight="150">
...
</vbox>
<splitter collapse="after" resizeafter="farthest">
<grippy height="10" align="end" />
</splitter>
<vbox flex="1" minheight="125">
...
</vbox>
</vbox>
</deck>
I'm trying to get #myscreen2 to take up the whole sidebar vertically. How do I achieve this?
Right now it only uses the minimum height set for the two boxes. I've tried to set height: 100% and flex="1" on the deck itself and #myscreen2, but it's not working.
I really don't like the available XUL documentation, but I managed to come up with a solution:
<deck id="mydeck" selectedIndex="0" flex="1">
<vbox id="myscreen1">
...
</vbox>
<vbox id="myscreen2">
<vbox flex="3" minheight="150">
...
</vbox>
<splitter collapse="after" resizeafter="farthest">
<grippy height="10" align="end" />
</splitter>
<vbox flex="1" minheight="125">
...
</vbox>
</vbox>
</deck>
The key was to have flex="1" on the deck. Not sure why it wasn't working when I tried it the first time.
Related
I have created my view for a JavaFX project using FXML. I was wondering if it's possible to add a few more items to the view pragmatically in controller class?
For example, how can I add another set of Text and TextField in my controller file?
FXML
<AnchorPane prefHeight="400.0" prefWidth="228.0">
<children>
<Text layoutY="10.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Selected User:" GridPane.rowIndex="0" />
<Text layoutY="45.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Username :" GridPane.rowIndex="1" />
<TextField fx:id="username" layoutY="55.0" GridPane.rowIndex="2" />
<Text layoutY="100.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Address :" GridPane.rowIndex="3" />
<TextField fx:id="address" layoutY="110.0" GridPane.rowIndex="4" />
<Text layoutY="155.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Web Page :" GridPane.rowIndex="5" />
<TextField fx:id="WP" layoutY="165.0" GridPane.rowIndex="6" />
<Text layoutY="210.0" strokeType="OUTSIDE" strokeWidth="0.0" text="State :" GridPane.rowIndex="7" />
<Text layoutY="265.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Login Name :" GridPane.rowIndex="9" />
<TextField fx:id="login_Name" layoutY="275.0" GridPane.rowIndex="10" />
<Button fx:id="btnSave" layoutX="50.0" layoutY="320.0" mnemonicParsing="false" onAction="#btnSaveClicked" text="Save" />
<Button fx:id="btnSave" layoutX="35.0" layoutY="365.0" mnemonicParsing="false" onAction="#btnDeleteUserClicked" text="Delete User" />
<Button fx:id="btnAddNew" layoutX="30.0" layoutY="410.0" mnemonicParsing="false" onAction="#btnAddeNewClicked" text="Add New User" />
<TextField fx:id="state" layoutX="-2.0" layoutY="222.0" />
</children>
</AnchorPane>
Adding New Nodes in FXML
I would say, you should always add new nodes to the FXML unless you have a very good reason not to. Adding nodes to FXML is as easy as adding an extra line to the existing FXML.
<AnchorPane prefHeight="400.0" prefWidth="228.0">
<children>
...
<Text fx:id="newText"/>
<TextField fx:id="newTextField"/>
</children>
</AnchorPane>
These new nodes will be reflected in the scene graph instantaneously and you can bind them to the controller using their fx:id's.
Adding New Nodes in Controller
First, you should have a fx:id defined for the AnchorPane in order to access it in the controller.
<AnchorPane fx:id="anchorPane" prefHeight="400.0" prefWidth="228.0">
<children>
...
</children>
</AnchorPane>
You can then define the new controls and add them the to AnchorPane in the controller.
public class MyController implements Initializable {
#FXML
private AnchorPane anchorPane;
...
public void intialize() {
...
Text newText = new Text("Some Text");
TextField newTextField = new TextField();
anchorPane.getChildren().addAll(newText, newTextField);
...
}
}
I am very perplexed with the XUL's 'Box Model' layout.
I want to make a table-like layout of elements.
The layout should consist of one row and three columns.
The columns should have the same width and occupy the whole width of the page.
I will put different elements inside the columns, but the width of the columns should remain the same
and the elements should have their normal sizes, not stretched out.
Say, first column is empty, second contains an image, third contains a button.
How can I achieve that?
I tried boxes and grids, but the columns just seem to assume arbitrary width.
Thank you.
This does not work:
<grid>
<columns flex="1">
<column/>
<column/>
<column/>
</columns>
<rows>
<row>
<spacer flex="1"/>
<image src="MyImage.png"/>
<button id="MyButton" label="MyButton"/>
</row>
</rows>
</grid>
Specify the min and max width of each column and make each cell in the grid an hbox width specific widths and heights. Something like this:
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="yourwindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:h="http://www.w3.org/1999/xhtml">
<grid>
<columns flex="1">
<column maxwidth="100" minwidth="100"/>
<column maxwidth="100" minwidth="100"/>
<column maxwidth="100" minwidth="100"/>
</columns>
<rows>
<row>
<hbox maxwidth="100">
xxxx xxxxxxxx xxxx xxxxx xxxxxxxx xxxxxxxx
</hbox>
<hbox maxwidth="100" minwidth="100" maxheight="10">
<button id="MyButton1" label="MyButton1"/>
</hbox>
<hbox maxwidth="100" minwidth="100" maxheight="30">
<button id="MyButton1" label="MyButton2"/>
</hbox>
<hbox maxwidth="100" minwidth="100" maxheight="40">
<button id="MyButton3" label="MyButton3"/>
</hbox>
</row>
</rows>
</grid>
</window>
In Xul, the width and length attributes are always in pixels. You cannot specify a percentage like you can with css. This means you will have to know your page width in advance and specify widths accordingly if you want the columns to be evenly spaced and extend to the page width.
Here's another way. Use this:
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="yourwindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml" xmlns:h="http://www.w3.org/1999/xhtml">
<grid>
<columns>
<column flex="1"/>
<column flex="1"/>
<column flex="1"/>
</columns>
<rows>
<row>
<button label="MyButton1"/>
<button label="MyButton2"/>
<button label="MyButton3"/>
</row>
</rows>
</grid>
</window>
to create this:
The buttons/columns will adjust as the window size is changed.
I suggest to use in combo with flex="1" on the column elements
<columns equalsize="always">
<column flex="1">
...
a/p documentation
https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Attribute/equalsize
you can also use equalsize="always" on the rows as well, this is how it is accomplished in the Thunderbird Lightning calendar layout
I have placed a few image views to the scene, all pointing to the same image with different
viewports.
generated fxml:
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ImageView fitHeight="150.0" fitWidth="200.0" layoutX="80.0" layoutY="91.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../../Pictures/sas.png" />
</image>
<viewport>
<Rectangle2D height="50.0" minY="50.0" width="50.0" />
</viewport>
</ImageView>
<ImageView fitHeight="150.0" fitWidth="200.0" layoutX="308.0" layoutY="91.0" pickOnBounds="true" preserveRatio="true">
<viewport>
<Rectangle2D height="50.0" minX="50.0" minY="50.0" width="50.0" />
</viewport>
<image>
<Image url="#../../../../../Pictures/sas.png" />
</image>
</ImageView>
<ImageView layoutX="225.0" layoutY="250.0">
<image>
<Image url="#../../../../../Pictures/sas.png" />
</image>
</ImageView>
</children>
Question is, will this create 3 instances of the same image in memory?
If yes, then what is the best ways to avoid it, url("") in style attribute, css class? I would like to avoid creating css class for each individual icon!
Is it even worth using single large croped image for multiple icons & UI elements instead of small image for each at this day & age?
A quick test shows that the ImageViews do not reference the same Image in memory.
To do so, you can either used css as you described, or you can define the Image once in the FXML with an <fx:define> block and reference it via its fx:id attribute:
<fx:define>
<Image url="#../../../../../Pictures/sas.png" fx:id="sasImage" />
</fx:define>
<ImageView image="$sasImage" fitHeight="150.0" fitWidth="200.0" layoutX="80.0" layoutY="91.0" pickOnBounds="true" preserveRatio="true">
<viewport>
<Rectangle2D height="50.0" minY="50.0" width="50.0" />
</viewport>
</ImageView>
<ImageView image="$sasImage" fitHeight="150.0" fitWidth="200.0" layoutX="308.0" layoutY="91.0" pickOnBounds="true" preserveRatio="true">
<viewport>
<Rectangle2D height="50.0" minX="50.0" minY="50.0" width="50.0" />
</viewport>
</ImageView>
<ImageView image="$sasImage" layoutX="225.0" layoutY="250.0">
</ImageView>
I've generated FXML in Scene Builder:
<?xml version="1.0" encoding="UTF-8"?>
<?scenebuilder-preview-i18n-resource ../lang/ru_RU.properties?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" fx:id="mainStagePane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="UI.MainStageController">
<children>
<SplitPane dividerPositions="0.6596244131455399" focusTraversable="true" prefHeight="-1.0" prefWidth="1280.0" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="160.0">
<items>
<AnchorPane id="rootPane" fx:id="pane3d" prefHeight="930.0" prefWidth="1280.0" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<Accordion id="accordeon" fx:id="accordion" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<panes>
<TitledPane animated="true" text="%3dSceneSettings" fx:id="x2">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Slider fx:id="farClipSlider" layoutY="50.0" majorTickUnit="10.0" max="100.0" min="-100.0" minorTickCount="1" prefWidth="337.0" showTickLabels="true" showTickMarks="true" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="75.0" />
<TextField layoutY="14.0" prefWidth="55.0" AnchorPane.rightAnchor="217.0" />
<Slider fx:id="distanceSlider" blockIncrement="25.0" layoutX="14.0" layoutY="133.0" majorTickUnit="50.0" max="500.0" min="-500.0" minorTickCount="25" prefWidth="399.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" />
<VBox layoutY="364.0" prefHeight="200.0" prefWidth="100.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0">
<children>
<HBox prefHeight="-1.0" prefWidth="-1.0">
<children>
<Label text="Label" />
<TextField prefWidth="55.0" />
</children>
</HBox>
<Slider fx:id="nearClipSlider" blockIncrement="1.0" majorTickUnit="10.0" max="100.0" min="-100.0" minorTickCount="1" prefWidth="338.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="0.0" />
</children>
</VBox>
<Label layoutX="104.0" layoutY="17.0" text="Label" />
</children>
</AnchorPane>
</content>
</TitledPane>
<TitledPane animated="true" expanded="false" text="%3dModelSettings" fx:id="x1">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</TitledPane>
</panes>
</Accordion>
</children>
</AnchorPane>
</items>
</SplitPane>
<ToolBar maxHeight="30.0" minHeight="30.0" prefHeight="30.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<items>
<ProgressBar fx:id="loadProgressBar" disable="false" prefWidth="200.0" progress="0.0" visible="true" />
</items>
</ToolBar>
<TabPane prefHeight="160.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<tabs>
<Tab text="%file">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Button alignment="CENTER" graphicTextGap="4.0" mnemonicParsing="false" prefHeight="90.0" prefWidth="90.0" text="%openFile" textAlignment="CENTER" textOverrun="ELLIPSIS" underline="false" wrapText="true" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0" />
<Separator layoutX="170.0" orientation="VERTICAL" prefHeight="200.0" AnchorPane.bottomAnchor="10.0" AnchorPane.topAnchor="10.0" />
</children>
</AnchorPane>
</content>
</Tab>
<Tab text="%analysis">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Button mnemonicParsing="false" prefHeight="90.0" prefWidth="90.0" text="Button" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0" />
</children>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
But suddenly I received the following exception:
javafx.fxml.LoadException:
/D:/Projects/CastAnalytics/out/production/CastAnalytics/UI/MainStage.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2592)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2570)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2416)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3160)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3121)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3094)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3070)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3062)
at core.CastAnalytics.start(CastAnalytics.java:32)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:331)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:297)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NullPointerException
at UI.MainStageController.set(MainStageController.java:98)
at UI.MainStageController.initialize(MainStageController.java:34)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2523)
... 18 more
What does it mean and how can I fix it?
Well, you've got a null pointer at line 98 of MainStageController....
If I had to guess, I'd say that one of the #FXML variables you've defined in your Controller isn't named the same as in your FXML file, so you're getting a NPE.
You'd have to paste the relevant MainStageController.java code for anyone to know more.
Please post the offending line or SSCE if possible. I agree with jhsheets and your approach double checking the variable names against your fx:id names. I have encountered this exact error/situation myself at exactly the same place (in the initialize method trying to do some post-loading initialization) where a small typo in my fx:I'd caused an NPE. But it would be good to know what is going on in the set method where the NPE originates.
As the question explains itself i've a button like firebug and i wanted to set there a number when some events happens like firebug doeas when it detects errors on the page.
Does anyone know how to set it?
This is the code of the top button that displays a panel, so i want to set there a number when certains events happens..
<panel id="asv-panel">
<hbox align="start">
<vbox>
<hbox align="center" style="background-color:#ffffff">
<image id="asvbutton-panel-icon" width="200px" height="50px" style="margin-left:10px"/>
</hbox>
<hbox style="background-color:#fff" id="menuPanelContainer">
<html:div style="margin-top:20px;margin-left:20px;width:150px" id="menuLogginInicial">
<description value="&asbutton.Signin;"/>
<html:hr/>
<image id="asvbutton-logoface" width="50px" height="50px" style="cursor:pointer" onclick="asvbutton.login();"/>
<image id="asvbutton-logogoogle" width="47px" height="45px" style="align:left;cursor:pointer"/>
<image id="asvbutton-logotwitter" width="50px" height="50px" style="align:left;cursor:pointer"/>
</html:div>
</hbox>
</vbox>
</hbox>
</panel>
</toolbarbutton>
After thousands of pages and samples... the easiest way was creating a div and doing an appendChild to it (old school method) :D
Hope this helps someone.