Klicken Sie mit dem Menü mit der rechten Maustaste aufgetragen, wenn Sie die JAR -Datei ausführen

StackOverflow https://stackoverflow.com/questions/19849558

  •  29-07-2022
  •  | 
  •  

Frage

Ich habe eine Java -App, in der ein Symbol in das Systray mit einem Rechtsklickmenü steckt. Wenn ich dies aus der IDE (NetBeans) ausführe, funktioniert es richtig. Aber wenn ich es erstelle und die JAR -Datei ausführe, wird das Symbol in das SyStray gesteckt, aber wenn ich mit der rechten Maustaste darauf klicke, hat es kein Kontextmenü.

Hier ist ein Code. Jede Hilfe geschätzt. Ich habe die Plattformversion und die Konsolenversion von Java überprüft und beide scheinen gleich zu sein.

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

}

Danke, ich habe festgestellt, dass es ein Problem mit einem vermissten Glas war. Die JAR -Datei scheint jedoch im Lib -Ordner zu sein. Ich weiß also nicht, warum es einen Drücken hat. Stacktrace:

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)
War es hilfreich?

Lösung

RXTX arbeitet mit Treibern zusammen, die vom Betriebssystem abhängen, das es ausgeführt hat. Diese Treiber sind mit der RXTX -Bibliothek versehen und sie sind:

  • librxtxSerial.so und librxtxParallel.so Für Linux.
  • librxtxSerial.dll und librxtxParallel.dll für Windows.
  • librxtxSerial.jnilib Für Mac

Dieser Link hat die Anweisungen, diese Treiber ordnungsgemäß zu installieren, und diese Frage: java.lang.unsatisfiedlinkerror: kein rxtxserial in java.library.path Hat mehrere Problemumgehungen, um diese Art von Ausnahme zu lösen.

Alle von ihnen gehen jedoch davon aus, dass Sie Zugriff auf % Java_Home % Path haben oder wissen, wo sich die Treiber befinden, was in Ordnung ist, wenn Sie an Ihrem Computer arbeiten. Es ist jedoch nicht in Ordnung, wenn Sie Ihre App verteilen müssen. Wenn dies der Fall ist, kopieren Sie einfach die Treiberdateien in demselben Ordner, in dem Ihre jar ist plaziert. Sie müssen so etwas sehen, um zu wissen, dass es richtig funktioniert:

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

Aktualisieren

Vor kurzem habe ich bemerkt, dass Linux das aktuelle Arbeitsverzeichnis nicht einbezieht java.library.path Eigentum. Folglich, wenn Sie einfach hinzufügen librxtxSerial.so In App -Ordner erhalten Sie immer noch UnsatisfiedLinkError. Sie können diese Eigenschaft erneut festlegen, wenn Sie die Anwendung über die Befehlszeile wie folgt ausführen:

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

Oder Sie können hier einen hackigen Ansatz verwenden: Setzen Sie "java.library.path" programmatisch. Dieser Ansatz ist unsicher und ich empfehle ihn nicht, wenn Sie Zugriff auf eine andere Problemumgehung haben, aber ich habe es versucht und es funktioniert:

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();
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top