gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 11:37:24 25 4
gpt4 key购买 nike

我想使用 Java 应用程序以 native 方式在 OS X 的系统托盘/任务栏中显示文本。我想通过调用 NSStatusItem 上的 setTitle 来实现这一点(就像在 this example 中一样)。我从未访问过 SWT 中的底层 native 库,我在使用它时遇到了麻烦。

有人在 this thread演示了如何调用 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 做同样的事情。目标是获得与此 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 解决了这个问题,但是文本仍然没有出现在状态栏上,所以我问了另一个问题 here .

最佳答案

托盘项目不是控件。您需要在该类层次结构中查找 Cocoa 句柄。

sources来看Cocoa 句柄存储在“item”字段中,它是 NSStatusItem 的实例。

很遗憾,我无法在 atm 上对其进行测试。

关于java - 如何在 SWT 对象上调用 Objective-C 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14068752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com