使用 FXML 在 JavaFX 中自定义 ListView [英] Customize ListView in JavaFX with FXML

查看:47
本文介绍了使用 FXML 在 JavaFX 中自定义 ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 javafx 中创建自定义列表视图.这里我需要在列表单元格中绑定多个组件,如下所示一个标签、一个文本框、一个 HBox 下的一个按钮和两个按钮,一个超链接,另一个 HBox 中的一个标签和这些 HBox 属于一个 VBox 和这个 VBox 位于单个列表单元格下,并且它将重复并制作一个列表视图.

I want to make a customize list view in javafx. Here I need to bind multiple component in list cell as follow, like one label, one textfield, one button under one HBox and two button, one hyperlink, one label in another HBox and these HBox comes under one VBox and this VBox comes under the single list cell and it will repeat and make a list View.

代码是

<ListView fx:id="ListView" layoutX="0" layoutY="30" prefWidth="600" prefHeight="300">
    <HBox fx:id="listBox" alignment="CENTER_LEFT">
        <padding><Insets top="5" bottom="5" left="5"></Insets> </padding>
        <HBox alignment="CENTER_LEFT" prefWidth="170" minWidth="88">
            <Label fx:id="surveyName" text="Field A" styleClass="Name"></Label>
        </HBox>
        <VBox styleClass="Description" prefWidth="155" minWidth="86">

            <HBox>
                <HBox styleClass="surveyDesIcon" prefWidth="20" prefHeight="16"></HBox>
                <Label fx:id="surveyCode" text="PRW3456HJ"></Label>
            </HBox>
            <HBox>
                <HBox styleClass="DateIcon" prefWidth="20" prefHeight="16"></HBox>
                <Label fx:id="Date" text="PRW3456HJ"></Label>
            </HBox>
        </VBox>
        <HBox fx:id="Status" prefWidth="160" minWidth="80">
            <Label fx:id="StatusLabel" text="Checking Files.."/>
        </HBox>
        <HBox fx:id="StatusIcon1" prefWidth="50" prefHeight="50" alignment="CENTER">
            <Label styleClass="StatusIcon1" prefWidth="24" prefHeight="24" alignment="CENTER"/>
        </HBox>
        <HBox fx:id="StatusIcon2" prefWidth="50" prefHeight="50" styleClass="StatusIconBox" alignment="CENTER">
            <Hyperlink styleClass="StatusIcon2" prefWidth="24" maxHeight="24" alignment="CENTER"/>
        </HBox>
    </HBox>
</ListView>

推荐答案

我理解你的问题.在Listview中设置items主要有两种方式:

I understand your question. There are mainly two ways to set items in a Listview:

1. 创建 ObservableList 并使用 ObservableList (listView.setItems(observableList)).

1. Create the ObservableList and set the items of the ListView with the ObservableList (listView.setItems(observableList)).

2. 使用 ListView 类的 setCellFactory() 方法.

2. Use the setCellFactory() method of the ListView class.

您更喜欢使用 setCellFactory() 方法,因为这种方法简化了流程,并且有助于分离业务逻辑和 UI (FXML).

You would prefer to use the setCellFactory() method, because this approach simplies the process as well as it helps to separate out the business logic and the UI (FXML).

这里有更详细的解释:

1. 创建一个名为 listview.fxml 的新 FXML 文件以包含 ListView,并设置 ListViewController 类作为其控制器:

1. Create a new FXML file with the name listview.fxml to contain the ListView, and set the ListViewController class as its controller:

文件:listview.fxml:

<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.ListView?>
<?import demo.ListViewController?>

<GridPane xmlns:fx="http://javafx.com/fxml" alignment="CENTER">
     <ListView fx:id="listView"/>
</GridPane>

<小时>

2. 创建控制器并将其命名为 ListViewController.
控制器可以加载listview.fxml文件并访问listview.


2. Create the controller and name it ListViewController.
The controller can load the listview.fxml file and access the listview.

文件:ListViewController.java:

package demo;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.util.Callback;
import java.io.IOException;
import java.util.Set;

public class ListViewController
{
    @FXML
    private ListView listView;
    private Set<String> stringSet;
    ObservableList observableList = FXCollections.observableArrayList();

    public ListViewController()
    {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/listview.fxml"));
        fxmlLoader.setController(this);
        try
        {
            Parent parent = (Parent)fxmlLoader.load();
            Scene scene = new Scene(parent, 400.0 ,500.0);
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    public void setListView()
    {
        stringSet.add("String 1");
        stringSet.add("String 2");
        stringSet.add("String 3");
        stringSet.add("String 4");
        observableList.setAll(stringSet);
        listView.setItems(observableList);
        listView.setCellFactory(new Callback<ListView<String>, javafx.scene.control.ListCell<String>>()
        {
            @Override
            public ListCell<String> call(ListView<String> listView)
            {
                return new ListViewCell();
            }
        });
    }
}

<小时>

3. 首先,您需要设置ObservableList 的值.这很重要.
然后,使用ObservableList 设置列表项,并调用ListView 上的setCellFactory() 方法.在给定的示例中,我只是将 String 值添加到 String 集合(Set stringSet)中.


3. First you need to set the value of the ObservableList. This is very important.
Then, set the items of list using the ObservableList and call the setCellFactory() method on the ListView. In the given example I just take the String values an add them to the String set (the Set<String> stringSet).

4.ListView调用setCellFactory()方法时,会返回ListCell.所以为了简单起见,我添加了一个扩展 ListCell 的类,并且 setGraphic() 方法存在于 ListCell() 和将设置 ListCell 的项目.

4. When the setCellFactory() method is called on the ListView, it will return the ListCell. So for sake of simplicity, I added a class which extends the ListCell, and the setGraphic() method is present for the ListCell() and will set the items of the ListCell.

文件:ListViewCell.java:

package demo;

import javafx.scene.control.ListCell;

public class ListViewCell extends ListCell<String>
{
    @Override
    public void updateItem(String string, boolean empty)
    {
        super.updateItem(string,empty);
        if(string != null)
        {
            Data data = new Data();
            data.setInfo(string);
            setGraphic(data.getBox());
        }
    }
}

<小时>

5. 我刚刚添加了一个类,它将加载 listCellItem.fxml 并返回 HBox,其中将包含其他组件作为孩子们.
然后将 HBox 设置为 ListCell.


5. I just added a class which will load the listCellItem.fxml and return the HBox, which will contain the other components as children.
The HBox is then set to the ListCell.

文件:listCellItem.fxml:

 <?import demo.Data?>
 <?import javafx.scene.layout.HBox?>
 <?import javafx.scene.control.Label?>

<HBox xmlns:fx="http://javafx.com/fxml" fx:id="hBox">
<children>
    <Label  fx:id="label1"/>
    <Label  fx:id="label2"/>
</children>
</HBox>

文件:Data.java:

package demo;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import java.io.IOException;

public class Data
{
    @FXML
    private HBox hBox;
    @FXML
    private Label label1;
    @FXML
    private Label label2;

    public Data()
    {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/listCellItem.fxml"));
        fxmlLoader.setController(this);
        try
        {
            fxmlLoader.load();
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    public void setInfo(String string)
    {
        label1.setText(string);
        label2.setText(string);
    }

    public HBox getBox()
    {
        return hBox;
    }
}

<小时>

使用这种方式,您可以使用 setCellFactory() 方法将业务逻辑和 FXML 分开.


Using this way, you can use the setCellFactory() method to separate the things that are business logic and FXML.

希望对您有所帮助.

这篇关于使用 FXML 在 JavaFX 中自定义 ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆