Icons neben Text in Listview setzen

Felix123

Mitglied
Hallo zusammen,

ich versuche gerade eine Listview zu erzeugen, in der ich alle Usernamen sehe und über ein Icon erkenne, welcher User online/offline ist.
Die Usernamen hole ich mir über eine Schleife aus einer Hashmap und schreibe sie in ein ListView. Mit dem zugehörigen Key zum Namen, frage ich in einer extra Klasse ab, ob der User online oder offline ist. Das klappt auch so weit. Dann will ich mit der Info UserStatus = 0/1 in die LEDStatus()-Methode rein gehen und dort das Bild setzen (0=rot, 1= grün).

Das Problem ist die updateItem()-Methode. Die wird nur beim letzten Durchlauf ausgeführt und setzt dann alle Bilder auf den Wert, den der letzte User hat.
Ich hätte aber gern, dass das Bild immer zusammen mit dem aktuellen User gesetzt wird.
Bin aber gerade etwas überfragt, wie ich das machen soll.

Mein FXML-Controller Quellcode sieht so aus:

Java:
  @FXML
  private ListView<String> list;
  private final Image RedLED = new Image("/images/LEDRed.png");
  private final Image GreenLED = new Image("/images/LEDGreen.png");
  private Image[] listOfImages = {RedLED, GreenLED};

 /**
  * Initializes the controller class.
  */
  @Override
  public void initialize(URL url, ResourceBundle rb) {

  UserData UserName = new UserData();
   
  HashMap<Integer, String> Map = UserName.getUsers();

  List<String> UserDisplay = new ArrayList<String>();

  for (Integer key : Map.keySet()) {

  String User = Map.get(key);
  int UserStatus = UserName.getUserStatus(key);

  System.out.println("Current User Key is: " + key + "  Current User Name is: " + User + "  Current User Status is: " + UserStatus);

  UserDisplay.add(User);
  ObservableList<String> data = FXCollections.observableArrayList(UserDisplay);
  LEDStatus(UserStatus);
   
  list.setItems((ObservableList<String>) data);
  }
  }

Und die Klasse für die Statusanzeige:
Java:
  public void LEDStatus(Integer UserStatus){
   
  System.out.print( "User Status is: " + UserStatus);
  System.out.println();
   
  list.setCellFactory(listView -> new ListCell<String>() {
   
  private ImageView imageView = new ImageView();

  @Override
  public void updateItem(String list, boolean empty) {
  super.updateItem(list, empty);
  imageView.setFitHeight(50);
  imageView.setFitWidth(50);
  System.out.print("UserStatus: " + UserStatus);
  System.out.println();
  if (empty) {
  setText(null);
  setGraphic(null);
  } else {
  if (UserStatus == 1){
  imageView.setImage(listOfImages[0]);
  setText(list);
  setGraphic(imageView);}
  else {
  imageView.setImage(listOfImages[1]);
  setText(list);
  setGraphic(imageView);}
  }
  }
  });
   
  }
 
Hey Felix,

Dein Code sieht doch sehr speziell aus, vor allem die Tatsache, dass du jedesmal die CellFactory neu setzt.

Versuchs mal so:

Java:
public class Main extends Application
{
      private ListView<UserData> mUserData;
 
      public static void main( String[] args )
      {
            launch(args);
      }

      @Override
      public void start(Stage stage)
      {
            mListView = new ListView<UserData>();
            mListView.setCellFactory( newCallback<ListView<UserData>,ListCell<UserData>>()
            {
                  @Override
                  public UserDataCell<UserData> call(ListView<UserData> listView)
                  {
                       return UserDataCell();
                  }
            });

            mListView.setItems(FxCollections.observableArrayList( UserData.getItemsAsList() );
            Scene lScene = new Scene( mListView );
            stage.setScene( lScene );
            stage.show();
  }

      private class UserDataCell
      {
            private HBox mContent;

            @Override
            public void updateItem(UserData pItem, boolean pIsEmpty)
            {
                  if( !pIsEmpty && pItem != null )
                  {
                        if( mContent == null )
                        {
                              createItem( pItem );
                        }
                        updateItem( pItem );
                  }
                  else
                  {
                        deleteItem( pItem );
                  }
            }

            private void createItem( pItem )
            {
                  mContent = new HBox();
                  setGraphic( mContent );
            }

            private void updateContent( pItem )
            {
                  mContent.getChildren().add( new Label( pItem.getName() ) );
                  Image lImage = new Image( UserData.getImagePath( pItem ) );
                  mContent.getChildren().add( new ImageView( lImage ) );
            }

            private void deleteItem( pItem )
            {
                  mContent.getChildren().clear();
                  setGraphic( null );
                  mContent = null;
            }
      }
}

public class UserData
{
      private static List<UserData> smUserData = new ArrayList<UserData>();
      private static String GREEN_IMAGE_PATH = "/images/your/path/green.png";
      private static String RED_IMAGE_PATH = "/images/your/path/red.png";

      public UserData()
      {
            smUserData.add(this);
      }
      private String mName;
      private boolean mIsOnline;

      //Getter Setter

      public static List<UserData> getItemsAsList()
      {
            return smUserData;
      }

      public static String getImagePath( UserData pData )
      {
            if( pData.isOnline() )
            {
                  return GREEN_IMAGE_PATH;
            }
            return RED_IMAGE_PATH;
      }
}

Der eine oder andere Flüchtigkeitsfehler hat sich eventuell eingeschlichen, da ich den Code nicht getestet habe, ich werde den Thread weiterhin verfolgen und dir weiterhelfen, falls es dazu noch Fragen gibt.
Vom Code Design her ist dies ebenfalls nicht die beste Lösung. Die UserData Klasse sollte lediglich als Datencontainer fungieren, übernimmt aber noch unschöne andere Funktionen. Der nächste Schritt wäre also das Design zu verbessern, wenn du es zum Laufen gekriegt hast. MVC ist hier das Stichwort!

Freundliche Grüsse

Hutzli
 

Neue Themen


Zurück
Oben