JavaFX 如何添加元素,例如。从数据库中存储的项目动态创建的按钮 Mysql?

JavaFX How to add elements eg. Buttons dynamically created from items stored in the database Mysql?

youtube 上有这个视频https://www.youtube.com/watch?v=Idtm2Y6I23w 因此,此人具有动态填充的按钮,这些按钮是根据存储在这张图片中的 database.For 实例中的项目创建的

它有一些类别,包括 TablesStockReportsUsers 当用户单击 Table 类别时,它会显示 Buttons 从数据库 mysql 中存储的项目动态创建的。例如,这是结果图像:

一个人如何发展成那样? 有没有要用到的for循环语句?

编辑

我就是这样做的it.This是源代码。

public class OrderController implements Initializable {

    @FXML
    private ListView<Button> listvieww;

    @FXML
    private HBox hboxx;

    List<String> listOfSomething = null;
//@FXML
//    private Pane panedynamic;
    private DBConnection database = new DBConnection();
    private Connection connection;
    private Statement statement;
    private ResultSet resultSet;

    private ObservableList<Button> buttons = FXCollections.observableArrayList();

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    hboxx.getChildren().add(buttons)
    }

    @FXML
    void acttable(ActionEvent event) {

        // TODO
        String sqlQuery = "SELECT * FROM restauranttables;";
        try {
            connection = database.getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sqlQuery);
            while (resultSet.next()) {
                String current = resultSet.getString("tablename");
                ObservableList<String> list = FXCollections.observableArrayList(current);
                Button b = new Button(list.toString());
                buttons.add(b);

            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    @FXML
    void actlogout(ActionEvent event) {

    }

    @FXML
    void actnew(ActionEvent event) {

    }

    @FXML
    void actorder(ActionEvent event) {

    }

    @FXML
    void actreports(ActionEvent event) {

    }

    @FXML
    void actstock(ActionEvent event) {

    }



    @FXML
    void actusers(ActionEvent event) {

    }

}

这就是我的场景构建器的样子

<?xml version="1.0" encoding="UTF-8"?>

<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXTextField?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.StackPane?>

<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="1080.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.OrderController">
    <children>
        <AnchorPane layoutX="55.0" layoutY="29.0" prefHeight="600.0" prefWidth="1080.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
            <children>
                <TableView layoutX="21.0" layoutY="49.0" prefHeight="386.0" prefWidth="413.0">
                    <columns>
                        <TableColumn prefWidth="122.0" text="Description" />
                        <TableColumn prefWidth="57.0" text="Price" />
                        <TableColumn prefWidth="81.0" text="Sub Total" />
                        <TableColumn prefWidth="96.0" text="Table Id" />
                        <TableColumn prefWidth="57.0" text="Price" />
                    </columns>
                </TableView>
                <JFXTextField layoutX="53.0" layoutY="439.0" prefHeight="37.0" prefWidth="155.0" />
                <JFXTextField layoutX="253.0" layoutY="439.0" prefHeight="37.0" prefWidth="155.0" />
                <GridPane layoutX="63.0" layoutY="503.0" prefHeight="75.0" prefWidth="345.0">
                    <columnConstraints>
                        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                    </columnConstraints>
                    <rowConstraints>
                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                    </rowConstraints>
                    <children>
                        <AnchorPane prefHeight="200.0" prefWidth="200.0">
                            <children>
                                <JFXButton layoutX="25.0" layoutY="25.0" onAction="#actorder" prefHeight="75.0" prefWidth="173.0" text="Order" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                            </children>
                        </AnchorPane>
                        <AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
                            <children>
                                <JFXButton layoutX="39.0" layoutY="14.0" onAction="#actnew" prefHeight="75.0" prefWidth="172.0" text="New" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                            </children>
                        </AnchorPane>
                    </children>
                </GridPane>
                <MenuBar layoutX="21.0" layoutY="14.0" prefHeight="29.0" prefWidth="413.0">
                    <menus>
                        <Menu mnemonicParsing="false" text="File">
                            <items>
                                <MenuItem mnemonicParsing="false" text="Close" />
                            </items>
                        </Menu>
                        <Menu mnemonicParsing="false" text="Edit">
                            <items>
                                <MenuItem mnemonicParsing="false" text="Delete" />
                            </items>
                        </Menu>
                        <Menu mnemonicParsing="false" text="Help">
                            <items>
                                <MenuItem mnemonicParsing="false" text="About" />
                            </items>
                        </Menu>
                    </menus>
                </MenuBar>
                <StackPane fx:id="acContent" layoutX="454.0" layoutY="49.0" prefHeight="525.0" prefWidth="605.0">
                    <children>
                        <AnchorPane fx:id="anchora" prefHeight="200.0" prefWidth="200.0">
                           <children>

                               <GridPane fx:id="sasa" layoutX="17.0" layoutY="7.0" prefHeight="90.0" prefWidth="571.0">
                                   <columnConstraints>
                                       <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                                       <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                                       <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                                       <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                                       <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                                   </columnConstraints>
                                   <rowConstraints>
                                       <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                                   </rowConstraints>
                                   <children>
                                       <AnchorPane prefHeight="200.0" prefWidth="200.0">
                                           <children>
                                               <JFXButton fx:id="table" layoutX="37.0" layoutY="19.0" onAction="#acttable" prefHeight="90.0" prefWidth="135.0" text="TABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                                           </children>
                                       </AnchorPane>
                                       <AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
                                           <children>
                                               <JFXButton fx:id="stock" layoutX="43.0" layoutY="32.0" onAction="#actstock" prefHeight="90.0" prefWidth="134.0" text="STOCK" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                                           </children>
                                       </AnchorPane>
                                       <AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
                                           <children>
                                               <JFXButton fx:id="reports" layoutX="26.0" layoutY="32.0" onAction="#actreports" prefHeight="90.0" prefWidth="134.0" text="REPORTS" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                                           </children>
                                       </AnchorPane>
                                       <AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="3">
                                           <children>
                                               <JFXButton fx:id="users" layoutX="26.0" layoutY="32.0" onAction="#actusers" prefHeight="90.0" prefWidth="134.0" text="USERS" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                                           </children>
                                       </AnchorPane>
                                       <AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="4">
                                           <children>
                                               <JFXButton fx:id="logout" layoutX="28.0" layoutY="32.0" onAction="#actlogout" prefHeight="90.0" prefWidth="134.0" text="LOGOUT" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                                           </children>
                                       </AnchorPane>
                                   </children>
                               </GridPane>
                        <HBox fx:id="hboxx" layoutX="17.0" layoutY="110.0" prefHeight="398.0" prefWidth="571.0" />
                           </children>
                        </AnchorPane>
                    </children>
                </StackPane>
            </children>
        </AnchorPane>
    </children>
</AnchorPane>

我想对齐 hbox 中的按钮,但这里出现错误

@Override
    public void initialize(URL url, ResourceBundle rb) {
    hboxx.getChildren().add(buttons)
    }

任何帮助谢谢。

你需要一个循环。基本上,您可以遍历您的项目,并为每个项目创建一个按钮并将其添加到窗格中。

List<Element> databaseItems = getElementFromDataBase(); 
int i = 0;
int j = 0;
for(Element databaseItem : databaseItems) {
    Button tempButton = new Button(databaseItem.getName());
    tempButton.setOnAction(new MyClickListener()) //handle button click
    gridPane.add(i, j);
    i ++;
    if(i == GridPane.getRowIndex()) {
        j++; // get to the new row.
    }
}

这段代码可能不准确,但它给出了一个大概的概念。

// connectivity for mysql database coding
String category_name= "Stock";
 
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/sonoo","root","root");  
Statement stmt=con.createStatement();  
ResultSet rs=stmt.executeQuery("select * from category where category_name=" + "'" + category_name + "'");  
rs.next();


int num_of_rows = rs.getInt(3); (Fetched from database according to category)

Panel p1=new Panel();
p1.setLayout(new GridLayout(Math.Ceil(num_of_rows/6),6,10,10));

Button b[];

b=new Button[num_of_rows];

for(int i=0;i<num_of_rows;i++)
{
 b[i]=new Button(category_name + "" + (i+1));
 p1.add(b[i]);
 b[i].addActionListener(this); // needed if to perform button click
}

//adding the panel to the container
add(p1);


public void actionPerformed(ActionEvent ae)
{
 // The event click code goes here
}

您想实施的工作流程:

  1. 根据动作事件从数据库中检索一些信息
  2. 对于从 (1) 返回的每一行-> 创建一个 Button
  3. 将所有创建的按钮添加到某个容器

    @FXML
    void acttable(ActionEvent event) {
    
    String sqlQuery = "SELECT * FROM restauranttables;";
    List<Button> buttonlist = new ArrayList<>(); //our Collection to hold newly created Buttons
    try {
        connection = database.getConnection();
        statement = connection.createStatement();
        resultSet = statement.executeQuery(sqlQuery);
        while (resultSet.next()) { //iterate over every row returned
            String restaurant = resultSet.getString("restaurantname"); //extract button text, adapt the String to the columnname that you are interested in
            buttonlist.add(new Button(restaurant));
    
        }
        hboxx.getChildren().clear(); //remove all Buttons that are currently in the container
        hboxx.getChildren().addAll(buttonlist); //then add all your Buttons that you just created
    
    } catch (SQLException e) {
        e.printStackTrace();
    } finally{
        resultSet.close();
        statement.close();
        connection.close;
    }
    }
    

作为工作流,上面发生了什么:

  1. 您创建了一个包含所有新按钮的列表。
  2. 你执行了一个查询
  3. 你从 2
  4. 开始迭代结果集
  5. 您获取要设置为按钮文本的字符串值
  6. 您将该按钮添加到列表中
  7. 您从之前添加的按钮中清除了 HBox
  8. 您将所有新按钮添加到您的 HBox

编辑:不要忘记关闭结果集、语句和连接。如果您将 try/catch 切换为 try with resources 您可以避免显式 .close() 因为所有三个对象都实现了 Autoclosable 接口。我添加了一个 "finally" 语句,它将在您的 try 块退出时执行。您还可以检查 resultSet/statement/connection 是否为空。