Вопрос

У меня есть приложение Java, которое помещает значок в Systray в меню правого щелчка. Когда я запускаю это из IDE (Netbeans), это работает правильно. Но когда я строю его, и запускаю файл JAR, он помещает значок в Systray, но когда я щелкнул правой кнопкой мыши, в нем нет контекстного меню.

Вот какой -то код. Любая помощь оценена. Я проверил версию платформы и консольную версию Java, и они оба кажутся одинаковыми.

package abaxis;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class Systray
{
    private TrayIcon trayIcon = null;
private Image databaseimage;
private Image databaseDisconnectedImage;
public PopupMenu popup;
private ActionListener exitListener;
private ActionListener settingsListener;
private ActionListener connectListener;
private ActionListener disconnectListener;
private static Systray instance;
private static Abaxis abaxis = null;

private SystemTray tray;

private MenuItem connectItem;
private MenuItem settingsItem; 
private MenuItem exitItem;
private MenuItem disconnectItem;

public Systray() 
{
    // create a action listener to listen for default action executed on the tray icon
    exitListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) 
        {
            System.exit(0);
        }
    };
    settingsListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) 
        {
            //New Jframe.
            JFrame settingsJFrame = new AbaxisSettingsForm();
            settingsJFrame.setVisible(true);
        }
    };
    connectListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) 
        {
            //Start the application.
            abaxis.connect();
            setConnectedItems();
        }
    };
    disconnectListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) 
        {
            //Discconect the application.
            abaxis.disconnect();
            setDisconnectedItems();
        }
    };
}

public static Systray getSystray()
{
    if(instance == null)
    {
        instance = new Systray();
        instance.init();
    }
    return instance;
}

public void init()
{
    // get the SystemTray instance
    tray = SystemTray.getSystemTray();
    // load Images
        databaseimage = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/images/database.png"));
        databaseDisconnectedImage = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/images/database_delete.png"));
    // create a popup menu
    this.popup = new PopupMenu();

    // create menu item for the default action
    connectItem = new MenuItem("Connect");
    connectItem.addActionListener(connectListener);
    settingsItem = new MenuItem("Settings");
    settingsItem.addActionListener(settingsListener);
    exitItem = new MenuItem("Exit");
    exitItem.addActionListener(exitListener);
    disconnectItem = new MenuItem("Disconnect");
    disconnectItem.addActionListener(disconnectListener);       

    // set the TrayIcon properties
    //trayIcon.addActionListener(exitListener);
    // construct a TrayIcon
    trayIcon = new TrayIcon( databaseimage, "Abaxis", this.popup );
    // add the tray image
    try 
    {
        tray.add(trayIcon);
    } 
    catch (AWTException e) 
    {
        System.err.println(e);
    }

    try 
    {
        abaxis = Abaxis.start();
    } 
    catch (Exception e)
    {
        System.out.println(e.getMessage());
    }

    if(abaxis.isConnected())
    {
        //Set all the stuff if its connected.
        setConnectedItems();
    } 
    else
    {
        //Set all the stuff if its disconnected.
        setDisconnectedItems();
    }
}

private void setConnectedItems()
{
    this.popup.removeAll();
    this.popup.add(disconnectItem);
    this.popup.add(settingsItem);
    this.popup.add(exitItem);
    this.updateImage(databaseimage);

}

private void setDisconnectedItems()
{
    this.popup.removeAll();
    this.popup.add(connectItem);
    this.popup.add(settingsItem);
    this.popup.add(exitItem);
    this.updateImage(databaseDisconnectedImage);
}

public void updateImage(Image x)
{
    if (this.trayIcon != null) 
    {
         this.trayIcon.setImage(x);
    }
}

}

Спасибо, мне удалось найти, что это была проблема с недостающей банкой. Но файл JAR, по -видимому, находится в папке LIB. Так что я не знаю, почему у него уклоняется. Трассировки стека:

java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path thrown while loading gnu.io.RXTXCommDriver
    Exception in thread "main" java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.loadLibrary0(Unknown Source)
    at java.lang.System.loadLibrary(Unknown Source)
    at gnu.io.CommPortIdentifier.<clinit>(CommPortIdentifier.java:123)
    at abaxis.Abaxis.connectToBloodMachine(Abaxis.java:114)
    at abaxis.Abaxis.connect(Abaxis.java:90)
    at abaxis.Abaxis.init(Abaxis.java:76)
    at abaxis.Abaxis.start(Abaxis.java:53)
    at abaxis.Systray.init(Systray.java:141)
    at abaxis.Systray.getSystray(Systray.java:88)
    at abaxis.Abaxis.main(Abaxis.java:279)
Это было полезно?

Решение

RXTX работает с драйверами, которые зависят от ОС, которую она работает. Эти драйверы снабжены библиотекой RXTX, и они есть:

  • librxtxSerial.so а также librxtxParallel.so Для Linux.
  • librxtxSerial.dll а также librxtxParallel.dll для окон.
  • librxtxSerial.jnilib для Mac

Эта ссылка Имеет инструкции по правильной установке этих драйверов и этот вопрос: java.lang.unsatisfiedlinkerror: нет rxtxserial в java.library.path имеет несколько обходных путей, чтобы решить этот вид исключения.

Однако все они предполагают, что у вас есть доступ к % java_home % path или вы знаете, где находятся драйверы, что в порядке, если вы работаете на своем компьютере, но это не нормально, если вам нужно распространять свое приложение. Если это так, просто скопируйте файлы драйверов в той же папке, где ваш jar размещен. Вы должны увидеть что -то подобное, чтобы знать, что это работает правильно:

Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7

Обновлять

Недавно я заметил, что Linux не включает в себя текущий рабочий каталог в java.library.path имущество. Следовательно, если вы просто добавите librxtxSerial.so в папку приложений, которую вы все еще получаете UnsatisfiedLinkError. Анкет Еще раз, вы можете установить это свойство, когда вы запустите приложение через командную строку, как это:

java -jar -Djava.library.path=/path/to/lib

Или вы можете использовать хакерский подход, объясненный здесь: Настройка «java.library.path» программно. Анкет Этот подход небезопасен, и я не рекомендую его, если у вас есть доступ для реализации другого обходного пути, но я попробовал это, и он работает:

String javaLibraryPath = System.getProperty("java.library.path");

if(!javaLibraryPath.contains(File.pathSeparator + "." + File.pathSeparator)){

    StringBuilder sb = new StringBuilder(javaLibraryPath).append(File.pathSeparator).append(".");
    // The line above appends "." (current directory) to the library path
    // Of course 'rxtxSerial.so' must be placed in the current directory

    System.setProperty("java.library.path", sb.toString());

    try {
        Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
        sysPathsField.setAccessible(true);
        sysPathsField.set(null, null);// Setting this field to null will force a reevaluation of 
                                      // the library path as soon as loadLibrary() is called

    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
        ex.printStackTrace();
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top