簡體   English   中英

是否可以以某種方式擁有兩個主視圖和一個局部視圖?

[英]Is it somehow possible to have two master views and one detail view?

例如,如果我在左側有一個主視圖,在中間有一個主視圖,每個主視圖都顯示了Java Beans / POJO,我可以使用共享的詳細視圖,以某種方式偵聽每個視圖的活動bean,然后在其中顯示當前選擇的一個視圖。更多詳情? 通過使用上下文庫,一對一關系非常容易管理。

@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只是配置為顯示所選配置文件的屬性。 我希望它能夠在UI中顯示最后選擇的POJO的當前信息。 這意味着,如果用戶從ListView中選擇了一個配置文件,則該配置文件應顯示在屬性視圖中。 如果他從表格(顯示在中間)中選擇了一個動作,則應該顯示該動作的屬性。

我是否只需要為Action.class POJO注冊一個新的ContextListener,然后調用一個方法來填充PropertiesView? 我不確定這是否是正確的解決方案...

是的,只需為您要觀察的每種POJO類型向activeContext添加另一個ContextListener

還要注意,在視圖的構造函數中,最好使用ServiceTracker而不是通過BundleContext查找服務,因為該服務可能尚不可用,具體取決於捆綁包的加載順序。

您可以在此處找到使用ServiceTracker的示例: https : //stackoverflow.com/a/35974498/506855

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM