简体   繁体   English

如何在SWT对象上调用Objective-C方法?

[英]How do I invoke Objective-C methods on SWT objects?

I'd like to use a Java application to display text in the system tray / task bar on OS X in a native way. 我想使用Java应用程序以本机方式在OS X的系统托盘/任务栏中显示文本。 I'd like to do this by invoking setTitle on the NSStatusItem (like in this example ). 我想通过在NSStatusItem上调用setTitle来做到这NSStatusItem (如本例所示 )。 I've never accessed the underlying native libraries in SWT, and I'm having trouble with it. 我从未访问过SWT中的基础本机库,但遇到了麻烦。

Someone on this thread demonstrated how to invoke an Objective-C method to change a property of a window in SWT (the full-screen button). 该线程上的某个人演示了如何调用Objective-C方法来更改SWT中的窗口属性(全屏按钮)。 Here is his/her code: 这是他/她的代码:

Field field = Control.class.getDeclaredField("view");
Object /*NSView*/ view = field.get(rShell);

if (view != null)
{
    Class<?> c = Class.forName("org.eclipse.swt.internal.cocoa.NSView");
    Object /*NSWindow*/ window = c.getDeclaredMethod("window").invoke(view);

    c = Class.forName("org.eclipse.swt.internal.cocoa.NSWindow");
    Method setCollectionBehavior = c.getDeclaredMethod(
        "setCollectionBehavior", JVM.is64bit() ? long.class : int.class);
    setCollectionBehavior.invoke(window, getFullScreenMask());
}

So I suppose this would result in this Objective-C code: 因此,我想这将导致此Objective-C代码:

[window setCollectionBehaviour:1<<7];

Now I'd like to do the same for an SWT TrayItem . 现在,我想对SWT TrayItem做同样的TrayItem The goal is to get the equivalent of this Objective-C code: 目的是获得与此Objective-C代码等效的代码:

[statusItem setTitle:@"Status"];

But I'm getting the following exception: 但是我收到以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: Can not set org.eclipse.swt.internal.cocoa.NSView field org.eclipse.swt.widgets.Control.view to org.eclipse.swt.widgets.TrayItem
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:18)
    at java.lang.reflect.Field.get(Field.java:358)
    at com.teez.status.MainStatus.main(MainStatus.java:35)

I'm not sure what this means. 我不确定这是什么意思。 I marked the line where the exception is thrown. 我标记了引发异常的行。 What other issues could I run into while attempting this? 尝试执行此操作时还会遇到其他什么问题? Here is my code: 这是我的代码:

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tray;
import org.eclipse.swt.widgets.TrayItem;

public class MainStatus {

    public static void main(String[] args) throws Exception {
        Display display = new Display();
        Shell shell = new Shell(display);
        Tray tray = display.getSystemTray();


        if (tray != null) {
            TrayItem item = new TrayItem(tray, SWT.NONE);

            Field field = Control.class.getDeclaredField("view");
            Object /*NSView*/ view = field.get(item); //Exception thrown here

            if (view != null)
            {
                Class<?> c = Class.forName("org.eclipse.swt.internal.cocoa.NSView");
                Object /*NSWindow*/ window = c.getDeclaredMethod("window").invoke(view);

                c = Class.forName("org.eclipse.swt.internal.cocoa.NSStatusItem");


                Method setCollectionBehavior = c.getDeclaredMethod("setTitle", long.class);

                setCollectionBehavior.invoke(window, "Desired title");
            }

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

        }

    }

}

Edit: Thanks Eugene for solving this problem, but the text is still not showing up on the status bar, so I asked another question here . 编辑:感谢Eugene解决了这个问题,但是文本仍然没有显示在状态栏上,因此我在这里提出了另一个问题。

Tray item is not a control. 纸盘项目不是控件。 You need to look for a Cocoa handle in that class hierarchy. 您需要在该类层次结构中查找可可柄。

Judging from sources the Cocoa handle is stored in "item" field and it is instance of NSStatusItem. 来源来看,可可柄存储在“ item”字段中,它是NSStatusItem的实例。

Unfortunately, I can't test it atm. 不幸的是,我无法测试它的atm。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM