2015-05-03 2 views
0

Я пытаюсь выполнить JESS .clp-файл при нажатии кнопки с помощью Rete.batch() в Java. Пробная попытка .clp im похожа на пример помощника по ремонту компьютеров в примерах Джесса - с графическим интерфейсом. Когда im исполняет файл внутри ActionListener кнопки, я получаю фрейм, но с пустым окном. Однако, если я выполняю файл в main, не помещая его в ActionListeners, он отлично работает (кадр отображается с содержимым). Любая помощь приветствуется. Благодарю.JESS - .CLP файл не работает должным образом с помощью ActionListener

Код для кнопки действий Listener:

JButton btnEnterNew = new JButton("Take Test!"); 
     btnEnterNew.setBounds(312, 439, 250, 30); 
     contentPane.add(btnEnterNew); 
     btnEnterNew.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent arg0) { 
       Rete ret = new Rete(); 
       try { 
        ret.batch("computer.clp");     

       } catch (JessException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 

Код для Computer.clp: -

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; Graphical version of PC Diagnostic Assistant from part 4 of 
;; "Jess in Action" 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

;; Import some commonly-used classes 
(import javax.swing.*) 
(import java.awt.*) 
(import java.awt.event.*) 

;; Don't clear defglobals on (reset) 
(set-reset-globals FALSE) 

(defglobal ?*crlf* = " 
") 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; Question and answer templates 

(deftemplate question 
    (slot text) 
    (slot type) 
    (multislot valid) 
    (slot ident)) 

(deftemplate answer 
    (slot ident) 
    (slot text)) 

(do-backward-chaining answer) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; Module trigger 

(defmodule trigger) 

(defrule trigger::supply-answers 
    (declare (auto-focus TRUE)) 
    (MAIN::need-answer (ident ?id)) 
    (not (MAIN::answer (ident ?id))) 
    (not (MAIN::ask ?)) 
    => 
    (assert (MAIN::ask ?id)) 
    (return)) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; power rules 

(defrule MAIN::not-plugged-in 
    (declare (auto-focus TRUE)) 
    (answer (ident sound) (text no)) 
    (answer (ident plugged-in) (text no)) 
    => 
    (recommend-action "plug in the computer") 
    (halt)) 

(defrule MAIN::power-supply-broken 
    (declare (auto-focus TRUE)) 
    (answer (ident sound) (text no)) 
    (answer (ident plugged-in) (text yes)) 
    => 
    (recommend-action "repair or replace power supply") 
    (halt)) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; sound rules 

(defrule MAIN::check-ram 
    (declare (auto-focus TRUE)) 
    (answer (ident sound) (text yes)) 
    (answer (ident seek) (text no)) 
    (answer (ident does-beep) (text yes)) 
    (answer (ident how-many-beeps) (text ?t)) 
    (test (< (integer ?t) 3)) 
    => 
    (assert (check loose-ram)) 
    (recommend-action "check for loose RAM, then continue")) 

(defrule MAIN::unknown-sound 
    (declare (auto-focus TRUE)) 
    (answer (ident sound) (text yes)) 
    (answer (ident seek) (text no)) 
    (answer (ident does-beep) (text no)) 
    => 
    (recommend-action "consult a human expert") 
    (halt)) 

(defrule MAIN::motherboard-or-keyboard 
    (declare (auto-focus TRUE)) 
    (answer (ident sound) (text yes)) 
    (answer (ident seek) (text no)) 
    (answer (ident does-beep) (text yes)) 
    (answer (ident how-many-beeps) (text ?t)) 
    (test (>= (integer ?t) 3)) 
    => 
    (recommend-action "check keyboard and motherboard") 
    (halt)) 

(defrule MAIN::no-boot-start 
    (declare (auto-focus TRUE)) 
    (answer (ident sound) (text yes)) 
    (answer (ident seek) (text yes)) 
    (answer (ident boot-begins) (text no)) 
    => 
    (recommend-action "check keyboard, RAM, motherboard, and power supply") 
    (halt)) 

(defrule MAIN::boot-start 
    (declare (auto-focus TRUE)) 
    (answer (ident sound) (text yes)) 
    (answer (ident seek) (text yes)) 
    (answer (ident boot-begins) (text yes)) 
    => 
    (recommend-action "consult a software expert") 
    (halt)) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; RAM rules 

(defrule MAIN::loose-ram 
    (declare (auto-focus TRUE)) 
    (check loose-ram) 
    (answer (ident loose-ram) (text yes)) 
    => 
    (recommend-action "remove and reseat memory modules") 
    (halt)) 

(defrule MAIN::faulty-ram 
    (declare (auto-focus TRUE)) 
    (check loose-ram) 
    (answer (ident loose-ram) (text no)) 
    => 
    (recommend-action "replace memory modules one by one and retest") 
    (halt)) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; domain rules 

(defrule MAIN::right-architecture 
    (declare (auto-focus TRUE)) 
    (explicit (answer (ident hardware) (text ~x86))) 
    => 
    (recommend-action "consult a human expert") 
    (halt)) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; Results output 

(deffunction recommend-action (?action) 
    "Give final instructions to the user" 
    (call JOptionPane showMessageDialog ?*frame* 
     (str-cat "I recommend that you " ?action) 
     "Recommendation" 
     (get-member JOptionPane INFORMATION_MESSAGE))) 

(defadvice before halt (?*qfield* setText "Close window to exit")) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; Module ask 

(defmodule ask) 

(deffunction ask-user (?question ?type ?valid) 
    "Set up the GUI to ask a question" 
    (?*qfield* setText ?question) 
    (?*apanel* removeAll) 
    (if (eq ?type multi) then 
    (?*apanel* add ?*acombo*) 
    (?*apanel* add ?*acombo-ok*) 
    (?*acombo* removeAllItems) 
    (foreach ?item ?valid 
      (?*acombo* addItem ?item)) 
    else 
    (?*apanel* add ?*afield*) 
    (?*apanel* add ?*afield-ok*) 
    (?*afield* setText "")) 
    (?*apanel* validate) 
    (?*apanel* repaint)) 

(deffunction is-of-type (?answer ?type ?valid) 
    "Check that the answer has the right form" 
    (if (eq ?type multi) then 
    (foreach ?item ?valid 
      (if (eq (sym-cat ?answer) (sym-cat ?item)) then 
       (return TRUE))) 
    (return FALSE)) 

    (if (eq ?type number) then 
    (return (is-a-number ?answer))) 

    ;; plain text 
    (return (> (str-length ?answer) 0))) 

(deffunction is-a-number (?value) 
    (try 
    (integer ?value) 
    (return TRUE) 
    catch 
    (return FALSE))) 

(defrule ask::ask-question-by-id 
    "Given the identifier of a question, ask it" 
    (declare (auto-focus TRUE)) 
    (MAIN::question (ident ?id) (text ?text) (valid $?valid) (type ?type)) 
    (not (MAIN::answer (ident ?id))) 
    (MAIN::ask ?id) 
    => 
    (ask-user ?text ?type ?valid) 
    (engine)) 

(defrule ask::collect-user-input 
    "Check an answer returned from the GUI, and optionally return it" 
    (declare (auto-focus TRUE)) 
    (MAIN::question (ident ?id) (text ?text) (type ?type) (valid $?valid)) 
    (not (MAIN::answer (ident ?id))) 
    ?user <- (user-input ?input) 
    ?ask <- (MAIN::ask ?id) 
    => 
    (if (is-of-type ?input ?type ?valid) then 
    (retract ?ask ?user) 
    (assert (MAIN::answer (ident ?id) (text ?input))) 
    (return) 
    else 
    (retract ?ask ?user) 
    (assert (MAIN::ask ?id)))) 

;; Main window 
(defglobal ?*frame* = (new JFrame "Diagnostic Assistant")) 
(?*frame* setDefaultCloseOperation (get-member JFrame EXIT_ON_CLOSE)) 
(?*frame* setSize 520 140) 
(?*frame* setVisible TRUE) 

;; Question field 
(defglobal ?*qfield* = (new JTextArea 5 40)) 
(bind ?scroll (new JScrollPane ?*qfield*)) 
((?*frame* getContentPane) add ?scroll) 
(?*qfield* setText "Please wait...") 

;; Answer area 
(defglobal ?*apanel* = (new JPanel)) 
(defglobal ?*afield* = (new JTextField 40)) 
(defglobal ?*afield-ok* = (new JButton OK)) 

(defglobal ?*acombo* = (new JComboBox (create$ "yes" "no"))) 
(defglobal ?*acombo-ok* = (new JButton OK)) 

(?*apanel* add ?*afield*) 
(?*apanel* add ?*afield-ok*) 
((?*frame* getContentPane) add ?*apanel* (get-member BorderLayout SOUTH)) 
(?*frame* validate) 
(?*frame* repaint) 

(deffunction read-input (?EVENT) 
    "An event handler for the user input field" 
    (assert (ask::user-input (sym-cat (?*afield* getText))))) 

(bind ?handler (new jess.awt.ActionListener read-input (engine))) 
(?*afield* addActionListener ?handler) 
(?*afield-ok* addActionListener ?handler) 

(deffunction combo-input (?EVENT) 
    "An event handler for the combo box" 
    (assert (ask::user-input (sym-cat (?*acombo* getSelectedItem))))) 

(bind ?handler (new jess.awt.ActionListener combo-input (engine))) 
(?*acombo-ok* addActionListener ?handler) 

(deffacts MAIN::question-data 
    (question (ident hardware) (type multi) (valid x86 Macintosh other) 
      (text "What kind of hardware is it?")) 
    (question (ident sound) (type multi) (valid yes no) 
      (text "Does the computer make any sound?")) 
    (question (ident plugged-in) (type multi) (valid yes no) 
      (text "Is the computer plugged in?")) 
    (question (ident seek) (type multi) (valid yes no) 
      (text "Does the disk make \"seeking\" sounds?")) 
    (question (ident does-beep) (type multi) (valid yes no) 
      (text "Does the computer beep?")) 
    (question (ident how-many-beeps) (type number) (valid) 
      (text "How many times does it beep?")) 
    (question (ident loose-ram) (type multi) (valid yes no) 
      (text "Are any of the memory modules loose?")) 
    (question (ident boot-begins) (type multi) (valid yes no) 
      (text "Does the computer begin to boot?")) 
    (ask hardware)) 


(reset) 
(run-until-halt) 
+0

Полный комплект кода, воспроизводящий возникшую у вас проблему, требуется. «Подобный» не помогает, и я не думаю, что могу даже определить «пример Джесса» из вашего описания. (Есть предмет, называемый «путь» для идентификации файлов ...) – laune

+0

Привет, извините, что ... добавил код. Путь правильный, и он даже выполняет файл .clp. Но содержимое внутри кадра не отображается, когда оно выполняется с помощью ActionListener. Мой поиск по этому до сих пор обнаружил его из-за вызова «waitForActivations» рядом с движком - причина в следующем коде. (defrule ask :: ask-question-by-id «С учетом идентификатора вопроса, спросите его» ............ (not (MAIN :: answer (ident? идентификатор))) (MAIN :: спрашивает? идентификатор) => (ASK-пользователь? текст? вид? действительный) ((моторный) waitForActivations)) до сих пор не может найти работу вокруг этого ... – DeeCode

+0

Этот код содержит ошибки. Нет такого конструктора для JCheckBox, как это происходит здесь. А как насчет HTML-тегов '' и ''? – laune

ответ

1

Вызов RETE выполнить затянувшийся пакетный файл замерзает графическую систему - обработчик события кнопки является обратным вызовом. Отсоедините поток для выполнения метода Rete, например.

public void actionPerformed(ActionEvent e) { 
    Runnable r = new Runnable() { 
     public void run() { 
      Rete ret = new Rete(); 
      try { 
       ret.batch("computer.clp");     
      } catch (JessException je) { 
       je.printStackTrace(); 
      }   
     } 
    }; 
    new Thread(r).start(); 
} 
+0

Спасибо ... Его работа отлично! – DeeCode