انقر بزر الماوس الأيمن على القائمة المكسورة عند تشغيل ملف جرة

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

  •  29-07-2022
  •  | 
  •  

سؤال

لدي تطبيق Java الذي يضع أيقونة في Systray مع قائمة النقر بزر الماوس الأيمن. عندما أقوم بتشغيل هذا من IDE (NetBeans) ، فإنه يعمل بشكل صحيح. ولكن عندما أقوم بإنشائها ، وقم بتشغيل ملف الجرة ، فإنه يضع الرمز في 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);
    }
}

}

شكرًا ، تمكنت من العثور على أنها كانت مشكلة مع جرة مفقودة. ولكن يبدو أن ملف الجرة في مجلد LIB. لذلك أنا لا أعرف لماذا لديها winge. تتبع المكدس:

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 للينكس.
  • librxtxSerial.dll و librxtxParallel.dll للنوافذ.
  • librxtxSerial.jnilib لل ماك

هذا الرابط لديه التعليمات لتثبيت هذه برامج التشغيل بشكل صحيح وهذا السؤال: java.lang.unsatisfiedlinkerror: لا rxtxserial في java.library.path لديه عدة حلول لحل هذا النوع من الاستثناء.

ومع ذلك ، يفترض جميعهم أن لديك إمكانية الوصول إلى مسار ٪ java_home ٪ أو أنك تعرف أين توجد برامج التشغيل وهو أمر جيد إذا كنت تعمل على جهاز الكمبيوتر الخاص بك ولكن لا بأس إذا كنت بحاجة إلى توزيع التطبيق الخاص بك. إذا كان هذا هو الحال ، فما عليك سوى انسخ ملفات برنامج التشغيل في نفس المجلد حيث 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