Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

JNI & C & EVENTS

Thread view: 
ginjasvinja - 19 Dec 2005 14:34 GMT
Hi all, I've already been here with similar topic but I need your help
again. I wrote the code that should be catch an event like "left button
of mouse clicked", using java JNI and C. I wrote it by following the
Desktop Indicator sample I've found on Internet. here is the code:

/*************************************Dogadjajava.java*******************************************/
import java.util.*;

public class Dogadjajava
{
    private int handler = 0;
    private Vector listeners = new Vector();

    private native void nativeEnable() throws UnsatisfiedLinkError;
    private native void nativeDisable() throws UnsatisfiedLinkError;
    /**
    * Loads the JNI library, if available.
    */
    public static boolean initialize()
    {
        // Load JNI library
        try
        {
            System.out.println("J: Dynamic Library should be Loaded\n");
            System.load( "C:\\C++\\dogadjajC\\Debug\\dogadjajC.dll" );
            System.out.println("J: Dynamic Library Loaded\n");
        }
        catch( UnsatisfiedLinkError x )
        {
            return false;
        }

        return true;
    }

    /**
    * Creates a window.
    **/
    public Dogadjajava()
    {
        super();
        System.out.println("J: Kontruktor Daogadajava\n");
    }

    /**
    * Enables the window for events
    */
    public void show()
    {
        System.out.println("J: show-call nativeEnable\n");
        try
        {
            nativeEnable();
        }
        catch( UnsatisfiedLinkError x )
        {
        }
    }

    /**
    * Hides the window for events
    */
    public void hide()
    {
        System.out.println("J: hide-call nativeDisable\n");
        try
        {
            nativeDisable();
        }
        catch( UnsatisfiedLinkError x )
        {
        }
    }

    /**
    * Notifies all listeners that the desktop indicator was clicked.
    **/
    public void fireClicked()
    {
        Vector listenersClone = (Vector) listeners.clone();
        DogadjajavaListener listener;
        for( Enumeration e = listenersClone.elements(); e.hasMoreElements();
)
        {
            listener = (DogadjajavaListener) e.nextElement();
            listener.onDogadjajClicked( this );
        }
        System.out.println("Kliknuli ste misem!\n");
    }

    public void addDogadjajavaListener( DogadjajavaListener listener )
    {
        listeners.addElement( listener );
    }

    public void removeDogadjajavaListener( DogadjajavaListener listener )
    {
        listeners.removeElement( listener );
    }

}

/**************************************DogadjajavaListener.java*************************************/
public interface DogadjajavaListener
{
    /**
    * Called when something is clicked.
    **/
    void onDogadjajClicked( Dogadjajava source );
}

/**************************************DogadjajavaTest.java****************************************/
public class DogadjajavaTest implements DogadjajavaListener
{
    static DogadjajavaTest listener;

    static public void main( String args[] )
    {
        // Initialize JNI extension
        if( !Dogadjajava.initialize() )
        {
            System.err.println( "Either you are not on Windows, or there is a
problem with the dogadjajC library!" );
            return;
        }

        Dogadjajava dogadjaj = new Dogadjajava();
        listener = new DogadjajavaTest();
        dogadjaj.addDogadjajavaListener( listener );
        dogadjaj.show();

        // Instructions
        System.err.println( "See the mouse? Click it!" );

        // Wait for the bitter end
        try
        {
            synchronized( listener )
            {
                listener.wait();
            }
        }
        catch( InterruptedException x )
        {
        }

        // Time to die
        dogadjaj.removeDogadjajavaListener( listener );
        dogadjaj.hide();

        System.err.println( "Goodbye!" );
    }

    public void onDogadjajClicked( Dogadjajava source )
    {
        synchronized( listener )
            {
                listener.notifyAll();
            }
        System.out.println("Klik misem!\n");
    }
}

/***************************************dogadjajC.cpp****************************************/
#include "stdafx.h"
#include "Dogadjajava.h"
#include "DogadjajCHandler.h"

HINSTANCE g_instance = NULL;

BOOL WINAPI DllMain
(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpvReserved   // reserved
)
{
   switch( fdwReason )
    {
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:

        case DLL_PROCESS_ATTACH:
            g_instance = hinstDLL;
            break;
   }
   return TRUE;
}

extern "C"
/*
* Class:     Dogadjajava
* Method:    nativeDisable
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Dogadjajava_nativeDisable
 (JNIEnv *env, jobject object)
{
    /*test*/
    printf("    C: nativeDisable\n");

    // Get handler
    DogadjajCHandler *l_handler = DogadjajCHandler::extract( env, object
);

    // Disable it
    if( l_handler )
        l_handler->disable();
}

extern "C"
/*
* Class:     Dogadjajava
* Method:    nativeEnable
* Signature: (ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Dogadjajava_nativeEnable
 (JNIEnv *env, jobject object)
{
    /*test*/
    printf("    C: nativeEnable\n");

    // Get handler
    DogadjajCHandler *l_handler = DogadjajCHandler::extract( env, object
);

    // Create our handler
    l_handler = new DogadjajCHandler( env, object );

    // Enable it
    if( l_handler )
        l_handler->enable( env );

}

/****************************************dogadjajCHandler.cpp***************************************/
#include "stdafx.h"
#include "DogadjajCHandler.h"
#include "DogadjajCThread.h"

#define WM_MOUSE_CLICK (WM_USER+1)

DogadjajCHandler *DogadjajCHandler::extract( JNIEnv *env, jobject
object )
{
    /*test*/
    printf("    C: extract\n");

    // Get field ID
    jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( object ),
"handler", "I" );

    // Get field
    DogadjajCHandler *l_handler = (DogadjajCHandler *) env->GetIntField(
object, l_handlerId );

    return l_handler;
}

DogadjajCHandler::DogadjajCHandler( JNIEnv *env, jobject object)
{
    /*test*/
    printf("    C: konstruktor\n");

    m_window = NULL;

    // Reference object
    m_object = env->NewGlobalRef( object );

    // Get method ID
    m_fireClicked = env->GetMethodID( env->GetObjectClass( m_object ),
"fireClicked", "()V" );

    // Get field ID
    jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( m_object
), "handler", "I" );

    // Set field
    env->SetIntField( m_object, l_handlerId, (jint) this );
}

DogadjajCHandler::~DogadjajCHandler()
{
    /*test*/
    printf("    C: destruktor\n");

    // Get field ID
    jfieldID l_handlerId = g_DogadjajCThread.m_env->GetFieldID(
g_DogadjajCThread.m_env->GetObjectClass( m_object ), "handler", "I" );

    // Set field
    g_DogadjajCThread.m_env->SetIntField( m_object, l_handlerId, 0 );

    // Release our reference
    g_DogadjajCThread.m_env->DeleteGlobalRef( m_object );

    // Destroy window
    DestroyWindow( m_window );

}

void DogadjajCHandler::enable( JNIEnv *env )
{
    /*test*/
    printf("    C: enable\n");

    g_DogadjajCThread.MakeSureThreadIsUp( env );
    while( !PostThreadMessage( g_DogadjajCThread, WM_CLICK, enableCode,
(LPARAM) this ) )
        Sleep( 1000 );
}

void DogadjajCHandler::doEnable()
{
    /*test*/
    printf("    C: doEnable\n");

    // Register window class
    WNDCLASSEX l_Class;
    l_Class.cbSize = sizeof( l_Class );
    l_Class.style = 0;
    l_Class.lpszClassName = TEXT( "DogadjajCHandlerClass" );
    l_Class.lpfnWndProc = WndProc;
    l_Class.hbrBackground = NULL;
    l_Class.hCursor = NULL;
    l_Class.hIcon = NULL;
    l_Class.hIconSm = NULL;
    l_Class.lpszMenuName = NULL;
    l_Class.cbClsExtra = 0;
    l_Class.cbWndExtra = 0;

    if( !RegisterClassEx( &l_Class ) )
        return;

    // Create window
    m_window = CreateWindow
    (
        TEXT( "DogadjajCHandlerClass" ),
        TEXT( "DogadjajCHandler" ),
        WS_POPUP,
        0, 0, 0, 0,
        NULL,
        NULL,
        0,
        NULL
    );

    if( !m_window )
        return;

    // Set this pointer
    SetWindowLong( m_window, GWL_USERDATA, (LONG) this );

}

void DogadjajCHandler::disable()
{
    /*test*/
    printf("    C: disable\n");

    PostThreadMessage( g_DogadjajCThread, WM_CLICK, disableCode, (LPARAM)
this );
}

void DogadjajCHandler::fireClicked()
{
    /*test*/
    printf("C: DogadjajCHandler-disable\n");

    g_DogadjajCThread.m_env->CallVoidMethod( m_object, m_fireClicked );
}

LRESULT CALLBACK DogadjajCHandler::WndProc( HWND hWnd, UINT uMessage,
WPARAM wParam, LPARAM lParam )
{
    /*test*/
    printf("    C: WndProc\n");

    // Check for our special notification message
    if( ( uMessage == WM_MOUSE_CLICK ) && ( INT(lParam) == WM_LBUTTONDOWN
) )
    {
        DogadjajCHandler *l_this = (DogadjajCHandler *) GetWindowLong( hWnd,
GWL_USERDATA );

        // Click!
        l_this->fireClicked();

        return 0;
    }
    else
        return DefWindowProc( hWnd, uMessage, wParam, lParam );
}

/*****************************************dogadjajCThread.cpp*************************************/
#include "stdafx.h"
#include "DogadjajCThread.h"
#include "DogadjajCHandler.h"

DogadjajCThread g_DogadjajCThread;

DogadjajCThread::DogadjajCThread()
{
    /*test*/
    printf("    C: DogadjajCThread-konstruktor\n");

    m_env = NULL;
    m_thread = 0;
    m_vm = NULL;
    m_handlerCount = 0;
}

void DogadjajCThread::MakeSureThreadIsUp( JNIEnv *env )
{
    /*test*/
    printf("    C: MakeSureThreadIsUp\n");

    if( !m_thread )
    {
        // Get VM
        env->GetJavaVM( &m_vm );

        // Start "native" thread
        CreateThread
        (
            NULL,
            0,
            ThreadProc,
            this,
            0,
            &m_thread
        );
    }
}

DogadjajCThread::operator DWORD ()
{
    return m_thread;
}

DWORD WINAPI DogadjajCThread::ThreadProc( LPVOID lpParameter )
{
    /*test*/
    printf("    C: Threadproc\n");

    DogadjajCThread *l_this = (DogadjajCThread *) lpParameter;

    // Attach the thread to the VM
    l_this->m_vm->AttachCurrentThread( (void**) &l_this->m_env, NULL );

    MSG msg;
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        if( msg.message == WM_CLICK )
        {
            // Extract handler
            DogadjajCHandler *l_handler = (DogadjajCHandler*) msg.lParam;

            switch( msg.wParam )
            {
            case DogadjajCHandler::enableCode:

                l_this->m_handlerCount++;
                l_handler->doEnable();
                break;

            case DogadjajCHandler::disableCode:

                // Destroy it!
                delete l_handler;

                // No more handlers?
                if( !--l_this->m_handlerCount )
                {
                    l_this->m_thread = 0;

                    // Detach thread from VM
                    l_this->m_vm->DetachCurrentThread();

                    // Time to die
                    ExitThread( 0 );
                }
                break;
            }
        }
        else
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }

    // Detach thread from VM
    l_this->m_vm->DetachCurrentThread();

    return 0;
}

I compile all the files as well, but when I run Dogadjajavatest I am
getting
      See the mouse> Click it!
line and no reaction. So I have to terminate my program. Does anyone
have any idea what is going on and why this is happening?
Thanks!
Gordon Beaton - 19 Dec 2005 18:36 GMT
> Hi all, I've already been here with similar topic but I need your
> help again. I wrote the code that should be catch an event like
> "left button of mouse clicked", using java JNI and C. I wrote it by
> following the Desktop Indicator sample I've found on Internet. here
> is the code:

You are truly an optimist if you expect someone to read through the
530 lines of code (that you "found on Internet") to find an error
you've only described as "doesn't work".

I suggest you return to the place you found it and ask the author. Or
reduce the problem significantly and provide a better description of
what happens, and what you've done to try to analyze the problem.

/gordon

Signature

[  do not email me copies of your followups  ]
g o r d o n + n e w s @  b a l d e r 1 3 . s e

ginjasvinja - 20 Dec 2005 07:12 GMT
I am not an optimist I am desperate.The code from Internet is much
longer and working fine. My code does not work as well. I and I
expected that someone will recognize the problem he/she had and give
some advice.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.