Страницы

Поиск по вопросам

понедельник, 17 июня 2019 г.

Привязка содержимого класса к TreeView

Допустим у меня есть некие классы:
public class Person{ String name; int age; List works; List certificates; }
public class Work{ String companyName; String positionName; int experienceAtMonth; }
public class Certificate{ String organization; String position; Date date; }
Суть в том, что мне необходимо отобразить в TreeView
экземпляры Person, внутри которых отображается список работ и сертификатов.
Остальные поля должны отображаться в отдельном контейнере (типа TextField) при нажатии на соотв. ноду.
Можно конечно формировать строки, а при работе с данными искать по названию. Однако мне это кажется костылем и я бы хотел его избежать и использовать какой-то binding, однако не могу понять, каким образом описать данное поведение.
По сему, подскажите, пожалуйста возможные реализации.


Ответ

UPDATE: + крайне примитивный биндинг
Добавляем интерфейс:
public interface Titlable { String getTitle(); StringProperty getProperty(); }
Дописываем ваши классы:
public class Person implements Titlable { String name; int age; List works; List certificates; public String getTitle() { return name; }
private StringProperty property;
public StringProperty getProperty() { if (null == property) return property = new SimpleStringProperty( name + " " + age ); return property; } }
public class Work implements Titlable{ String companyName; String positionName; int experienceAtMonth; public String getTitle() { return companyName; } private StringProperty property;
public StringProperty getProperty() { if (null == property) return property = new SimpleStringProperty( companyName + " " + positionName ); return property; } }
public class Certificate implements Titlable{ String organization; String position; Date date; public String getTitle() { return organization; }
private StringProperty property;
public StringProperty getProperty() { if (null == property) return property = new SimpleStringProperty( organization + " " + position + " " + date ); return property; }
}
Собственно само дерево:
public class CustomTree extends TreeView {
private final ObservableList persons; private final Main main;
public CustomTree( ObservableList persons, Main main ) { this.persons = persons; this.main = main;
TreeItem rootItem = new TreeItem(); rootItem.setExpanded( true ); this.setShowRoot( false ); this.setCellFactory( p -> new TreeCell() { @Override public void updateItem( Titlable t, boolean empty ) { super.updateItem( t, empty ); setText( t == null ? null : t.getTitle() ); } });
for ( Person p : persons ) { TreeItem pItem = new TreeItem( p ); rootItem.getChildren().add( pItem ); Titlable fake1 = new Titlable() { public String getTitle() { return "Works"; } private StringProperty property = new SimpleStringProperty( "-" ); }; Titlable fake2 = new Titlable() { public String getTitle() { return "Certificates"; } private StringProperty property = new SimpleStringProperty( "-" ); }; TreeItem f1Item = new TreeItem( fake1 ); TreeItem f2Item = new TreeItem( fake2 ); pItem.getChildren().addAll( f1Item, f2Item ); for ( Work w : p.works ) { f1Item.getChildren().add( new TreeItem( w ) ); } for ( Certificate c : p.certificates ) { f2Item.getChildren().add( new TreeItem( c ) ); } } setRoot( rootItem );
EventDispatcher originalDispatcher = this.getEventDispatcher(); this.setEventDispatcher( new NotExpandedEventDispatcher( originalDispatcher ) ); }
private class NotExpandedEventDispatcher implements EventDispatcher{
private final EventDispatcher originDispatcher;
public NotExpandedEventDispatcher( EventDispatcher originDispatcher ){ this.originDispatcher = originDispatcher; }
@Override public Event dispatchEvent( Event event, EventDispatchChain tail ) { if ( event instanceof MouseEvent ) { if ( ((MouseEvent)event).getButton() == MouseButton.PRIMARY && ((MouseEvent)event).getClickCount() >= 2 ) { if ( !event.isConsumed() ) { TreeItem selectedItem = getSelectionModel().getSelectedItem(); main.doSomething( selectedItem .getValue() ); } event.consume(); } }else if ( event instanceof KeyEvent ){ if ( ((KeyEvent)event).getCode() == KeyCode.ENTER ){ if ( !event.isConsumed() ) { TreeItem selectedItem = getSelectionModel().getSelectedItem(); main.doSomething( selectedItem .getValue() ); } event.consume(); } } return originDispatcher.dispatchEvent( event, tail ); } } }
Проверяем:
public class Main extends Application {
private TextArea ta;
@Override public void start( Stage stage ) {
ObservableList persons = FXCollections.observableArrayList();
Work work1 = new Work(); Work work2 = new Work(); Work work3 = new Work(); Work work4 = new Work(); Work work5 = new Work(); Work work6 = new Work(); Work work7 = new Work(); Work work8 = new Work(); work1.companyName = "roga i kapbIta 1"; work2.companyName = "roga i kapbIta 2"; work3.companyName = "roga i kapbIta 3"; work4.companyName = "roga i kapbIta 4"; work5.companyName = "roga i kapbIta 5"; work6.companyName = "roga i kapbIta 6"; work7.companyName = "roga i kapbIta 7"; work8.companyName = "roga i kapbIta 8";
Certificate certificate1 = new Certificate(); Certificate certificate2 = new Certificate(); Certificate certificate3 = new Certificate(); Certificate certificate4 = new Certificate(); certificate1.organization = "kapbIta i roga 1"; certificate2.organization = "kapbIta i roga 2"; certificate3.organization = "kapbIta i roga 3"; certificate4.organization = "kapbIta i roga 4";
Person a = new Person(); Person b = new Person(); Person c = new Person(); a.name = "ivan"; b.name = "da"; c.name = "mar'ya"; a.works = new ArrayList<>( Arrays.asList( work1, work2, work3 ) ); b.works = new ArrayList<>( Arrays.asList( work4, work5, work6 ) ); c.works = new ArrayList<>( Arrays.asList( work7, work8 ) ); a.certificates = new ArrayList<>( Arrays.asList( certificate1 ) ); b.certificates = new ArrayList<>( Arrays.asList( certificate2 ) ); c.certificates = new ArrayList<>( Arrays.asList( certificate3, certificate4 ) );
persons.addAll( a, b, c );
Parent container = new CustomTree( persons, this ); ta = new TextArea();
Scene scene = new Scene( new HBox( container, ta ) ); stage.setWidth( 650 ); stage.setHeight( 600 ); stage.setScene( scene ); stage.show(); }
public static void main(String[] args) { launch(args); }
public void doSomething( Titlable t ) { ta.textProperty().unbind(); ta.textProperty().bind( t.getProperty() ); }
}

Комментариев нет:

Отправить комментарий