我应该如何将 JFrame 添加到打开的 Office 中的对话框?
Posted
技术标签:
【中文标题】我应该如何将 JFrame 添加到打开的 Office 中的对话框?【英文标题】:How should I add JFrame to dialog in open Office? 【发布时间】:2016-06-17 08:40:28 【问题描述】:Jframe 的父级需要是电子表格,我需要在运行时将 Jframe 添加到在开放式办公室创建的对话框中。这样电子表格就无法处理,点击按钮,只能在由 JFrame 组成的对话框中完成。我正在使用java,UNO。 我试着关注Creating dialog at runtime in open office
package com.example;
import com.sun.star.awt.ActionEvent;
import com.sun.star.awt.XButton;
import com.sun.star.awt.XControl;
import com.sun.star.awt.XControlContainer;
import com.sun.star.awt.XControlModel;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XFixedText;
import com.sun.star.awt.XListBox;
import com.sun.star.awt.XToolkit;
import com.sun.star.awt.XWindow;
import com.sun.star.beans.XMultiPropertySet;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.XNameContainer;
import com.sun.star.lang.EventObject;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.lib.uno.helper.Factory;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public final class AddOn extends WeakBase
implements com.sun.star.frame.XDispatchProvider,
com.sun.star.frame.XDispatch,
com.sun.star.lang.XServiceInfo,
com.sun.star.lang.XInitialization
private final XComponentContext m_xContext;
private com.sun.star.frame.XFrame m_xFrame;
private static final String m_implementationName = AddOn.class
.getName();
private static final String[] m_serviceNames =
"com.sun.star.frame.ProtocolHandler";
private static final String _buttonName = "Button1";
private static final String _cancelButtonName = "CancelButton";
private static final String _labelName = "Label1";
private static final String _labelPrefix = "Number of button clicks: ";
protected XNameContainer m_xDlgModelNameContainer;
protected XMultiServiceFactory m_xMSFDialogModel;
public AddOn(XComponentContext context)
m_xContext = context;
;
public static XSingleComponentFactory __getComponentFactory(String sImplementationName)
XSingleComponentFactory xFactory = null;
if (sImplementationName.equals(m_implementationName))
xFactory = Factory.createComponentFactory(AddOn.class, m_serviceNames);
return xFactory;
public static boolean __writeRegistryServiceInfo(XRegistryKey xRegistryKey)
return Factory.writeRegistryServiceInfo(m_implementationName,
m_serviceNames,
xRegistryKey);
// com.sun.star.frame.XDispatchProvider:
public com.sun.star.frame.XDispatch queryDispatch(com.sun.star.util.URL aURL,
String sTargetFrameName,
int iSearchFlags)
if (aURL.Protocol.compareTo("com.example.addon:") == 0)
if (aURL.Path.compareTo("Command0") == 0)
return this;
if (aURL.Path.compareTo("Command1") == 0)
return this;
if (aURL.Path.compareTo("Command2") == 0)
return this;
return null;
// com.sun.star.frame.XDispatchProvider:
public com.sun.star.frame.XDispatch[] queryDispatches(
com.sun.star.frame.DispatchDescriptor[] seqDescriptors)
int nCount = seqDescriptors.length;
com.sun.star.frame.XDispatch[] seqDispatcher
= new com.sun.star.frame.XDispatch[seqDescriptors.length];
for (int i = 0; i < nCount; ++i)
seqDispatcher[i] = queryDispatch(seqDescriptors[i].FeatureURL,
seqDescriptors[i].FrameName,
seqDescriptors[i].SearchFlags);
return seqDispatcher;
// com.sun.star.frame.XDispatch:
public void dispatch(com.sun.star.util.URL aURL,
com.sun.star.beans.PropertyValue[] aArguments)
if (aURL.Protocol.compareTo("com.example.addon:") == 0)
if (aURL.Path.compareTo("Command0") == 0)
// add your own code here
trigger("execute");
return;
if (aURL.Path.compareTo("Command1") == 0)
// add your own code here
return;
if (aURL.Path.compareTo("Command2") == 0)
// add your own code here
return;
public void addStatusListener(com.sun.star.frame.XStatusListener xControl,
com.sun.star.util.URL aURL)
// add your own code here
public void removeStatusListener(com.sun.star.frame.XStatusListener xControl,
com.sun.star.util.URL aURL)
// add your own code here
// com.sun.star.lang.XServiceInfo:
public String getImplementationName()
return m_implementationName;
public boolean supportsService(String sService)
int len = m_serviceNames.length;
for (int i = 0; i < len; i++)
if (sService.equals(m_serviceNames[i]))
return true;
return false;
public String[] getSupportedServiceNames()
return m_serviceNames;
// com.sun.star.lang.XInitialization:
public void initialize(Object[] object)
throws com.sun.star.uno.Exception
if (object.length > 0)
m_xFrame = (com.sun.star.frame.XFrame) UnoRuntime.queryInterface(
com.sun.star.frame.XFrame.class, object[0]);
// XJobExecutor
public void trigger(String sEvent)
if (sEvent.compareTo("execute") == 0)
try
createDialog();
catch (Exception e)
throw new com.sun.star.lang.WrappedTargetRuntimeException(e.getMessage(), this, e);
/**
* method for creating a dialog at runtime
*/
private void createDialog() throws com.sun.star.uno.Exception
// get the service manager from the component context
XMultiComponentFactory xMultiComponentFactory = m_xContext.getServiceManager();
// create the dialog model and set the properties
Object dialogModel = xMultiComponentFactory.createInstanceWithContext(
"com.sun.star.awt.UnoControlDialogModel", m_xContext);
XPropertySet xPSetDialog = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, dialogModel);
xPSetDialog.setPropertyValue("PositionX", 100);
xPSetDialog.setPropertyValue("PositionY", 100);
xPSetDialog.setPropertyValue("Width", 150);
xPSetDialog.setPropertyValue("Height", 200);
xPSetDialog.setPropertyValue("Title", "Runtime Dialog Button Demo");
// get the service manager from the dialog model
XMultiServiceFactory xMultiServiceFactory = (XMultiServiceFactory) UnoRuntime.queryInterface(
XMultiServiceFactory.class, dialogModel);
// create the button model and set the properties
Object buttonModel = xMultiServiceFactory.createInstance(
"com.sun.star.awt.UnoControlButtonModel");
XPropertySet xPSetButton = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, buttonModel);
xPSetButton.setPropertyValue("PositionX", 20);
xPSetButton.setPropertyValue("PositionY", 70);
xPSetButton.setPropertyValue("Width", 50);
xPSetButton.setPropertyValue("Height", 14);
xPSetButton.setPropertyValue("Name", _buttonName);
xPSetButton.setPropertyValue("TabIndex", (short) 0);
xPSetButton.setPropertyValue("Label", "Click Me");
// create the label model and set the properties
Object labelModel = xMultiServiceFactory.createInstance(
"com.sun.star.awt.UnoControlFixedTextModel");
XPropertySet xPSetLabel = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, labelModel);
xPSetLabel.setPropertyValue("PositionX", new Integer(40));
xPSetLabel.setPropertyValue("PositionY", new Integer(30));
xPSetLabel.setPropertyValue("Width", new Integer(100));
xPSetLabel.setPropertyValue("Height", new Integer(14));
xPSetLabel.setPropertyValue("Name", _labelName);
xPSetLabel.setPropertyValue("TabIndex", new Short((short) 1));
xPSetLabel.setPropertyValue("Label", _labelPrefix);
// create a Cancel button model and set the properties
Object cancelButtonModel = xMultiServiceFactory.createInstance(
"com.sun.star.awt.UnoControlButtonModel");
XPropertySet xPSetCancelButton = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, cancelButtonModel);
xPSetCancelButton.setPropertyValue("PositionX", new Integer(80));
xPSetCancelButton.setPropertyValue("PositionY", new Integer(70));
xPSetCancelButton.setPropertyValue("Width", new Integer(50));
xPSetCancelButton.setPropertyValue("Height", new Integer(14));
xPSetCancelButton.setPropertyValue("Name", _cancelButtonName);
xPSetCancelButton.setPropertyValue("TabIndex", new Short((short) 2));
xPSetCancelButton.setPropertyValue("PushButtonType", new Short((short) 2));
xPSetCancelButton.setPropertyValue("Label", new String("Cancel"));
// insert the control models into the dialog model
XNameContainer xNameCont = (XNameContainer) UnoRuntime.queryInterface(
XNameContainer.class, dialogModel);
xNameCont.insertByName(_buttonName, buttonModel);
xNameCont.insertByName(_labelName, labelModel);
xNameCont.insertByName(_cancelButtonName, cancelButtonModel);
// create the dialog control and set the model
Object dialog = xMultiComponentFactory.createInstanceWithContext(
"com.sun.star.awt.UnoControlDialog", m_xContext);
XControl xControl = (XControl) UnoRuntime.queryInterface(
XControl.class, dialog);
XControlModel xControlModel = (XControlModel) UnoRuntime.queryInterface(
XControlModel.class, dialogModel);
xControl.setModel(xControlModel);
// add an action listener to the button control
XControlContainer xControlCont = (XControlContainer) UnoRuntime.queryInterface(
XControlContainer.class, dialog);
Object objectButton = xControlCont.getControl("Button1");
XButton xButton = (XButton) UnoRuntime.queryInterface(
XButton.class, objectButton);
xButton.addActionListener(new ActionListenerImpl(xControlCont));
// create a peer
Object toolkit = xMultiComponentFactory.createInstanceWithContext(
"com.sun.star.awt.ExtToolkit", m_xContext);
XToolkit xToolkit = (XToolkit) UnoRuntime.queryInterface(
XToolkit.class, toolkit);
XWindow xWindow = (XWindow) UnoRuntime.queryInterface(
XWindow.class, xControl);
xWindow.setVisible(false);
xControl.createPeer(xToolkit, null);
// execute the dialog
XDialog xDialog = (XDialog) UnoRuntime.queryInterface(
XDialog.class, dialog);
xDialog.execute();
// dispose the dialog
XComponent xComponent = (XComponent) UnoRuntime.queryInterface(
XComponent.class, dialog);
xComponent.dispose();
/**
* action listener
*/
public class ActionListenerImpl implements com.sun.star.awt.XActionListener
private int _nCounts = 0;
private XControlContainer _xControlCont;
public ActionListenerImpl(XControlContainer xControlCont)
_xControlCont = xControlCont;
// XEventListener
public void disposing(EventObject eventObject)
_xControlCont = null;
// XActionListener
public void actionPerformed(ActionEvent actionEvent)
// increase click counter
_nCounts++;
// set label text
Object label = _xControlCont.getControl("Label1");
XFixedText xLabel = (XFixedText) UnoRuntime.queryInterface(
XFixedText.class, label);
xLabel.setText(_labelPrefix + _nCounts);
这是一个示例项目,我可以在 open office 上创建一个对话框,但我的下一个任务是如何将 JFrame 添加到对话框中。
我也试过了
public void addConfigToDialog() throws Exception // to be tested
setIdsconfig(IDSConfig.getIDSConfigObject(getM_xContext(), getXcomponent()));//calls singleton method for IDSConfig
JDialog dialog = new JDialog(getIdsconfig());
showModal(dialog);
public void showModal(javax.swing.JDialog dialog)
try
XMultiComponentFactory multiComponentFactory = m_xContext.getServiceManager();
// create the dialog model and set the properties
Object tempDialogModel
= multiComponentFactory.createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel",
m_xContext);
XPropertySet properties = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, tempDialogModel);
properties.setPropertyValue("PositionX", new Integer(0));
properties.setPropertyValue("PositionY", new Integer(0));
properties.setPropertyValue("Width", new Integer(150));
properties.setPropertyValue("Height", new Integer(100));
// properties.setPropertyValue("Enabled", false);
final Object tempDialog
= multiComponentFactory.createInstanceWithContext("com.sun.star.awt.UnoControlDialog",
m_xContext);
XControl xControl = (XControl) UnoRuntime.queryInterface(XControl.class, tempDialog);
XControlModel xControlModel = (XControlModel) UnoRuntime.queryInterface(XControlModel.class, tempDialogModel);
xControl.setModel(xControlModel);
Object toolkit
= multiComponentFactory.createInstanceWithContext("com.sun.star.awt.Toolkit",
m_xContext);
XToolkit xToolkit = (XToolkit) UnoRuntime.queryInterface(XToolkit.class, toolkit);
XWindow xWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, xControl);
xWindow.setVisible(false);//changed
xControl.createPeer(xToolkit, null);
final XDialog xTempDialog = (XDialog) UnoRuntime.queryInterface(XDialog.class, tempDialog);
dialog.addWindowListener(new WindowAdapter()
public void windowClosed(WindowEvent e)
xTempDialog.endExecute();
XComponent component = (XComponent) UnoRuntime.queryInterface(XComponent.class, tempDialog);
component.dispose();
);
dialog.setVisible(true);
xTempDialog.execute();
catch (com.sun.star.uno.Exception ex)
ex.printStackTrace();
我使用了这段代码,但是在将 Jframe 的数据输入到 openoffice 的对话框中时遇到了问题。我在打开的办公室电子表格中的一个按钮上调用 addConfigToDialog()。
【问题讨论】:
您能否让示例运行?如果不是,请描述错误或失败的行为。如果它有效,那么它在哪些方面没有达到您的需要? OpenOffice 对话框使用their own API,而不是JFrame 等摆动组件。 我现在可以创建示例对话框,现在带有按钮和标签@JimK,但我需要以某种方式将 JFrame 添加到打开办公室的对话框中,因为我已经在该 JFrame 中添加了很多功能 【参考方案1】:有几种选择,但我认为您的要求是不可能的。
我的建议是简单地使用 OpenOffice 对话框,并改写 JFrame 功能以使用 UNO API。这就是您的示例的工作原理。
或者,您可以创建一个 Java swing 窗口,而不是创建 OpenOffice 对话框。一个例子是ScriptSelector。然后该窗口将独立于 OpenOffice 运行,并且可以很容易地出现在 OpenOffice 窗口的后面而不是前面。应该可以锁定 OpenOffice 窗口控制器以防止编辑。
或者在 Java 中创建一个有窗口的 AWT 应用程序,并使用 OOBean 嵌入一个 OpenOffice 窗口。
【讨论】:
第一个似乎不是可行的选项,第二个需要像 BeanShell 一样编写脚本(需要 XScriptContext)。我无法获得,我应该如何获得 XScriptContext 的值。 OOoBeanViewer.java 的第三个可以在与 ScriptSelector 相同的链接上找到,运行时出现异常,我无法解决它。 我试过了,但我不想使用任何脚本框架,也不想使用小程序,即选项 2 和 3。 对于使用XScriptContext
的“Hello World”示例,请按照wiki.openoffice.org/wiki/Documentation/DevGuide/Scripting/… 处的Java 说明进行操作。
是的,我看到了它的工作、安装,也检查了 XScriptContext 的代码。我已经尝试过了,但我不想为我的项目创建任何宏或使用任何脚本。【参考方案2】:
我没有找到任何关于如何将 Jframe 添加到打开办公室的对话框的解决方案,而是找到了另一种方法是锁定容器窗口,将 XFrame 传递给 JFrame 的参数。我可以使用 open office 的窗口事件和 java.awt.event 的窗口事件并使用
XDesktop desktop;//get the current desktop object being used
desktop.getCurrentFrame().getContainerWindow().setEnable(false);// uses uno component window methods and uno objects methods
然后在中启用它
JFrame jFrame;//get the JFrame being used
jFrame.addWindowListener(new WindowAdapter()
public void windowClosing(WindowEvent e)
getxDesktop().getCurrentFrame().getContainerWindow().setEnable(true);//get Xdesktop being in used and enable the containerWindow to true
);
在需要解锁电子表格的地方启用容器窗口。 请记住,必须通过将 containerWindow 设置为 true 来解锁电子表格,否则您的文档将被锁定,并且只能通过取消 uno-run 项目或在任务管理器中结束相关进程或通过终端中的命令来关闭。
【讨论】:
以上是关于我应该如何将 JFrame 添加到打开的 Office 中的对话框?的主要内容,如果未能解决你的问题,请参考以下文章