我应该如何将 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 中的对话框?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 jscrollpane 添加到 jframe?

如何将两个 JPanel 添加到中心的 JFrame?

无法将组件添加到扩展 JFrame 的类

如何将多个 MouseListeners 添加到单个 JFrame?

将图像添加到 JFrame

如何在不覆盖JFrame的情况下将JPanel图形添加到JFrame