2016-03-17 53 views
0

如果我在左边和中间有一个主视图,每个主视图都显示oder Java Beans/POJO,我可以使用共享详细视图以某种方式监听每个视图的活动bean,然后显示当前选定的一个更详细?通过使用Context库,一对一关系很容易管理。是否有可能拥有两个主视图和一个详细视图?

@ViewDocking(areaId ="left", position=1, displayName="Profiles", menuEntry = @WindowMenuEntry(path = "", position=0), accelerator="Shortcut+1") 
public class ProfileListView extends BorderPane implements LocalContextProvider { 

private final SimpleContextContent content = new SimpleContextContent(); 

private final SimpleContext context = new SimpleContext(content); 

@FXML 
private ListView<Profile> listview; 

public ProfileListView() { 
    load(); 
    // add some profiles 
    listview.getItems().add(new Profile("Profile1")); 
    listview.getItems().add(new Profile("Profile2")); 
    listview.getItems().add(new Profile("Profile3")); 

    // setup selection listener 
    listview.getSelectionModel().selectedItemProperty().addListener((value, oldProfile, newProfile) -> { 
     // set active profile and remove old one 
     content.remove(oldProfile); 
     content.add(newProfile); 
    }); 

    // setup double click listener 
    configureClickListener(); 
} 

private Profile getSelectedProfile() { 
    return listview.getSelectionModel().getSelectedItem(); 
} 

private void configureClickListener() { 
    listview.setOnMouseClicked(event -> { 
     // check if it was a double click 
     if(event.getClickCount() == 2) { 
      System.out.println(getSelectedProfile()); 
      // inject into editor pane 
      // calls the procedure to create a tab in the center area... 
     } 
    }); 
} 

private void load() { 
    FXMLLoaders.loadRoot(this); 
} 

@Override 
public Context getLocalContext() { 
    return context; 
} 
} 

这是一个持有项目列表视图的主视图。 另一个将是相同的,作为另一个选项卡右侧对接并持有类型为“Action”的POJO。

详细视图是在这里:

@ViewDocking(areaId = "right", displayName = "Properties", accelerator = "Shortcut+2", menuEntry = @WindowMenuEntry(path = "", position = 0), position = 1) 
public class ProfilePropertiesView extends BorderPane implements LocalContextProvider, ActiveContextSensitive { 

private Context activeContext; 

private SimpleContextContent content = new SimpleContextContent(); 

private SimpleContext context = new SimpleContext(content); 

private Profile profile; 

private IWindowService service = new NullWindowService(); 

@FXML 
private PropertySheet propertysheet; 

public ProfilePropertiesView() { 
    load(); 
    // retrieve framework service, TODO: use tracker 
    BundleContext ctx = FrameworkUtil.getBundle(getClass()).getBundleContext(); 
    service = ctx.getService(ctx.getServiceReference(IWindowService.class)); 
    // initialize callback 
    service.addCallback(title -> { 
     System.out.println("callback called " + title); 
     // update the property sheet ui by re-creating the items list 
     // updateUI(); 
     // we can safely return null 
     return null; 
    }); 

    // configure editor factory so the user is able to use a combobox 
    propertysheet.setPropertyEditorFactory(new CustomPropertyEditorFactory(service)); 
} 

private void load() { 
    FXMLLoaders.loadRoot(this); 
} 

@Override 
public Context getLocalContext() { 
    return context; 
} 

private void contextChanged() { 
    // find profile information 
    Profile found = activeContext.find(Profile.class); 
    // if the found profile is null, ignore it 
    if (found != null) { 
     // reset if profile is valid 
     if (profile != null) { 
      reset(); 
     } 
     // create reference and register 
     profile = found; 
     register(); 
    } 
} 

private void register() { 
    // retrieve observablelist of bean properties if some profile is selected 
    if(profile != null) { 
     ObservableList<Item> items = createDetailedList(profile); 
     propertysheet.getItems().setAll(items); 
    } 
} 

private void updateUI() { 
    // clear property elements and re-create them 
    reset(); 
    // re-create items 
    ObservableList<Item> items = createDetailedList(profile); 
    propertysheet.getItems().addAll(items); 
} 

private ObservableList<Item> createDetailedList(Object bean) { 
    ObservableList<Item> list = FXCollections.observableArrayList(); 
    try { 
     BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class); 
     Arrays.stream(beanInfo.getPropertyDescriptors()).map(pd -> new DetailedBeanProperty(bean, pd)).forEach(list::add); 
    } catch (IntrospectionException e) { 
     e.printStackTrace(); 
    } 

    return list; 
} 

private void reset() { 
    propertysheet.getItems().clear(); 
} 

@Override 
public void setActiveContext(Context activeContext) { 
    this.activeContext = activeContext; 
    this.activeContext.addContextListener(Profile.class, event -> contextChanged()); 
    // trigger change 
    contextChanged(); 
} 
} 

当前ProfilePropertiesView只是配置为显示所选择的配置文件的属性。我希望它能够在用户界面中显示上次选择的POJO的当前信息。这意味着如果用户从ListView中选择了一个配置文件,该配置文件应该显示在属性视图中。如果他从表中选择一个动作(显示在中间),则应该显示该动作的属性。

+0

关闭我的头顶,我想它应该是相同的,与一个主视图。你有没有看到任何问题?你能发布相关的代码吗? – Puce

+0

当然,我一起获取文件... – SirWindfield

+0

我只需要为Action.class POJO注册一个新的ContextListener,然后调用一个方法来填充PropertiesView?我不确定这是否是正确的解决方案... – SirWindfield

回答

0

我是否需要为Action.class POJO注册一个新的ContextListener,然后调用一个方法来填充PropertiesView?我 不能确定这是否是正确的解决方案......

是的,只需添加另一种ContextListener到activeContext你要观察每一个POJO类。

另请注意,在视图的构造函数中,最好使用ServiceTracker而不是通过BundleContext查找服务,因为服务可能还不可用,具体取决于bundle的加载顺序。

你可以找到它使用这里ServiceTracker的一个样本:https://stackoverflow.com/a/35974498/506855

相关问题