簡體   English   中英

如何在SWT對象上調用Objective-C方法?

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

我想使用Java應用程序以本機方式在OS X的系統托盤/任務欄中顯示文本。 我想通過在NSStatusItem上調用setTitle來做到這NSStatusItem (如本例所示 )。 我從未訪問過SWT中的基礎本機庫,但遇到了麻煩。

該線程上的某個人演示了如何調用Objective-C方法來更改SWT中的窗口屬性(全屏按鈕)。 這是他/她的代碼:

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());
}

因此,我想這將導致此Objective-C代碼:

[window setCollectionBehaviour:1<<7];

現在,我想對SWT TrayItem做同樣的TrayItem 目的是獲得與此Objective-C代碼等效的代碼:

[statusItem setTitle:@"Status"];

但是我收到以下異常:

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)

我不確定這是什么意思。 我標記了引發異常的行。 嘗試執行此操作時還會遇到其他什么問題? 這是我的代碼:

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 ();

        }

    }

}

編輯:感謝Eugene解決了這個問題,但是文本仍然沒有顯示在狀態欄上,因此我在這里提出了另一個問題。

紙盤項目不是控件。 您需要在該類層次結構中查找可可柄。

來源來看,可可柄存儲在“ item”字段中,它是NSStatusItem的實例。

不幸的是,我無法測試它的atm。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM