使用FXML在JavaFX中自定义ListView [英] Customize ListView in JavaFX with FXML
问题描述
我想在javafx中创建自定义列表视图。在这里,我需要在列表单元格中绑定多个组件,如下所示,例如
一个标签,一个文本字段,一个HBox下的一个按钮和
两个按钮,一个超链接,另一个HBox中的一个标签和
这些HBox属于一个VBox和
这个VBox属于单个列表单元格而
它将重复并制作一个列表View。
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.
代码是
The code is
<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中设置项目
:
I understand your question. There are mainly two ways to set items in a Listview
:
1。创建 ObservableList
并使用 ObservableList
ListView 的项目>( listView.setItems(observableList)
)。
1. Create the ObservableList
and set the items of the ListView
with the ObservableList
(listView.setItems(observableList)
).
2。使用 setCellFactory()
ListView
类的方法。
你我更喜欢使用 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
上的方法。在给定的示例中,我只需要将 String
值添加到 String
集(设置< String> 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屋!