Настройка ListView в JavaFX с FXML
Я хочу настроить представление списка в javafx. Здесь мне нужно связать несколько компонентов в ячейке списка следующим образом: один ярлык, одно текстовое поле, одна кнопка под одним HBox и две кнопки, одна гиперссылка, одна метка в другом HBox и эти HBox приходят под один 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>
3 ответов
я понимаю ваш вопрос. Есть в основном два способа установить элементы в Listview
:
1. создать ObservableList
и установить элементы ListView
С ObservableList
(listView.setItems(observableList)
).
2. использовать setCellFactory()
метод ListView
класса.
вы предпочли бы использовать setCellFactory()
метод, потому что этот подход упрощает процесс, а также помогает отделить бизнес-логику и пользовательский интерфейс (FXML-файл).
вот более подробное объяснение:
1. создайте новый файл FXML с именем listview.fxml
содержат ListView
и выберите ListViewController
класс в качестве контроллера:
<?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
.
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
, а вызов setCellFactory()
метод ListView
. В данном примере я просто беру String
значения добавить их в String
set (the Set<String> stringSet
).
4. когда setCellFactory()
метод вызывается на ListView
, он вернет ListCell
. Поэтому для простоты я добавил класс, который расширяет ListCell
и setGraphic()
способ для ListCell()
и выберите пункты ListCell
.
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
, который будет содержать другие компоненты, как дети.
The HBox
затем к ListCell
.
<?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>
: данные.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 должен быть запущен в потоке приложения JavaFX.
- вы можете вызвать только введенные элементы @FXML из JavaFX инициализации() метод
- необходимо вызвать setListView ()
- набор строк в примере должен быть выделен с новым перед вызовом setListView ().
listviewcontroller ниже работает с этими изменениями. Я изменился"методы stringset" в "stringList". Контроллер в значительной степени является образцом контроллера, предоставляемого Сцена 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 должна быть запущена в методе main () из приложения JavaFX. Netbeans conviently предоставляет большую часть этой структуры из приложения 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 по какой-то причине не работал для меня, что я должен был сделать, чтобы исправить это были просто очень маленькие настройки:
- удалить оператор импорта данных из listCellItem.FXML-файл
- как говорится в комментарии ниже поста в данных.java put hBox = fmxlLoader.load ()
-
У меня также был основной класс (intellij auto generated).
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); }
Я знаю, что это было, вероятно, очевидно для большинства экспертов, но эти проблемы озадачивали меня в течение нескольких часов, пока я отлаживал.