I have two controllers:
Main
which contains TableViewTab
which displays SQLITE database tables (which contain different number of columns) in tabular format, andRem
which contains a button which dictates which database to display (there are many such controllers).
Now if I create a method in Main
which is responsible for updating and displaying TableView contents, how do I use that method in other controller?
I created two static ObservableList variables columns
and rows
and bind them to Tab
in Main
's initialize.
APP.java
public class App extends Application {
private static Scene scene;
public static Connection conn;
@Override
public void start(Stage stage) throws IOException {
try{
conn=java.sql.DriverManager.getConnection("jdbc:sqlite:sample.db");
if(conn!=null){
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS tab1(Field0 TEXT, Field1 TEXT, Field2 TEXT);");
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS tab2(Field3 TEXT, Field4 TEXT);");
}
}catch(Exception ex){
System.out.println(ex);
}
scene = new Scene(loadFXML("main"), 640, 480);
stage.setScene(scene);
stage.show();
}
private static Parent loadFXML(String fxml) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
return fxmlLoader.load();
}
public static void main(String[] args) {
launch();
}
public static ResultSet getRS(String table){
String sql="SELECT * FROM "+table;
ResultSet rs=null;
try{
rs=conn.createStatement().executeQuery(sql);
}catch(Exception ex){
System.out.println(ex);
}
return rs;
}
}
MAIN.FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nic.testfx.Main">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" onAction="#loadRem" text="Load Remaining" />
</items>
</Menu>
</menus>
</MenuBar>
<TableView fx:id="Tab" prefHeight="200.0" prefWidth="200.0" />
<VBox fx:id="remPane" prefHeight="200.0" prefWidth="100.0" />
</children>
</VBox>
MAIN.JAVA
public class Main implements Initializable {
@FXML
public TableView<ObservableList<String>> Tab;
@FXML
private VBox remPane;
@Override
public void initialize(URL url, ResourceBundle rb) {
Tab.itemsProperty().bind(getTabRow());
}
public void makeTable(ResultSet rs){
try{
var rsm=rs.getMetaData();
ObservableList<TableColumn<ObservableList<String>,String>>cols=FXCollections.observableArrayList();
for(int i=0;i<rsm.getColumnCount();i++){
final int j=i;
TableColumn<ObservableList<String>,String> col=new TableColumn(rsm.getColumnName(i+1));
col.setCellValueFactory(param->new SimpleStringProperty(param.getValue().get(j)));
cols.add(col);
}
ObservableList<ObservableList<String>> arows=FXCollections.observableArrayList();
while(rs.next()){
ObservableList<String> row=FXCollections.observableArrayList();
for(int i=1;i<=rsm.getColumnCount();i++){
row.add(rs.getString(i));
}
arows.add(row);
}
setTable(cols,arows);
}catch(Exception ex){
System.out.println(ex);
}
}
private static final ObservableList<TableColumn<ObservableList<String>,String>> columns=FXCollections.observableArrayList();
private static final javafx.beans.property.ListProperty<ObservableList<String>> rows=new javafx.beans.property.SimpleListProperty();
private javafx.beans.property.ListProperty getTabRow(){
Tab.getColumns().clear();
Tab.getColumns().addAll(columns);
return rows;
}
private static void setTable(ObservableList<TableColumn<ObservableList<String>,String>>c,ObservableList<ObservableList<String>> r){
columns.setAll(c);
rows.set(r);
}
@FXML
private void loadRem(ActionEvent event) {
try{
for(int i=remPane.getChildren().size()-1;i>=0;i--){
remPane.getChildren().remove(i);
}
javafx.fxml.FXMLLoader fxmlLoader=new javafx.fxml.FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("rem.fxml"));
javafx.scene.layout.Pane panel=fxmlLoader.load();
remPane.getChildren().add(panel);
makeTable(App.getRS("tab1"));
}catch(Exception ex){
System.out.println(ex);
}
}
}
REM.FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<VBox alignment="CENTER" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nic.testfx.Rem">
<children>
<Button fx:id="btn" mnemonicParsing="false" onAction="#loadTab" text="Button" />
</children>
</VBox>
REM.JAVA
public class Rem implements Initializable {
@FXML
private Button btn;
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private void loadTab(ActionEvent event) {
try{
var fxml=new javafx.fxml.FXMLLoader(App.class.getResource("main.fxml"));
fxml.load();
Main controller=fxml.getController();
var rs=App.getRS("tab2");
controller.makeTable(rs);
}catch(Exception ex){
System.out.println(ex);
}
}
}