JavaFX ListView MultipleSelection

hk

Bekanntes Mitglied
Hallo Forum,
ich möchte von einer ListView die selektierten Elemente abrufen, bekomme aber immer nur das zuletzt selektierte Element zurück. Was mache ich falsch?
Code:
import java.io.IOException;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;

public class PrimaryController {
 
  @FXML ListView fx_lvSelect;
  static ObservableList<String> items;
    
  @FXML private void lvSelected() {
    // In dieser Liste sollten alle selektierten Elemente aufscheinen
    // es ist jedoch immer nur die letzte Selektion in der Liste
    ObservableList<Integer> index =
            fx_lvSelect.getSelectionModel().getSelectedIndices();
    int a = 0;
  }
 
  @FXML public void initialize() {
    fx_lvSelect.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    items =FXCollections.observableArrayList (
    "Single", "Double", "Suite", "Family App");
    fx_lvSelect.setItems(items);
    fx_lvSelect.getSelectionModel().select(0);
    fx_lvSelect.getSelectionModel().select(1);
  } 
}
 

KonradN

Super-Moderator
Mitarbeiter
ich möchte von einer ListView die selektierten Elemente abrufen, bekomme aber immer nur das zuletzt selektierte Element zurück. Was mache ich falsch?
Wie rufst Du es denn auf?

Denn das machst Du ja soweit alles richtig - wenn Du das so startest, dann sind die ersten beiden Elemente selektiert. Mit dem getSelectedIndices bekommst Du auch die Indices. Also die Methode einfach einmal etwas umgeschrieben:
Java:
    @FXML private void lvSelected() {
        // In dieser Liste sollten alle selektierten Elemente aufscheinen
        // es ist jedoch immer nur die letzte Selektion in der Liste
        ObservableList<Integer> index =
                fx_lvSelect.getSelectionModel().getSelectedIndices();
        index.forEach(System.out::println);
    }

dann funktioniert das auch. Ich habe es einfach einen Knopf zugewiesen und habe direkt die zugewiesenen Indices ausgegeben bekommen (0 und 1). Bei einer Veränderung habe ich dann auch die angepasste Auswahl komplett bekommen.

Daher ist es wirklich wichtig, dass Du uns genau zeigst, was Du da überhaupt machst. Denn Deine Methode macht ja nichts - Du holst Dir die Observable list und setzt eine lokale Variable a auf 0 und das ist alles, was Du uns da zeigst.
 

hk

Bekanntes Mitglied
Wie rufst Du es denn auf?

Denn das machst Du ja soweit alles richtig - wenn Du das so startest, dann sind die ersten beiden Elemente selektiert. Mit dem getSelectedIndices bekommst Du auch die Indices. Also die Methode einfach einmal etwas umgeschrieben:
Java:
    @FXML private void lvSelected() {
        // In dieser Liste sollten alle selektierten Elemente aufscheinen
        // es ist jedoch immer nur die letzte Selektion in der Liste
        ObservableList<Integer> index =
                fx_lvSelect.getSelectionModel().getSelectedIndices();
        index.forEach(System.out::println);
    }

dann funktioniert das auch. Ich habe es einfach einen Knopf zugewiesen und habe direkt die zugewiesenen Indices ausgegeben bekommen (0 und 1). Bei einer Veränderung habe ich dann auch die angepasste Auswahl komplett bekommen.

Daher ist es wirklich wichtig, dass Du uns genau zeigst, was Du da überhaupt machst. Denn Deine Methode macht ja nichts - Du holst Dir die Observable list und setzt eine lokale Variable a auf 0 und das ist alles, was Du uns da zeigst.
Ich mache nichts mehr. Ich will das Abfragen von mehreren selektierten Elementen nur testen. Aber auch mit der Printfunktion wird nur das zuletzt selektierte angezeigt.
 

hk

Bekanntes Mitglied
Wie rufst Du es denn auf?

Denn das machst Du ja soweit alles richtig - wenn Du das so startest, dann sind die ersten beiden Elemente selektiert. Mit dem getSelectedIndices bekommst Du auch die Indices. Also die Methode einfach einmal etwas umgeschrieben:
Java:
    @FXML private void lvSelected() {
        // In dieser Liste sollten alle selektierten Elemente aufscheinen
        // es ist jedoch immer nur die letzte Selektion in der Liste
        ObservableList<Integer> index =
                fx_lvSelect.getSelectionModel().getSelectedIndices();
        index.forEach(System.out::println);
    }

dann funktioniert das auch. Ich habe es einfach einen Knopf zugewiesen und habe direkt die zugewiesenen Indices ausgegeben bekommen (0 und 1). Bei einer Veränderung habe ich dann auch die angepasste Auswahl komplett bekommen.

Daher ist es wirklich wichtig, dass Du uns genau zeigst, was Du da überhaupt machst. Denn Deine Methode macht ja nichts - Du holst Dir die Observable list und setzt eine lokale Variable a auf 0 und das ist alles, was Du uns da zeigst.
Wenn ich die Abfrage in den "initialize" Funktion verlege funktioniert es. Aber wenn ich per Maus selektiere bekomme ich nur die zuletzt selektierte.
 

KonradN

Super-Moderator
Mitarbeiter
Zeige den konkreten Code! Was genau machst Du?

Der Code, den ich gezeigt habe, gibt eben genau alle selektierten Indices aus. Ich habe es hier getestet. Zeige die fxml Datei, zeige den Controller, mit dem Du es testest. Dein gezeigter Code gibt ja eben gar nichts aus, nicht einmal das letzte selektierte Element.
 

hk

Bekanntes Mitglied
Zeige den konkreten Code! Was genau machst Du?

Der Code, den ich gezeigt habe, gibt eben genau alle selektierten Indices aus. Ich habe es hier getestet. Zeige die fxml Datei, zeige den Controller, mit dem Du es testest. Dein gezeigter Code gibt ja eben gar nichts aus, nicht einmal das letzte selektierte Element.
Ok,
Controller:
Java:
package com.hk.mybackup;

import java.io.IOException;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;

public class PrimaryController {
 
  @FXML ListView fx_lvSelect;
  static ObservableList<String> items;
 
  @FXML private void lvSelected() {
    // In dieser Liste sollten alle selektierten Elemente aufscheinen
    // es ist jedoch immer nur die letzte Selektion in der Liste
    ObservableList<Integer> index =
            fx_lvSelect.getSelectionModel().getSelectedIndices();
    index.forEach(System.out::println);
    int a = 0;
  }
 
  @FXML public void initialize() {
    fx_lvSelect.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    items =FXCollections.observableArrayList (
    "Single", "Double", "Suite", "Family App");
    fx_lvSelect.setItems(items);
    fx_lvSelect.getSelectionModel().select(0);
    fx_lvSelect.getSelectionModel().select(1);
        ObservableList<Integer> index =
            fx_lvSelect.getSelectionModel().getSelectedIndices();
    index.forEach(System.out::println);
  } 
}
FXML:
Code:
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>

<Pane prefHeight="425.0" prefWidth="569.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.hk.mybackup.PrimaryController">
   <children>
      <Button fx:id="primaryButton" layoutX="14.0" layoutY="45.0" onAction="#switchToSecondary" text="zur Wiederherstellen" />
      <Label layoutX="10.0" layoutY="10.0" text="Datensicherung">
         <font>
            <Font name="System Bold" size="22.0" />
         </font>
      </Label>
      <ListView fx:id="fx_lvSelect" layoutX="53.0" layoutY="92.0" onMousePressed="#lvSelected" prefHeight="200.0" prefWidth="200.0" />
   </children>
</Pane>
 

KonradN

Super-Moderator
Mitarbeiter
Ok, und wie testest Du es dann? das lvSelected wird ja jetzt aufgerufen, wenn Du mit der Maus in der ListView clickst.

Drückst Du evtl. nur die Maus? Dabei wird ja die Selektion aufgehoben und nur das angeklickte Elemente ausgewählt. Das wäre dann das, was Du beschreibst: Das zuletzt ausgewählte Element wird angezeigt (weil das ja so auch das einzig angeklickte Element ist).

Wenn Du die Strg Taste gedrück hältst, dann würdest Du die Auswahl verändern und Du bekommst auch die Auswahl angezeigt.
Oder mit der Shift Taste - da wird dann ein Bereich ausgewählt.

Bei Tests fällt aber auf, dass es nicht immer richtig funktioniert, wenn mehrere Elemente deselektiert werden. Hintergrund dürfte sein, dass auf dieses onClick Event mehrere Dinge ablaufen. Daher kommt die Ausgabe schneller als die Änderung selbst. (Halt ein Click von Anwender und im Rahmen der Verarbeitung laufen mehrere Dinge ab.)

Hier ist also die Frage, was Du auch genau erreichen willst. Mit den Clicks selbst machst Du ja nichts - die Logik mit dem selektieren willst Du ja nicht verändern. Da würde ich also gar nicht drauf reagieren.

Statt an den Clicks bist Du doch an den Veränderungen interessiert. Also willst Du immer dann etwas machen, wenn Du die Selektion verändert wird. Also etwas in der Art:

Java:
    ObservableList<Integer> index;  // Instanzvariable

    public void printAll() {
        System.out.println(index);
    }

    @FXML public void initialize() {
        fx_lvSelect.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        items = FXCollections.observableArrayList (
                "Single", "Double", "Suite", "Family App");
        fx_lvSelect.setItems(items);
        fx_lvSelect.getSelectionModel().select(0);
        fx_lvSelect.getSelectionModel().select(1);
        index =
                fx_lvSelect.getSelectionModel().getSelectedIndices();
        index.addListener((ListChangeListener) c -> printAll()); // Gibt zwei addListener - daher die Angabe, dass es um den ListChangeListener geht!
    }

Immer dann, wenn die Selektion angepasst wurde, wird das printAll aufgerufen.

Aber das ist nicht zwingend notwendig. Wenn Du das lvSelected z.B. bei einem Button machen würdest, dann wäre es auch alles ok, da ja erst die User Aktionen in der ListView abgearbeitet würden und der Klick auf den Button nach der Verarbeitung des ersten Events kommt.
 

hk

Bekanntes Mitglied
Ok, und wie testest Du es dann? das lvSelected wird ja jetzt aufgerufen, wenn Du mit der Maus in der ListView clickst.

Drückst Du evtl. nur die Maus? Dabei wird ja die Selektion aufgehoben und nur das angeklickte Elemente ausgewählt. Das wäre dann das, was Du beschreibst: Das zuletzt ausgewählte Element wird angezeigt (weil das ja so auch das einzig angeklickte Element ist).

Wenn Du die Strg Taste gedrück hältst, dann würdest Du die Auswahl verändern und Du bekommst auch die Auswahl angezeigt.
Oder mit der Shift Taste - da wird dann ein Bereich ausgewählt.

Bei Tests fällt aber auf, dass es nicht immer richtig funktioniert, wenn mehrere Elemente deselektiert werden. Hintergrund dürfte sein, dass auf dieses onClick Event mehrere Dinge ablaufen. Daher kommt die Ausgabe schneller als die Änderung selbst. (Halt ein Click von Anwender und im Rahmen der Verarbeitung laufen mehrere Dinge ab.)

Hier ist also die Frage, was Du auch genau erreichen willst. Mit den Clicks selbst machst Du ja nichts - die Logik mit dem selektieren willst Du ja nicht verändern. Da würde ich also gar nicht drauf reagieren.

Statt an den Clicks bist Du doch an den Veränderungen interessiert. Also willst Du immer dann etwas machen, wenn Du die Selektion verändert wird. Also etwas in der Art:

Java:
    ObservableList<Integer> index;  // Instanzvariable

    public void printAll() {
        System.out.println(index);
    }

    @FXML public void initialize() {
        fx_lvSelect.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        items = FXCollections.observableArrayList (
                "Single", "Double", "Suite", "Family App");
        fx_lvSelect.setItems(items);
        fx_lvSelect.getSelectionModel().select(0);
        fx_lvSelect.getSelectionModel().select(1);
        index =
                fx_lvSelect.getSelectionModel().getSelectedIndices();
        index.addListener((ListChangeListener) c -> printAll()); // Gibt zwei addListener - daher die Angabe, dass es um den ListChangeListener geht!
    }

Immer dann, wenn die Selektion angepasst wurde, wird das printAll aufgerufen.

Aber das ist nicht zwingend notwendig. Wenn Du das lvSelected z.B. bei einem Button machen würdest, dann wäre es auch alles ok, da ja erst die User Aktionen in der ListView abgearbeitet würden und der Klick auf den Button nach der Verarbeitung des ersten Events kommt.
Gut, das mit der Strg-Taste funktioniert. So brauche ich aber das Mehrfachselektieren nicht.
Was ich eigentlich will ist eine Liste aus der ich mehrere Elemente aktivieren, deaktivieren kann ohne die nicht betroffenen zu verändern. Etwa so:
Screenshot 2023-01-06 170904.png
 

KonradN

Super-Moderator
Mitarbeiter
Ich verstehe jetzt gerade nicht, was Du meinst. Wenn Du die ListView irgendwie anders nutzt / bedienst, dann ist das ja auch ok. Du musst die AUswertung der selektierten Elemente halt an einer sinnvollen Stelle mache. Das onClick Event ist dazu eben nicht geeignet.

Generell kannst Du es so aufbauen, wie Du willst. Wenn Du eine Liste mit Checkboxen haben willst, dann kannst Du Dir auch sowas bauen. Da wird vermutlich einfach ein CheckBoxListCell ausreichen. Aber man kann da auch z.B. zu https://controlsfx.github.io/ greifen mit der CheckListView.
 

hk

Bekanntes Mitglied
Ich verstehe jetzt gerade nicht, was Du meinst. Wenn Du die ListView irgendwie anders nutzt / bedienst, dann ist das ja auch ok. Du musst die AUswertung der selektierten Elemente halt an einer sinnvollen Stelle mache. Das onClick Event ist dazu eben nicht geeignet.

Generell kannst Du es so aufbauen, wie Du willst. Wenn Du eine Liste mit Checkboxen haben willst, dann kannst Du Dir auch sowas bauen. Da wird vermutlich einfach ein CheckBoxListCell ausreichen. Aber man kann da auch z.B. zu https://controlsfx.github.io/ greifen mit der CheckListView.
Danke, das werde ich mir ansehen!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
MiMa Obseved List mit ListView (Dateiliste) AWT, Swing, JavaFX & SWT 4
AmsananKING ListView Drag And Drop AWT, Swing, JavaFX & SWT 0
AmsananKING Drag And Drop Filenames Inside A Listview AWT, Swing, JavaFX & SWT 1
D Layout einer scene mit ListView Elementen und Zwei Textfeldern AWT, Swing, JavaFX & SWT 1
TheWhiteShadow JavaFX ListView Problem beim Entfernen von Elementen AWT, Swing, JavaFX & SWT 1
Davee JavaFX ListView = null wenn ich sie in Laufzeit ändern will! AWT, Swing, JavaFX & SWT 16
G Eintrag soll nur einmal in Listview zu sehen sein AWT, Swing, JavaFX & SWT 3
T ListView nach Erweiterung Fehler in CellFactory AWT, Swing, JavaFX & SWT 8
T ListView in TableCell AWT, Swing, JavaFX & SWT 4
MiMa File Dateien im ListView als Name anzeigen? AWT, Swing, JavaFX & SWT 6
B JavaFX ListView in Kombination mit TextField AWT, Swing, JavaFX & SWT 5
B JavaFX das richtige ListView filtern AWT, Swing, JavaFX & SWT 2
B Dynamische ListView-Größe, die bei Fenstergrößenänderung sich anpasst AWT, Swing, JavaFX & SWT 19
S JavaFX ListView Inhalte während Laufzeit ändern AWT, Swing, JavaFX & SWT 23
karlmasutra JavaFX ListView zeigt Einträge nicht an AWT, Swing, JavaFX & SWT 11
B Textfelder in einer ListView ausgeben AWT, Swing, JavaFX & SWT 13
J CheckBoxListCell auf click event in listView reagieren AWT, Swing, JavaFX & SWT 1
karlmasutra JavaFX Listenelemente bearbeiten Listview AWT, Swing, JavaFX & SWT 1
D JavaFX Listview mit observableList AWT, Swing, JavaFX & SWT 6
MiMa Selektion aus einer ListView AWT, Swing, JavaFX & SWT 5
N Frage zu ListView AWT, Swing, JavaFX & SWT 11
L JavaFX ListView Größe anpassen AWT, Swing, JavaFX & SWT 1
F JavaFX ListView füllen in Controller Class AWT, Swing, JavaFX & SWT 12
F JavaFX In SampleController ObservableList zu ListView hinzufügen AWT, Swing, JavaFX & SWT 0
D JavaFX ListView & TabelView AWT, Swing, JavaFX & SWT 9
F JavaFX Custom ListView erstellt ghost Element AWT, Swing, JavaFX & SWT 3
F JavaFX Von Datenbank in ListView AWT, Swing, JavaFX & SWT 4
F JavaFX ListView Zeilenhöhe AWT, Swing, JavaFX & SWT 2
M Auswahl aus einer ListView AWT, Swing, JavaFX & SWT 3
F Icons neben Text in Listview setzen AWT, Swing, JavaFX & SWT 2
K ListView right click AWT, Swing, JavaFX & SWT 1
Y Listview Textfield vergrößern, Schrift anpassen AWT, Swing, JavaFX & SWT 0
C Liste - ListView wird nicht angezeigt AWT, Swing, JavaFX & SWT 15
L JavaFX ListView oder TableView Style überschreiben? AWT, Swing, JavaFX & SWT 6
thobren listview seclect abschalten AWT, Swing, JavaFX & SWT 1
NoXiD Java FX JFX 2 DnD ListView AWT, Swing, JavaFX & SWT 3
T [JavaFX 2.0] ListView editieren AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen


Oben