Меню java приложения в трее операционной системы.
Появилась задача сделать системное меню для java приложения. Посмотрев в данном направлении, я нашел несколько вариантов реализации:
- java 6
- java desktop components integraion library (jdic)
- eclipse swt
К предлагаемым библиотекам у меня было всего одно требование – поддержка основных операционных систем (win, linux и mac os). Java 6 отпала из за её отсутствия в системе от apple. Jdic тоже не умеет работать с меню в mac os. Короче говоря, остался только один вариант - eclipse swt. Да и то, поддержка все той же mac os появилась сравнительно недавно - начиная с версии 3.3, которая все еще в разработке (хотя есть и стабильные билды).
Набросав пару строк кода на swt, я нашел следующую проблему – открывающееся меню позиционируется в зависимости от точки нажатия. Это легко рассмотреть на примере приложения azureus, которое использует данную библиотеку:
![]() |
![]() |
Хотя если посмотреть на родные приложения из mac os, легко понять как было бы хорошо выровнять и swt меню:
![]() |
![]() |
Программными методами получилось выровнять только высоту меню, да и то, только отталкиваясь от того, что высота панели везде одинакова:
package com.kobyleha.test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
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 MacTrayTest {
private static final String MENU_ITEM_TEXT = "Menu Item";
private static final String ICON_IMAGE = "icon.gif";
public static void main(String[] args) {
MacTrayTest test = new MacTrayTest();
test.showTray();
}
public void showTray() {
final Display display = new Display();
final Shell shell = new Shell(display);
Tray tray = display.getSystemTray();
if (tray != null) {
initTray(display, shell, tray);
}
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private void initTray(final Display display, final Shell shell, Tray tray) {
Image image = new Image(display, MacTrayTest.class.getClassLoader()
.getResourceAsStream(ICON_IMAGE));
TrayItem item = new TrayItem(tray, SWT.NONE);
item.setImage(image);
final Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
menuItem.setText(MENU_ITEM_TEXT);
item.addSelectionListener(getSelectionListener(display, menu));
item.addMenuDetectListener(getMenuDetectListener(display, menu));
}
private MenuDetectListener getMenuDetectListener(final Display display, final Menu menu) {
return new MenuDetectListener() {
public void menuDetected(MenuDetectEvent arg0) {
menu.setLocation(display.getCursorLocation().x - 13, 26);
menu.setVisible(true);
}
};
}
private SelectionListener getSelectionListener(final Display display, final Menu menu) {
return new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
public void widgetSelected(SelectionEvent event) {
menu.setLocation(display.getCursorLocation().x - 13, 26);
menu.setVisible(true);
}
};
}
}
Буду очень признателен, если кто-то расскажет как обойти это ограничение
»
- 2400 просмотров
- English




Отправить комментарий