JavaFX VBox oder HBox children filtern?

lam_tr

Top Contributor
Hallo zusammen,

ich habe so etwas ähnliches wie eine ListView gebaut mit verschiedene Item Nodes. Kann ich zum Beispiel über ein Textfeld nach bestimmte Items filtern?

Ich will ähnlich wie bei ListView mit FilteredList es implementieren, habe leider keine Idee wie ich es angehen soll.

Ich könnte über HBox/VBox#getChildren alle Kinder holen und zum Beispiel nach dem Inhalt der Nodes suchen, wenn es nicht enthalten ist die Methode setVisible(false) oder setPrefWidth(0) / setPrefHeight(0) aufrufen?

Wie würdet ihr in dem Fall angehen?

Grüße
lam
 

mihe7

Top Contributor
Dein "ähnliches wie eine ListView" sollte einfach die Einträge aus einer ObservableList darstellen und auf Änderungen der Liste entsprechend reagieren. Dann funktioniert der Rest automatisch.
 

lam_tr

Top Contributor
Dein "ähnliches wie eine ListView" sollte einfach die Einträge aus einer ObservableList darstellen und auf Änderungen der Liste entsprechend reagieren. Dann funktioniert der Rest automatisch.

Ja genau das ist der Weg den ich gehen will, aber es geht mir grad noch ein bisschen mehr ums rendern. Soll jedes mal wenn die Liste angepasst wird den kompletten Layout mit den Items neu gerendert werden oder ich schmeiße die Items von dem Layout raus, oder verstecken :) ? Was ist da der gute Ansatz um so etwas zu machen?

ObservableList#addListChangeLister hört sich schon ganz gut an.

@Robot
ja ich will noch ein bisschen mehr wie nur ListView, zum Beispiel die Größe des HBox oder VBox anhand von den Kindern vergrößern.

Grüße
lam
 

mihe7

Top Contributor
Soll jedes mal wenn die Liste angepasst wird den kompletten Layout mit den Items neu gerendert werden oder ich schmeiße die Items von dem Layout raus,
Verstehe. Persönlich würde ich mir die Arbeit erst einmal so einfach wie möglich machen: alles raus, neu rein. Synchronisieren ist mit Aufwand (auch zur Laufzeit) verbunden.

Aber (großes Aber) ich will Dir da keinen Unsinn erzählen, daher halte Dich besser an @Robat, der kennt sich mit JavaFX wesentlich besser aus :)
 

Robat

Top Contributor
An sich ist der Weg über den ListChangeListener schon nicht schlecht. Dieser Listener bietet direkt die Möglichkeit hinzugefügte / gelöschte Elemente zu bekommen. So könntest du doch recht einfach die Liste bearbeiten.
Java:
ObservableList<String> obs = FXCollections.observableArrayList();
obs.addListener((ListChangeListener<String>) change -> {
    while(change.next()) {
        if(change.wasAdded()) {
            change.getAddedSubList().forEach(....);
        }
        if(change.wasRemoved()) {
            change.getRemoved().forEach(...);
        }
    }
});
Rein aus Interesse: Magst du eventuell etwas mehr über dein Vorhaben preisgeben? Mich würde doch mal interessieren, ob es nicht vielleicht doch über eine ListView möglich ist und ggf. Arbeit spart. zB Unterschiedliche Größen der Elemente ist auch in einer ListView möglich
 

looparda

Top Contributor
Beim ListView hast du über die CellFactory komplette Kontrolle darüber, wie die Listenelemente aussehen und die Höhe kannst du auch dynamisch definieren.

Java:
public class MainView implements Initializable {

    @FXML
    private ListView<ProgressViewModel> listView;

    private final MainViewModel viewModel;

    public MainView() {
        viewModel = new MainViewModel();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        listView.setItems(viewModel.progresses());
        listView.setCellFactory(param -> new ProgressView());
    }
}
Java:
public class ProgressView extends ListCell<ProgressViewModel> {

    @FXML
    private ProgressBar progressBar;

    @FXML
    private Label progressText;

    @Override
    protected void updateItem(ProgressViewModel item, boolean empty) {
        super.updateItem(item, empty);

        if(empty || item == null) {
            setText(null);
            setGraphic(null);
        } else {
            try {
                FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ProgressView.fxml"));
                fxmlLoader.setController(this);
                final Parent node = fxmlLoader.load();
                progressBar.progressProperty().bind(item.progressPropertyPercent());
                progressText.textProperty().bind(item.progressPropertyAsString());
                setGraphic(node);
            } catch (IOException e) {
                e.printStackTrace();
                throw new IllegalStateException(e);
            }
        }
    }
}
XML:
<AnchorPane xmlns="http://javafx.com/javafx/8.0.999-ea" xmlns:fx="http://javafx.com/fxml/1">
   <HBox>
      <children>
            <ProgressBar fx:id="progressBar">
            <padding>
               <Insets left="5.0" right="5.0" />
            </padding></ProgressBar>
            <Label fx:id="progressText" text="Label">
            <padding>
               <Insets left="5.0" right="5.0" />
            </padding></Label>
      </children>
   </HBox>
</AnchorPane>
 
Zuletzt bearbeitet:

lam_tr

Top Contributor
An sich ist der Weg über den ListChangeListener schon nicht schlecht. Dieser Listener bietet direkt die Möglichkeit hinzugefügte / gelöschte Elemente zu bekommen. So könntest du doch recht einfach die Liste bearbeiten.
Java:
ObservableList<String> obs = FXCollections.observableArrayList();
obs.addListener((ListChangeListener<String>) change -> {
    while(change.next()) {
        if(change.wasAdded()) {
            change.getAddedSubList().forEach(....);
        }
        if(change.wasRemoved()) {
            change.getRemoved().forEach(...);
        }
    }
});
Rein aus Interesse: Magst du eventuell etwas mehr über dein Vorhaben preisgeben? Mich würde doch mal interessieren, ob es nicht vielleicht doch über eine ListView möglich ist und ggf. Arbeit spart. zB Unterschiedliche Größen der Elemente ist auch in einer ListView möglich

Na klar,ist kein großes Geheimnis dahinter. Ich versuche ein Kommentarbox zu schreiben. Da die Kommentare unterschiedliche Größen haben soll das an der Stelle dymnamischer sein und unendlich nach unten wachsen. Ich habe das Ganze in ein ScrollPane gepackt. Wie du da sehen kannst, ist die Files Box auch auf dem gleichen Prinzip, wenn da nur 5 Files sind ok, aber wenn da mehr wird , soll die Box mitwachsen. Ich habe es ursprünglich mit ListView gemacht, habs aber nicht so schön gestyled bekommen und das mit dynamisch wachsen lassen war auch nicht einfach, aber geht :)12283
 

Robat

Top Contributor
Ja gut .. das ganze Styling von der ListView dort dann wieder an dein Styling anzupassen kann anstrengend sein, das glaub ich dir. In dem Fall seh ich kein Problem daran, es über deinen jetzigen Weg zu machen. Dazu kommt das du - so wie ich das sehe - ja doch nicht so viel mit einer out-of-the-box ListView gemeinsam hast. Nutz den ListChangeListener um die Elemente zu deiner VBox hinzuzufügen bzw zu löschen und dann sollte das passen.
 

lam_tr

Top Contributor
Ja gut .. das ganze Styling von der ListView dort dann wieder an dein Styling anzupassen kann anstrengend sein, das glaub ich dir. In dem Fall seh ich kein Problem daran, es über deinen jetzigen Weg zu machen. Dazu kommt das du - so wie ich das sehe - ja doch nicht so viel mit einer out-of-the-box ListView gemeinsam hast. Nutz den ListChangeListener um die Elemente zu deiner VBox hinzuzufügen bzw zu löschen und dann sollte das passen.

Danke für die rasche Antwort, dann bin ich schon mal auf dem richtigen Pfad :)
 

lam_tr

Top Contributor
Eine weitere Frage hätte ich noch, wie würdest du in dem Fall für das SelectionModel für die Commet Box oder für die Files in der Box implementieren? Ich habe in die ListView reingeschaut und habe keinen Überblick da zu viel passiert.

Theoretisch kann ich das doch über

Code:
vbox.setOnMouseClicked(e->this.lastSelection = ((CommentItem)e.getSource()).getModel());

Wahrscheinlich wird es gehen, aber ich möchte gerne darüber reden was der schönere Weg wäre.

Grüße
lam

P.S irgendwie kann ich den letzten Post nicht mehr editieren, daher der Doppelpost.
 

lam_tr

Top Contributor
Was genau möchtest du machen? Das selektierte Item hervorheben? So richtig verstanden hab ich dich noch nicht.
Nur aus rein Interesse wenn ich zum Bsp so etwas nachbauen möchte wie bei ListView mit commentVBox.getSelectionModel().getSelectedItem() -> öffne mir die Details Ansicht.

Oder ein Anwendungsfall hier wäre die Files Box, wenn ich eine Datei anklicke soll eine Preview geöffnet werden, beim Selektieren soll ich das Modell bekommen.
 

Robat

Top Contributor
Hatte bisher noch keine Zeit mich damit wirklich zu beschäftigen. Prinzipiell würde es wahrscheinlich einfach ein Model geben mit einer ObjectProperty<T> für das Item und einer IntegerProperty für den Index. Dann würde ich, so wie du oben beschrieben hast, das geklickte Node bekommen, schauen welchem Item das entspricht und dann das SelectionModel updaten bzw eine SelectionChange (o.ä.) Event feuern.
 

Ähnliche Java Themen

Neue Themen


Oben