Is that possible to display a calendar controller from scene builder? I am trying to display a calendar which ideally has to be linked to a data property and time slot. Any help?
I'm not using scene builder, but you can manually edit your fxml to add a DatePicker. I created a simple example that shows a date picker and when the date is chosen it displays it in a Text field below.
The fxml looks like:
<GridPane fx:controller="datepicker.DatePickerController" xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
<padding>
<Insets top="25" right="25" bottom="10" left="25" />
</padding>
<DatePicker fx:id="datepicker" GridPane.columnIndex="0" GridPane.rowIndex="0" onAction="#handleDatePickerAction"></DatePicker>
<Text fx:id="actiontarget" GridPane.columnIndex="0" GridPane.rowIndex="1" />
</GridPane>
And the controller looks like:
public class DatePickerController
{
#FXML
private Text actiontarget;
#FXML
private DatePicker datepicker;
#FXML
protected void handleDatePickerAction(ActionEvent event)
{
actiontarget.setText(datepicker.getValue().toString());
}
}
Related
I have a customized TableView defined in an FXML and the table works fine so far. The code is something like the followings:
<FitWidthTableView fx:id="dataDisplayView" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="300.0" prefWidth="380.0" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="rowColumn" maxWidth="50.0" prefWidth="30.0" sortable="false" style="-fx-alignment: CENTER_RIGHT;" text="Row" />
...
</FitWidthTableView>
Now, I need to add the Pagination due to a huge amount of data (from a DB). It would be great if I can wrap around the TableView tag with the Pagination tag. I find a sample with the approach as the following
<Pagination fx:id="pagination" layoutX="2.0" layoutY="188.0" prefHeight="275.0" prefWidth="912.0">
<fx:define>
<FitWidthTableView fx:id="dataDisplayView" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" prefHeight="300.0" prefWidth="380.0"
VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="rowColumn" maxWidth="50.0" prefWidth="30.0" sortable="false"
style="-fx-alignment: CENTER_RIGHT;" text="Row"/>
...
</columns>
<VBox.margin>
<Insets left="1.0" right="1.0"/>
</VBox.margin>
</FitWidthTableView>
</fx:define>
</Pagination>
while almost all examples of TableView with Pagination are done without FXML.
I, however, don't see the pagination controller code sample which shall do a few things: determine the number of pages, specify the page size, and populate data to the table. Can someone advise on the subject?
My controller is something like the followings:
public class DataViewerController implements Initializable {
#FXML
private Pagination pagination ;
#FXML
private FitWidthTableView<OutputData> dataDisplayView;
#FXML
private TableColumn<OutputData, Integer> rowColumn;
…
#Autowired
private OutputDataRepository outputDataRepository;
#Override // This method is called by the FXMLLoader when initialization is complete
#FXML
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
…
}
…
}
How to populate data with the above code structure?
As shown here, any Pagination property can be initialized in your FXML:
<Pagination pageCount="8" currentPageIndex="3" …/>
More likely, you'll derive the values based on your actual data. Your implementation of the pageFactory() should set the desired partition on the table and return a table view, as seen here.
I want to keep the TableView in the FXML.
As, #James_D comments, the TableView declaration is irrelevant to the pageFactory(). As a concrete example, start from the complete example cited here and substitute the following FXML declarations in center:
<center>
<Pagination fx:id="pager" currentPageIndex="1"/>
<fx:define>
<TableView fx:id="tableView" prefHeight="60.0">
<columns>
<TableColumn fx:id="itemName" text="Item Name" />
<TableColumn fx:id="pricePerUnit" text="Price Per Unit" />
<TableColumn fx:id="quantity" text="Quantity" />
<TableColumn fx:id="amount" text="Amount" />
</columns>
</TableView>
</fx:define>
</center>
In the controller, inject the pager and initialize() it:
#FXML
Pagination pager;
…
//tableView.setItems(objList);
pager.setPageCount(objList.size());
pager.setPageFactory((Integer pageIndex) -> createPage(pageIndex));
The following factory assigns a single row to the tableView and returns it:
public TableView<TestModel> createPage(int page) {
tableView.getItems().setAll(objList.get(page));
return tableView;
}
it is a simple calculator made by using javaFx. My problem is that i want to use the on_off button to get power and to get inactive the calculator. How to do so??? Thanks in advance.
You cannot do this using SceneBuilder alone, however it could be done by editing the fxml yourself. Just use a ToggleButton for the on/off button and bind the disable properties to the selected property of the ToggleButton or do this in the initialize method of the controller (requires all Buttons to be injected to the controller via fx:id).
binding in fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.*?>
<VBox xmlns:fx="http://javafx.com/fxml/1" spacing="10">
<padding>
<Insets left="10" right="10" bottom="10" top="10" />
</padding>
<children>
<fx:define>
<!-- create ToggleButton to be used with the disable properties -->
<ToggleButton fx:id="on" text="On"/>
</fx:define>
<!-- create buttons and bind the disable property to the negated
selected property of the on button -->
<Button text="Button 1" disable="${!on.selected}" />
<Button text="Button 2" disable="${!on.selected}" />
<Button text="Button 3" disable="${!on.selected}" />
<Button text="Button 4" disable="${!on.selected}" />
<Button text="Button 5" disable="${!on.selected}" />
<!-- add on button to scene -->
<fx:reference source="on"/>
</children>
</VBox>
binding in controller
#FXML
private Button button1;
#FXML
private Button button2;
#FXML
private Button button3;
...
#FXML
private ToggleButton on;
#FXML
private void initialize() {
BooleanBinding disable = on.selectedProperty().not();
button1.disableProperty().bind(disable);
button2.disableProperty().bind(disable);
button3.disableProperty().bind(disable);
...
}
to make this quickly i advice you to add all buttons, except for the on/off one to a container like an hbox v box or what you want, then to disable the container(parent) which contains your buttons e.g.
vBoxMain.getChildren().addAll(/*every button except on/off*/);
//or generate dynamically the buttons and add them to the vBoxMain in a for cycle
buttonOnOff.setOnAction((ActionEvent e) -> {
if(vBoxMain.isDidable()){
vBoxMain.setDisable(false);
}else{
vBoxMain.setDisable(true);
}
});
This is not for your specific layout but to give you an idea, i hope it would be helpful to you.
So here's the deal, i'm trying to code a GUI that shows live data on a linechart.
So far so good, i can get the linechart working but not into the GUI.
Using scenebuilder, i made a view with a linechart object, in order to link it to my generated chart. But for some reason this does not seem to work with this code in my mainApp.
public void showSes() {
try {
// Load the fxml file and set into the center of the main layout
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/Session.fxml"));
AnchorPane Session = (AnchorPane) loader.load();
rootLayout.setCenter(Session);
SessionController controller = loader.getController();
controller.setMainApp(this);
controller.initGraph();
} catch (IOException e) {
// Exception gets thrown if the fxml file could not be loaded
e.printStackTrace();
}
}
This simply shows the view with an empty linechart.
I know the chart should know however, because i can use it to create a scene, and show that into the GUI, but the view i made in scenebuilder also has some other fields i want to show...
Does anybody have an idea?
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.chart.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="900.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gui.view.SessionController">
<children>
<Pane prefHeight="900.0" prefWidth="1280.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<LineChart fx:id="linechart" layoutX="29.0" layoutY="194.0" prefHeight="416.0" prefWidth="1222.0" title="Temperature of session">
<xAxis>
<CategoryAxis label="Time (s)" fx:id="xAxis" />
</xAxis>
<yAxis>
<NumberAxis fx:id="yAxis" label="Temperature (°C)" side="LEFT" upperBound="160.0" />
</yAxis>
</LineChart>
<GridPane layoutX="254.0" layoutY="87.0" prefHeight="150.0" prefWidth="771.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="274.0" minWidth="10.0" prefWidth="274.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="273.0" minWidth="10.0" prefWidth="273.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="273.0" minWidth="10.0" prefWidth="273.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label prefHeight="53.0" prefWidth="153.0" text="Temperature fluid:" GridPane.halignment="CENTER" GridPane.valignment="TOP">
<font>
<Font size="16.0" />
</font>
</Label>
<Label prefHeight="52.0" prefWidth="181.0" text="Temperature vapor:" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.valignment="TOP">
<font>
<Font size="16.0" />
</font>
</Label>
<TextField fx:id="fluidT" editable="false" />
<TextField fx:id="gasT" editable="false" GridPane.columnIndex="2" />
</children>
</GridPane>
<Label layoutX="474.0" layoutY="14.0" text="TempTracker">
<font>
<Font size="50.0" />
</font>
</Label>
<TextArea editable="false" layoutX="190.0" layoutY="638.0" prefHeight="160.0" prefWidth="900.0" promptText=" ------Warning log------- " wrapText="true" />
<Button layoutX="540.0" layoutY="808.0" mnemonicParsing="false" onAction="#handleStop" prefHeight="65.0" prefWidth="200.0" text="STOP">
<font>
<Font size="22.0" />
</font>
</Button>
</children></Pane>
</children>
</AnchorPane>
CONTROLLER
private static final int MAX_DATA_POINTS = 50;
private String xSeriesData = "";
private XYChart.Series series1;
private XYChart.Series series2;
private ExecutorService executor;
private BlockingQueue<Number> dataQ1 = new ArrayBlockingQueue<Number>(1024);
private BlockingQueue<Number> dataQ2 = new ArrayBlockingQueue<Number>(1024);
#FXML
private CategoryAxis xAxis = new CategoryAxis();
#FXML
final NumberAxis yAxis = new NumberAxis();
#FXML
final LineChart<String, Number> linechart = new LineChart<String, Number>(xAxis, yAxis);
public void initGraph(){
xAxis.setAutoRanging(false);
xAxis.setTickLabelsVisible(false);
xAxis.setTickMarkVisible(false);
NumberAxis yAxis = new NumberAxis();
yAxis.setAutoRanging(true);
//Graph
final LineChart<String, Number> lc = new LineChart<String, Number>(xAxis, yAxis){
#Override
protected void dataItemAdded(Series<String, Number> series, int itemIndex, Data<String, Number> item){}
};
lc.setAnimated(false);
lc.setId("liveLineChart");
lc.setTitle("Animated Line Chart");
//Graph Series
series1 = new XYChart.Series<Number, Number>();
series2 = new XYChart.Series<Number, Number>();
linechart.getData().addAll(series1, series2);
series1.setName("T1");
series2.setName("T2");
fluidT.setText("0000");
gasT.setText("0000");
prepareTimeline();
Runnable con = new Consumer(this);
Thread c = new Thread(con);
c.start();
}
Don't create new objects for #FXML injected members
Never use new in conjunction with #FXML, i.e., never write:
#FXML
private CategoryAxis xAxis = new CategoryAxis();
Instead, just write:
#FXML
private CategoryAxis xAxis;
The FXMLLoader will automatically generate, i.e., create, a new object for each element in the FXML file and inject a reference to that into your controller where you provide an #FXML annotation. So if you reset the #FXML member reference to a new object you create in the controller there will be no association between that object and objects created by the loader.
Additionally, don't create another new LineChart within your initGraph() function. You already have a LineChart created by the FXMLLoader, just reference that. Same for NumberAxis and the other elements you are using #FXML injection with.
If you use an #FXML annotation also use <fx:id>
You have:
#FXML
private CategoryAxis xAxis;
So in your fxml, you should define:
<xAxis fx:id="xAxis">
Otherwise, the FXMLLoader will not be able to inject a reference to the axis you defined in your FXML.
Aside
You may have other errors in your code (e.g., around concurrency and threading). So the above might not be all of your errors. In general, when creating an mcve, try to eliminate anything which is not relevant to the question at hand (e.g. the threading code and non-linechart portions of the FXML), but include everything that somebody could use to copy and paste your code to compile and run it to replicate your issue.
Note: The Ensemble sample application contains a sample program which updates a graph in real-time based upon audio spectrum input data.
I'm using Accelerator in my application, and when I hit the F1 key it should open a dialog just once, but when I close the dialog it appears again. The runnable is been called twice.
Does anyone know what it could be? Is it a bug? I'm using a Macbook to develop.
This is my controller:
public class Screen1Controller {
#FXML
private TextField txtCode;
#FXML
private TableView tblProducts;
#FXML
private Button buttonAskUserDecision;
#FXML
public void initialize () {
Platform.runLater(new Runnable() {
#Override
public void run() {
initializeKeyCombinations();
}
});
}
#FXML
private void executePrint (ActionEvent event) {
System.out.println("ExecutePrint");
}
public void initializeKeyCombinations() {
buttonAskUserDecision.getScene().getAccelerators().clear();
buttonAskUserDecision.getScene().getAccelerators().put(
new KeyCodeCombination(KeyCode.F1),
new Runnable() {
#Override
public void run() {
System.out.println("Executed F1");
}
}
);
}
}
This is my FXML:
<StackPane prefHeight="600.0" prefWidth="800.0" stylesheets="#../../../css/main.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Screen1Controller">
<children>
<BorderPane prefHeight="200.0" prefWidth="200.0">
<center>
<ScrollPane fitToHeight="true" fitToWidth="true" BorderPane.alignment="CENTER">
<content>
<VBox alignment="TOP_CENTER">
<children>
<GridPane hgap="10.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="20.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="20.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="30.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="30.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints fillHeight="false" minHeight="30.0" vgrow="NEVER" />
</rowConstraints>
<children>
<TextField fx:id="txtCode" GridPane.columnSpan="2" />
</children>
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
</GridPane>
<TableView fx:id="tblProducts" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn prefWidth="75.0" text="C1" />
<TableColumn prefWidth="75.0" text="C2" />
</columns>
</TableView>
</children>
</VBox>
</content>
</ScrollPane>
</center>
<bottom>
<ToolBar maxHeight="80.0" minHeight="80.0" prefHeight="80.0" styleClass="default-skin-pdv-toolbar" stylesheets="#../../../css/main.css">
<items>
<Button fx:id="buttonAskUserDecision" layoutX="10.0" layoutY="20.0" mnemonicParsing="false" onAction="#executePrint" prefHeight="60.0" prefWidth="69.0" styleClass="default-skin-pdv-button">
</Button>
</items>
<padding>
<Insets left="10.0" />
</padding>
</ToolBar>
</bottom>
</BorderPane>
</children>
Inside this screen I have a textfield, a tableview and a toolbar with a button.
I did some new tests. Every time I give focus on my tableview and hit the F1 button, the execution is incremented by 1. For instance, if I click on the tableview and hit F1, it prints "Executed F1" just once on the console and the focus go back to the textfield, if i give focus to the tableview again and hit F1, It prints two times the text on the console and give focus back to the textfield, and if I give focus to the tableview for the third time and press the F1 again it prints three more lines on the console, and so on.
It only happens when I use the F1 button.. When I click the button with the mouse it prints only once.
I removed the TableView from the screen and it stopped duplicating the executions.
The problem is: I need this tableView in my screen. What could be happening here?
That's my Java version details:
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
The problem was in a component (Dialog) from ControlsFX library.
I created a new Project and included a textfield, viewTable and a button. The duplication didn't happened.
When I included the ControlsFX Dialog, the started to happen. When I click the button, with the mouse, the dialog opens just once. But when I use the accelerator to fire the button, the dialog opens twice.
Edited:
I created my own dialog, but it happened again. Instead of using the stage.showAndWait() I tried the stage.show() and it stopped to open twice.
I searched the stackoverflow and found this answer https://stackoverflow.com/a/22463857/916804 ... When I tried to wrap the call to the Dialog with the Platform.runLater the execution happened only once.
I have JavaFX application using FXML to build its GUI.
When this application is launched, I need to have ListView, which has some values loaded, for example, from database. So, how can I do this?
I know how to make application, which loads items to ListView after user clicks a button, or something like this ("onAction" attribute in FXML). But this does not suites me as I need items to be loaded automaticaly to the ListView.
This fills my choicebox with the five predetermined baud rates. I assume if you try to add items from your controller, the list only shows those values (untested).
<ChoiceBox fx:id="baudRates" layoutX="234.0" layoutY="72.0">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="4800" />
<String fx:value="9600" />
<String fx:value="19200" />
<String fx:value="57600" />
<String fx:value="115200" />
</FXCollections>
</items>
</ChoiceBox>
You also need to include the following import statement in your FXML:
<?import javafx.collections.*?>
If you have fxml with Controller, like next:
<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="test.Sample">
<children>
<ListView fx:id="listView"/>
</children>
</AnchorPane>
you can just implement Initializable in your Controller:
public class Sample implements Initializable {
#FXML
private ListView listView;
#Override
public void initialize(URL url, ResourceBundle rb) {
// change next line to DB load
List<String> values = Arrays.asList("one", "two", "three");
listView.setItems(FXCollections.observableList(values));
}
}