Javafxでリストビューをカスタマイズしたい。ここでは、1つのラベル、1つのテキストフィールド、1つのボタンと2つのボタン、1つのハイパーリンク、1つのラベルを別のHBoxのように、リストセルの複数のコンポーネントをバインドする必要があります。これらのHBoxは1つのVBoxに、このVBoxは単一のリストセルとそれが繰り返され、リストビューが作成されます。
コードは
<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
にアイテムを設定するには、主に2つの方法があります。
1。ObservableList
を作成し、ListView
の項目をObservableList
(listView.setItems(observableList)
)で設定します。
2。ListView
クラスのsetCellFactory()
メソッドを使用します。
setCellFactory()
メソッドを使用することをお勧めします。このアプローチはプロセスを単純化し、ビジネスロジックとUI(FXML)を分離するのに役立つためです。
ここに詳細な説明があります:
1。ListView
を含む_listview.fxml
_という名前の新しいFXMLファイルを作成し、ListViewController
クラスをコントローラーとして設定します。
ファイル: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
にアクセスできます。
ファイル: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();
}
});
}
}
_
。最初に、ObservableList
の値を設定する必要があります。 これは非常に重要です。
次に、ObservableList
を使用してリストの項目を設定し、ListView
でsetCellFactory()
メソッドを呼び出します。与えられた例では、String
の値を取り、それらをString
セット(_Set<String> stringSet
_)に追加するだけです。
4。ListView
でsetCellFactory()
メソッドが呼び出されると、ListCell
が返されます。そこで、簡単にするために、ListCell
を拡張するクラスを追加し、setGraphic()
メソッドがListCell()
に存在し、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
に設定されます。
ファイル: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であるものを分離できます。
これが役に立てば幸いです。
上記の@ Anvayの例では、いくつかの調整が必要です。これらはオントラックに設定する簡単なものです。
以下のListViewControllerは、これらの変更に対応しています。 「stringSet」をリスト「stringList」に変更しました。コントローラーは、ほとんどScene Builder 2によって提供されるサンプルコントローラーです。
public class ListViewController
{
@FXML private ResourceBundle resources;
@FXML private URL location;
@FXML private ListView listView;
private List<String> stringList = new ArrayList<>(5);
private ObservableList observableList = FXCollections.observableArrayList();
public void setListView(){
stringList.add("String 1");
stringList.add("String 2");
stringList.add("String 3");
stringList.add("String 4");
observableList.setAll(stringList);
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();
}
});
}
@FXML
void initialize() {
assert listView != null : "fx:id=\"listView\" was not injected: check your FXML file 'CustomList.fxml'.";
setListView();
}
}//ListViewController
JavaFXプラットフォームは、JavaFXアプリケーションのmain()メソッドで起動する必要があります。 Netbeansは、Maven JavaFXアプリケーションテンプレートからこの構造のほとんどを便利に提供します。
public class MainApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/CustomList.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add("/styles/Styles.css");
stage.setTitle("CustomList");
stage.setScene(scene);
stage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
*
* @param args the command line arguments
**/
public static void main(String[] args) {
launch(args);
}
}
何らかの理由でAnvayによる答えは私にはうまくいきませんでした、それを修正するために私がしなければならなかったことは、ほんのいくつかの非常に小さな調整でした:
メインクラス(intellij自動生成)もありました。
public class MainMain extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader fxmlLoader = new
FXMLLoader(getClass().getResource("MainController.fxml"));
try
{
Parent root = fxmlLoader.load();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Title");
primaryStage.show();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
launch(args);
}
これはおそらくここのほとんどの専門家にとって明らかなことだと思いますが、これらの問題はデバッグ中に何時間も困惑しました。