java 中的 swt 未打开且菜单未显示

Shall is not opening and Menu is not showing in swt in java

我想在 java 中嵌入 Microsoft Word。我的程序将在 jframe 中打开一个 word 文档文件。经过大量搜索,我找到了以下解决方案:Open MS documents into JFrame

将MS文档嵌入Jframe的代码如下:

 import java.awt.Canvas;
import java.io.File;

import javax.swing.JFrame;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;


public class AbrirWordJFrame {
    static OleClientSite clientSite;
    static OleFrame frame;

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);

        JFrame jframe=new JFrame("Mi jframe");
        final Canvas canvas=new Canvas();
        jframe.getContentPane().add(canvas);
        jframe.setSize(800, 600);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setVisible(true);

        display.asyncExec(new Runnable() {
            public void run() {
                Shell shell = SWT_AWT.new_Shell(display, canvas);
                shell.setSize(800, 600);

                //abrimos un word
                shell.setText("Word Example");
                shell.setLayout(new FillLayout());
                try {
                    frame = new OleFrame(shell, SWT.NONE);
                    //esto abre un documento existente
                    clientSite = new OleClientSite(frame, SWT.NULL, new File("prueba.doc"));
                    //esto abre un documento en blanco
//                  clientSite = new OleClientSite(frame, SWT.NONE, "Word.Document");
                    addFileMenu(frame); 
                    System.out.println(" I am in run method ");
                } catch (SWTError e) {
                    System.out.println("Unable to open activeX control");
                    display.dispose();
                    return;
                }  
                shell.open(); 

            }
        }); 
//      
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();  
        }
        display.dispose();
    }

    static void addFileMenu(OleFrame frame) {
        final Shell shell = frame.getShell(); 
        Menu menuBar = shell.getMenuBar();
        if (menuBar == null) {
            menuBar = new Menu(shell, SWT.BAR);
            shell.setMenuBar(menuBar);
        } 
        MenuItem fileMenu = new MenuItem(menuBar, SWT.CASCADE);
        fileMenu.setText("&File");
        Menu menuFile = new Menu(fileMenu);
        fileMenu.setMenu(menuFile);
        frame.setFileMenus(new MenuItem[] { fileMenu }); 

        MenuItem menuFileOpen = new MenuItem(menuFile, SWT.CASCADE);
        menuFileOpen.setText("Open..."); 
        menuFileOpen.addSelectionListener( new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                fileOpen();

                System.out.println(" I am in widgetSelected method ");
            }
        });
        MenuItem menuFileExit = new MenuItem(menuFile, SWT.CASCADE);
        menuFileExit.setText("Exit");
        menuFileExit.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                shell.dispose();
            }
        }); 
    }

    static class fileSaveItemListener implements SelectionListener {
        public void widgetSelected(SelectionEvent event) {
            fileOpen();

            System.out.println(" I am in widgetSelected method ");
        }

        public void widgetDefaultSelected(SelectionEvent event) {
            fileOpen();

            System.out.println(" I am in widgetSelected method ");
        }
      }

    static void fileOpen() {
        FileDialog dialog = new FileDialog(clientSite.getShell(), SWT.OPEN);
        dialog.setFilterExtensions(new String[] { "*.doc" });
        String fileName = dialog.open();
        if (fileName != null) {
            clientSite.dispose();
            clientSite = new OleClientSite(frame, SWT.NONE, "Word.Document", new File(fileName));
            clientSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
        }
    }
}

但是我无法打开 Shell window 。里面也没有菜单。我怎样才能打开 shall 并在其中显示菜单?请帮助我

按照@Baz 的建议,您可以稍微修改您的代码以仅使用 SWT。

对于初学者,您可以删除整个 JFrame 创建和设置:

public static void main(final String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    // Remove these lines:
    final JFrame jframe = new JFrame("Mi jframe");
    final Canvas canvas = new Canvas();
    jframe.getContentPane().add(canvas);
    jframe.setSize(800, 600);
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jframe.setVisible(true);
    ...

接下来,您不需要创建两个 Shell 对象:

...
public static void main(final String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display); // Already creating a Shell here

    display.asyncExec(new Runnable() {
        public void run() {
            final Shell shell = SWT_AWT.new_Shell(display, canvas);  // Remove this
            shell.setSize(800, 600);
...

接下来,您不需要 Runnable。只需在 shell 上设置大小、文本和布局。从那里您可以将 OleFrame 等添加到 shell 并打开它。

你的主要方法应该留下这样的东西:

public static void main(final String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    shell.setSize(800, 600);
    shell.setText("Word Example");
    shell.setLayout(new FillLayout());

    try {
        frame = new OleFrame(shell, SWT.NONE);
        // esto abre un documento existente
        // clientSite = new OleClientSite(frame, SWT.NONE, new File("Doc1.doc"));
        // esto abre un documento en blanco
        clientSite = new OleClientSite(frame, SWT.NONE, "Word.Document");
        addFileMenu(frame);
        System.out.println(" I am in run method ");
    } catch (final SWTError e) {
        System.out.println("Unable to open activeX control");
        display.dispose();
        return;
    }

    shell.open();

    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
    display.dispose();
}

小注,但我还在下面提到的行中将 SWT.NULL 更改为 SWT.NONE,因为即使两者的值都是 0x0,但 SWT.NONE 是更准确的样式值(未设置样式位)。

clientSite = new OleClientSite(frame, SWT.NONE, "Word.Document");

通过这些更改,我能够成功打开应用程序(默认打开一个新的空白文档)并使用工具栏打开一个 *.doc 文件: