作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用 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/
我是一名优秀的程序员,十分优秀!