Próba wywołania kodu Javy z LogTalka. Mimo iż modul jpl bardzo dobrze się sprawdza przy tworzeniu obiektów Javy, wywoływany z standardowego kodu Prolog'a jak widać np w tym przykładzie :
:-use_module(library(jpl)).
jpl_test:-
jpl_new('javax.swing.JFrame', ['Frame with dialog'], F),
jpl_call(F, setLocation, [400, 300], _),
jpl_call(F, setSize, [400, 300], _),
jpl_call(F, setVisible, [@(true)], _),
jpl_call(F, toFront, [], _),
jpl_call('javax.swing.JOptionPane', showInputDialog, [F, 'Write sth'], N),
jpl_call(F, dispose, [], _),
( N == @(null) ->
write('You cancelled');
write('You typed'), write(N)
),
nl.
:-jpl_test.
Działa bez zarzutu, wyświetlając okienko dialogowe. Ale już próba uruchomienia podobnego kodu w metodzie obiektu LogTalk:
:-use_module(library(jpl),[jpl_new/3, jpl_call/4]).
:-object(logTalkControler).
:-public(toString/0).
:-public(testValue/1).
:-public(jpl_test/0).
:-initialization(
write('Constructor speaking')).
test(a).
test(b).
test(c).
value(a).
testValue(X) :-
test(X),
value(X).
jpl_test:-
jpl_new('javax.swing.JFrame', ['Frame with dialog'], F),
jpl_call(F, setLocation, [400, 300], _),
jpl_call(F, setSize, [400, 300], _),
jpl_call(F, setVisible, [@(true)], _),
jpl_call(F, toFront, [], _).
:-end_object.
Powoduje dość ciekawy komunikat przy próbie kompilacji w swi :
63 ?- logtalk_load(logTalkControler).
<<< reloading source file logTalkControler...
>>> compiling source file logTalkControler...
compiling object logTalkControler...
WARNING! These predicates are called but never defined: jpl_call/4, jpl_new/3
compiled object logTalkControler...
>>> logTalkControler source file compiled
WARNING! Redefining object logTalkControler
Constructor speaking
% logTalkControler.pl compiled 0.00 sec, 92 bytes
<<< logTalkControler source file reloaded
(1 compilation warning and 1 loading warning)
true.
64 ?- logTalkControler::jpl_test.
ERROR: Undefined procedure: jpl_new/3
ERROR: However, there are definitions for:
ERROR: jpl_new/3
I oczywiście nie działa. Podejrzewam, że problem tkwi w niewłaściwie dodanym pakiecie. Ale nie udało mi się jeszcze znaleźć rozwiązania..
Rozwiązaniem problemu z jest stosunkowo proste, mianowicie do wywoływania metod z pakietu należy użyć operatora {}/1. Inaczej LogTalk próbuje jakoś zrobić z modułu obiekt i nie zawsze to działa.
Także poprawne wywołanie wygląda tak :
jpl_test:-
{ jpl_new('javax.swing.JFrame', ['Frame with dialog'], F) },
A poniżej działający już poniższy przykład :
:-use_module(library(jpl),[jpl_new/3, jpl_call/4]).
:-object(logTalkControler).
:-public(toString/0).
:-public(testValue/1).
:-public(jpl_test/0).
:-initialization(
write('Constructor speaking')).
test(a).
test(b).
test(c).
value(a).
testValue(X) :-
test(X),
value(X).
jpl_test:-
{jpl_new('javax.swing.JFrame', ['Frame with dialog'], F)},
{jpl_call(F, setLocation, [400, 300], _)},
{jpl_call(F, setSize, [400, 300], _)},
{jpl_call(F, setVisible, [@(true)], _)},
{jpl_call(F, toFront, [], _)}.
:-end_object.