2016-06-02 13 views
2

Ich möchte eine Überschrift in meiner ObservableList, die fett ist. Ich habe es fett, aber es trifft den Ausnahmeblock, wenn es ausgewählt ist, weil es keine Zeichenfolge ist. Ich kann die anderen Elemente Text machen, aber dann möchte der ChangeListener eine Zeichenfolge. Ich möchte nur, dass die Ausnahme weggeht.Fett Text in ObservableList bricht ChangeListener

Gibt es eine Möglichkeit, es nicht wählbar OR fett und vom Typ String?

ListView<String> list = new ListView<>(); 
    ObservableList items = FXCollections.observableArrayList(); 
    Task curr = tasklist.head; 

    items.add(TextBuilder.create().text("Done Tasks").style("-fx-font-weight:bold;").build()); 
    items.add(curr.name + " - " + curr.description); 
    //items.add(new Text(curr.name + " - " + curr.description)); 

    try { 
     list.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() { 
      public void changed(ObservableValue<? extends String> ov, 
           final String oldvalue, final String newvalue) { 
       if(newvalue != "Done Tasks") 
        selectedValue[0] = newvalue.split(" - ")[0]; 
       else 
        selectedValue[0] = "done"; 
      } 
     }); 
    } catch(Exception e) 
    { 
     actiontarget.setFill(Color.FIREBRICK); 
     actiontarget.setText("You must select a task."); 
    } 

Antwort

1

Quick and Dirty Antwort

direkt an Ihre Wünsche beantworten „kann ich die anderen Elemente Text machen, aber dann will der Change einen String. Ich möchte nur die Ausnahme, wegzugehen.“ Sie ändern Sie den Typ des Change kann Objekt eher als String zu akzeptieren:

new ChangeListener<Object>() { 
    @Override 
    public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue) { 
     if(!(newvalue instanceof Text)) { 
      String string = ((String) newvalue).split(" - ")[0]; 
      System.out.println(string); 
     } 
    } 
} 

Allerdings habe ich nicht den obigen Ansatz empfehlen, wie Sie einige der angeborenen Typ Sicherheit Güte verlieren, dass die Java-Umgebung zur Verfügung stellt.

Tipps Coding

Einige Ratschläge basierend auf dem Code-Snippet.

  1. Verwenden Sie cell factories, um ListView-Zellknoten aus den zugrunde liegenden Elementmodelldaten für die ListView zu generieren.
  2. Fügen Sie Knoten wie Text nicht direkt in die ListView-Elementliste ein. Die ListView-Objektliste dient zum Darstellen von Modellobjekten, die keine Knoten sind. Ich weiß, dass die ListView javadoc dies nicht explizit angibt, aber trotzdem ist das immer noch die beste Empfehlung, die ich habe. Wann immer Sie denken, dass ein Knoten in einem ListView gut passt, ist es normalerweise besser, eine Zellenfabrik zu verwenden.
  3. Wenn Sie items in die ListView platzieren, sollten sie den Typ der Elemente der ListView entsprechen (das Javadoc für ListView besagt dies).
  4. Für einen nicht-trivialen Anwendungsfall, wie Sie hier haben, verwenden Sie eine kompliziertere Datenstruktur, um die Elemente in der Liste zu repräsentieren, so dass Sie semantische Daten wie z. B. ob ein Element ein Header ist direkt in die anstelle von Hardcoding Strings wie "Done Tasks".
  5. Verwenden Sie nicht die Builder-Klassen wie TextBuilder, sie sind veraltet und werden aus zukünftigen JavaFX-Laufzeitverteilungen entfernt.
  6. Verwenden Sie externe Stylesheets, und bearbeiten Sie Stile, indem Sie Stilklassen aktivieren und deaktivieren, anstatt Stildefinitionen im Code zu inline zu legen.

Probe Einbeziehung Tipps

auf Anraten Basierend Sie Ihr Problem auf, als so etwas wie die Anwendung unter Code könnte (man beachte, es immer noch nicht den Stil Info zu einem externen Stylesheet zu extrahieren, werde ich verlassen, dass ein Teil als Übung):

screenshot

import javafx.application.Application; 
import javafx.beans.property.SimpleBooleanProperty; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.collections.FXCollections; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.stage.Stage; 

public class ListDisplay extends Application { 
    @Override 
    public void start(Stage stage) { 
     ListView<TaskItem> listView = new ListView<>(
       FXCollections.observableArrayList(
         new TaskItem("Todo Tasks", null, true, true), 
         new TaskItem("Senility", "The Autumn Years", false, false), 
         new TaskItem("Death", "But I didn't eat the salmon mousse", false, false), 
         new TaskItem("Done Tasks", null, true, true), 
         new TaskItem("Birth", "The Miracle of Life", true, false), 
         new TaskItem("School", "Growth and Learning", true, false), 
         new TaskItem("Middle Age", "Stagnation", true, false), 
         new TaskItem("Live Organ Transplants", "The Machine that goes 'Ping'", true, false) 
       ) 
     ); 

     listView.setCellFactory(param -> new ListCell<TaskItem>() { 
      @Override 
      protected void updateItem(TaskItem item, boolean empty) { 
       super.updateItem(item, empty); 

       if (!empty && item != null) { 
        if (item.isHeader()) { 
         setText(item.getName()); 
         setStyle("-fx-font-weight: bold;"); 
        } else { 
         setText(item.getName() + " - " + item.getDescription()); 
         setStyle(null); 
        } 
       } else { 
        setText(null); 
       } 
      } 
     }); 

     listView.setPrefHeight(200); 

     listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { 
      if (!newValue.isHeader()) { 
       System.out.println("Selected: " + newValue.getName()); 
      } 
     }); 

     stage.setTitle("Monty Python's Meaning of Life"); 
     stage.setScene(new Scene(listView)); 
     stage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

    private static class TaskItem { 
     private final String name; 
     private final String description; 
     private final SimpleBooleanProperty completed; 
     private final boolean header; 

     public TaskItem(String name, String description, boolean completed, boolean header) { 
      this.name = name; 
      this.description = description; 
      this.completed = new SimpleBooleanProperty(completed); 
      this.header = header; 
     } 

     public boolean isHeader() { 
      return header; 
     } 

     public boolean isCompleted() { 
      return completed.get(); 
     } 

     public SimpleBooleanProperty completedProperty() { 
      return completed; 
     } 

     public String getName() { 
      return name; 
     } 

     public String getDescription() { 
      return description; 
     } 
    } 
}