使用注释在 Netbeans 平台上创建 window 个组
Creating window groups on Netbeans Platform with Annotations
已经回答了一个相关的 question,但是从那时起使用注释发生了很多变化。
我正在注册带有注释的 TopComponents。例如:
@TopComponent.Registration(mode = "explorer", openAtStartup = false,
roles = "Test Role")
后来试过这样开群,作为测试:
WindowManager.getDefault().invokeWhenUIReady(() -> {
WindowManager.getDefault().getRegistry().getOpened().stream()
.forEach((tc) -> {
tc.close();
});
TopComponentGroup group
= WindowManager.getDefault()
.findTopComponentGroup("Test Role");
if (group != null) {
group.open();
}
});
所有组件都已关闭,但没有打开任何组件。它不起作用,所以显然缺少一些管道。
这仍然是正确的做法吗?
有这方面的工作示例吗?
以下是我如何让它适用于遇到这个问题的任何人:
我创建了一个 class 并基于此 code 注册为服务:
/**
* Based on code from: http://www.smartcode.ch/netbeans-hide-show-topcomponent/
*
* @author Javier A. Ortiz Bultrón javier.ortiz.78@gmail.com
*/
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.Mode;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
@ServiceProvider(service = ViewManager.class)
public class ViewManager {
private final Map<TopComponent, Mode> hiddenComponents;
public ViewManager() {
hiddenComponents = new HashMap<>();
}
public synchronized void showTopComponent(Class<? extends TopComponent> topComponentClass) {
for (Map.Entry<TopComponent, Mode> hiddenComponentEntry : hiddenComponents.entrySet()) {
TopComponent hiddenComponent = hiddenComponentEntry.getKey();
if (hiddenComponent.getClass().equals(topComponentClass)) {
Mode mode = hiddenComponentEntry.getValue();
WindowManager.getDefault().findMode(mode.getName()).dockInto(hiddenComponent);
hiddenComponent.open();
hiddenComponents.remove(hiddenComponent);
break;
}
}
}
public synchronized void hideTopComponent(Class<? extends TopComponent> topComponentClass) {
Set<TopComponent> shownTopComponents = WindowManager.getDefault().getRegistry().getOpened();
for (TopComponent shownTopComponent : shownTopComponents) {
if (shownTopComponent.getClass().equals(topComponentClass)) {
Mode mode = WindowManager.getDefault().findMode(shownTopComponent);
hiddenComponents.put(shownTopComponent, mode);
shownTopComponent.close();
}
}
}
public synchronized void showAll() {
for (TopComponent tc : hiddenComponents.keySet()) {
showTopComponent(tc.getClass());
}
}
/**
* Load a screen role.
*
* @param role Role to load.
*/
public static void loadRole(String role) {
//Open all components
Lookup.getDefault().lookup(ViewManager.class).showAll();
//Change role (this closes the ones not in this role)
WindowManager.getDefault().setRole(role);
}
}
然后在模块安装程序中我这样做:
@Override
public void restored() {
WindowManager.getDefault().invokeWhenUIReady(() -> {
/**
* All windows start opened. Populated the ViewManager. It is
* important to configure all TopComponents with:
* persistenceType = TopComponent.PERSISTENCE_NEVER or TopComponent.PERSISTENCE_ONLY_OPENED
* and openAtStartup = true
*/
ViewManager manager = Lookup.getDefault().lookup(ViewManager.class);
WindowManager.getDefault().getRegistry().getOpened().stream()
.forEach((tc) -> {
manager.hideTopComponent(tc.getClass());
});
manager.loadRole(Tool.LOBBY);
});
}
如安装程序代码中所述,诀窍是将所有模块标记为在启动时打开并使用正确的持久性类型。
这将在应用程序启动时打开所有 windows,隐藏它们(同时在 ViewManager 上注册它们)然后打开指定的角色。
角色,如记录here,执行以下操作:
此方法的默认实现执行以下操作:
- 隐藏主要window。
- 保存当前window当前布局
角色。
- 从给定的角色加载新的 window 布局。
- 显示主要window.
另一种选择是覆盖 WindowManager 本身来完成所有这些,但我发现它过于具有侵入性和危险性,因为某些方法受到保护,因此不可能包装 WindowsManagerImpl(默认)。也不可能只扩展 WindowsManagerImpl,因为它的包是私有的。
已经回答了一个相关的 question,但是从那时起使用注释发生了很多变化。
我正在注册带有注释的 TopComponents。例如:
@TopComponent.Registration(mode = "explorer", openAtStartup = false,
roles = "Test Role")
后来试过这样开群,作为测试:
WindowManager.getDefault().invokeWhenUIReady(() -> {
WindowManager.getDefault().getRegistry().getOpened().stream()
.forEach((tc) -> {
tc.close();
});
TopComponentGroup group
= WindowManager.getDefault()
.findTopComponentGroup("Test Role");
if (group != null) {
group.open();
}
});
所有组件都已关闭,但没有打开任何组件。它不起作用,所以显然缺少一些管道。
这仍然是正确的做法吗?
有这方面的工作示例吗?
以下是我如何让它适用于遇到这个问题的任何人:
我创建了一个 class 并基于此 code 注册为服务:
/**
* Based on code from: http://www.smartcode.ch/netbeans-hide-show-topcomponent/
*
* @author Javier A. Ortiz Bultrón javier.ortiz.78@gmail.com
*/
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.Mode;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
@ServiceProvider(service = ViewManager.class)
public class ViewManager {
private final Map<TopComponent, Mode> hiddenComponents;
public ViewManager() {
hiddenComponents = new HashMap<>();
}
public synchronized void showTopComponent(Class<? extends TopComponent> topComponentClass) {
for (Map.Entry<TopComponent, Mode> hiddenComponentEntry : hiddenComponents.entrySet()) {
TopComponent hiddenComponent = hiddenComponentEntry.getKey();
if (hiddenComponent.getClass().equals(topComponentClass)) {
Mode mode = hiddenComponentEntry.getValue();
WindowManager.getDefault().findMode(mode.getName()).dockInto(hiddenComponent);
hiddenComponent.open();
hiddenComponents.remove(hiddenComponent);
break;
}
}
}
public synchronized void hideTopComponent(Class<? extends TopComponent> topComponentClass) {
Set<TopComponent> shownTopComponents = WindowManager.getDefault().getRegistry().getOpened();
for (TopComponent shownTopComponent : shownTopComponents) {
if (shownTopComponent.getClass().equals(topComponentClass)) {
Mode mode = WindowManager.getDefault().findMode(shownTopComponent);
hiddenComponents.put(shownTopComponent, mode);
shownTopComponent.close();
}
}
}
public synchronized void showAll() {
for (TopComponent tc : hiddenComponents.keySet()) {
showTopComponent(tc.getClass());
}
}
/**
* Load a screen role.
*
* @param role Role to load.
*/
public static void loadRole(String role) {
//Open all components
Lookup.getDefault().lookup(ViewManager.class).showAll();
//Change role (this closes the ones not in this role)
WindowManager.getDefault().setRole(role);
}
}
然后在模块安装程序中我这样做:
@Override
public void restored() {
WindowManager.getDefault().invokeWhenUIReady(() -> {
/**
* All windows start opened. Populated the ViewManager. It is
* important to configure all TopComponents with:
* persistenceType = TopComponent.PERSISTENCE_NEVER or TopComponent.PERSISTENCE_ONLY_OPENED
* and openAtStartup = true
*/
ViewManager manager = Lookup.getDefault().lookup(ViewManager.class);
WindowManager.getDefault().getRegistry().getOpened().stream()
.forEach((tc) -> {
manager.hideTopComponent(tc.getClass());
});
manager.loadRole(Tool.LOBBY);
});
}
如安装程序代码中所述,诀窍是将所有模块标记为在启动时打开并使用正确的持久性类型。
这将在应用程序启动时打开所有 windows,隐藏它们(同时在 ViewManager 上注册它们)然后打开指定的角色。
角色,如记录here,执行以下操作:
此方法的默认实现执行以下操作:
- 隐藏主要window。
- 保存当前window当前布局 角色。
- 从给定的角色加载新的 window 布局。
- 显示主要window.
另一种选择是覆盖 WindowManager 本身来完成所有这些,但我发现它过于具有侵入性和危险性,因为某些方法受到保护,因此不可能包装 WindowsManagerImpl(默认)。也不可能只扩展 WindowsManagerImpl,因为它的包是私有的。