Hi, I think i will use another approach:
I wrote a terminal for octave in java. This terminal is also a server.
Another java object (e.g. Action Listener of a JButton) can send a command
to the terminal via socket communication. And the Terminal executes the
received commands.
So my "action loop" works like this:
{java0: Terminal=Server} =controlls=> {Octave} =creates=> {java1: Java
Objects} =having a=> {java3: Listener} =controlls=> {java0: Terminal} =>...
I post my code below. It has to be further improved, but it works in
principle.
If you know a more elegant way to execute octave commands as result of
defined java actions, please post it here.
Solutions on how to use the listen() and socket() commands or some kind of
octave api to get a shorter action loop are also welcome.
I think my approach is quite powerfull for writing interactive GUIs with
Octave and Java.
To test it:
-put all files (see source code below) in a folder
-change the octave path in OctaveTerminal.java
-compile the Java Classes
javac OctaveTerminal.java
javac Action.java
-run the Octave Terminal
java OctaveTerminal
-enter the Command "UserGUI" in the Textfield to start UserGUI.m
Have Fun!
http://octave.1599824.n4.nabble.com/file/n3027214/callback.m callback.m
http://octave.1599824.n4.nabble.com/file/n3027214/UserGUI.m UserGUI.m
http://octave.1599824.n4.nabble.com/file/n3027214/OctaveTerminal.java
OctaveTerminal.java
http://octave.1599824.n4.nabble.com/file/n3027214/OctaveTerminal.class
OctaveTerminal.class
http://octave.1599824.n4.nabble.com/file/n3027214/OctaveTerminal%241.class
OctaveTerminal%241.class
http://octave.1599824.n4.nabble.com/file/n3027214/OctaveTerminal%24ClientWorker.class
OctaveTerminal%24ClientWorker.class
http://octave.1599824.n4.nabble.com/file/n3027214/Action.java Action.java
http://octave.1599824.n4.nabble.com/file/n3027214/Action.class Action.class
Here is an example for a callback action that will be performed:
callback.m
=================================================================
function callback(n)
resultOfCallback = n
endfunction
=================================================================
Here is a user defined GUI with two JButtons:
UserGUI.m
=================================================================
%load java package
pkg load java
javaaddpath(".");
%create JFrame
JFrameObj=java_new("javax.swing.JFrame");
Dimension = java_new("java.awt.Dimension",200, 100);
JFrameObj.setSize(Dimension);
JFrameObj.setLocation(100,100);
%create a JPanel
JPanelObj=java_new("javax.swing.JPanel");
%add a JButton
JButtonObj1=java_new("javax.swing.JButton","Click me1");
%add Action Listener to the JButton
ActionObj1=java_new("Action",{"callback","1"});
JButtonObj1.addActionListener(ActionObj1);
JPanelObj.add(JButtonObj1);
%add a second JButton
JButtonObj2=java_new("javax.swing.JButton","Click me2");
%add Action Listener to the JButton
ActionObj2=java_new("Action",{"callback","2"});
JButtonObj2.addActionListener(ActionObj2);
JPanelObj.add(JButtonObj2);
%put JPanelObj on JFrame
JFrameObj.add(JPanelObj);
%request Focus for the JButton
%JButtonObj.requestFocus();
%Show the JFrame
JFrameObj.show();
=================================================================
Here is the java source code of my Action Listener class
Action.java
=================================================================
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.net.*;
public class Action implements ActionListener {
public String[] args;
public String commandString;
public PrintWriter pw=null;
public Socket ClientSocket = null;
public BufferedReader ServerReader = null;
public PrintWriter ServerWriter = null;
public Action(String[] arguments) {
//create command string from argument array
args=arguments;
commandString=args[0];
if (args.length>1){
commandString =commandString+"(";
for (int i=1; i<args.length; ++i) {
commandString = commandString+args[i];
if (i<args.length-1){
commandString = commandString+", ";
}
}
commandString=commandString+")";
}
//connect to Octave Terminal Server
try {
InetAddress addr = InetAddress.getLocalHost(); // Get IP Address
byte[] ipAddr = addr.getAddress(); // Get hostname
String hostname = addr.getHostName();
ClientSocket = new Socket(hostname, 4444);
ServerReader = new BufferedReader(new
InputStreamReader(ClientSocket.getInputStream()));
ServerWriter = new PrintWriter(ClientSocket.getOutputStream(), true);
} catch (UnknownHostException e) {
System.err.println("Don't know about host.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to Octave
Terminal.");
System.exit(1);
}
}
public void actionPerformed(ActionEvent actionEvent) {
//send Command
ServerWriter.println(commandString);
}
public void eval(String command){
//send Command
ServerWriter.println(command);
}
public void test() throws IOException {
JOptionPane.showMessageDialog(null, commandString, "Info",
JOptionPane.OK_CANCEL_OPTION);
}
public void closeClient(){
ServerWriter.println("OctaveTerminal_EndClient");
}
public void finalize(){
//Tetermine Client Socket
try{
ServerWriter.close();
ServerReader.close();
ClientSocket.close();
} catch (IOException e) {
System.out.println("Could not close Action Client.");
System.exit(-1);
}
}
}
=================================================================
And here is the java source code of the Octave Terminal
OctaveTerminal.java
=================================================================
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.net.*;
public class OctaveTerminal extends JFrame implements ActionListener{
public String octavepath = "C:\\Octave\\3.2.4_gcc-4.4.0\\bin\\octave.exe
--persist";
public JTextArea outputTextArea = new JTextArea(25, 60);
public JTextField TextField;
public String nextLine;
public int lineNumber=1;
public String commandString;
public String outputText;
public String errorText;
public PrintWriter pw=null;
public InputStream outputstream=null;
public BufferedReader boutput=null;
public InputStream errorstream=null;
public BufferedReader berror=null;
public Runtime r=null;
public Process p=null;
public Boolean listenflag = true;
public ServerSocket server = null;
public Socket client = null;
public BufferedReader ClientReader = null;
public PrintWriter ClientWriter = null;
public InputStream ClientStream = null;
public String ClientCommandString;
public OctaveTerminal () throws IOException{
//Set textarea's initial text and put it in a scroll pane
outputTextArea.setText("Welcome to Octave Terminal!\n");
int v = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
int h = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
JScrollPane scroller = new JScrollPane(outputTextArea,v,h);
//Create a content pane, set layout, add scroller to center
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(scroller, BorderLayout.CENTER);
//Create TextField and add it
TextField = new JTextField("");
TextField.addActionListener(this);
content.add(TextField, BorderLayout.PAGE_END);
//Add the content to the frame and set frame properties
this.setContentPane(content);
this.setTitle("Octave Terminal");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setLocation(100, 100);
//Execute Octave
Runtime r = Runtime.getRuntime();
p = r.exec(octavepath);
try {
//Create input, output and error stream
pw = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(p.getOutputStream())),true);
outputstream = p.getInputStream();
boutput = new BufferedReader(new InputStreamReader(outputstream));
errorstream = p.getErrorStream();
berror = new BufferedReader(new InputStreamReader(errorstream));
//write output to text area
nextLine = boutput.readLine();
if (nextLine!=null)
outputTextArea.append(nextLine+"\n");
while(boutput.ready()){
nextLine = boutput.readLine();
outputTextArea.append(nextLine+"\n");
}
//write errors to text area
nextLine = berror.readLine();
if (nextLine!=null)
outputTextArea.append(nextLine+"\n");
while(berror.ready()){
nextLine = berror.readLine();
outputTextArea.append(nextLine+"\n");
}
//System.out.println("Bytes in output: "+outputstream.available());
//System.out.println("Bytes in error: "+outputstream.available());
//set curser to text field
TextField.requestFocus();
}catch (Exception e) {
System.out.println("Error writing to output stream " + e);
e.printStackTrace();
}
//add closing action
WindowListener wlisten = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
this.addWindowListener(wlisten);
//show frame
this.setVisible(true);
}
public void actionPerformed(ActionEvent evt) {
Object ActionSource = evt.getSource();
if(ActionSource == TextField){
//get text
commandString = TextField.getText();
//write text to text area
outputTextArea.append("#"+lineNumber+">"+commandString + "\n");
//increas line number
lineNumber=lineNumber+1;
//run commandString as Octave Command
runOctaveCommand(commandString);
}
//run action commandString
//Terminal.runOctaveActionCommand(commandString);
//System.out.println("actionPerformed");
}
public static void main (String args[]) throws IOException {
//create Terminal
OctaveTerminal Terminal = new OctaveTerminal();
//Listen to Socket
Terminal.startSocketListener();
}
public void startSocketListener(){
//System.out.println("listenOk");
//create Socket Server
try {
server = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Could not listen on port: 4444.");
System.exit(1);
}
//System.out.println("serverOk");
//Wait to accept Clients
while(listenflag){
ClientWorker w;
try{
w = new ClientWorker(server.accept(), outputTextArea);
Thread t = new Thread(w);
t.start();
//System.out.println("acceptOk");
}catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
}//end of while(listenflag) loop
}
public void stopSocketListener(){
listenflag = false;
}
public class ClientWorker implements Runnable {
private Socket client;
private JTextArea outputTextArea;
ClientWorker(Socket client, JTextArea outputTextArea) {
this.client = client;
this.outputTextArea = outputTextArea;
}
public void run(){
String commandString="OctaveClientError=1";
BufferedReader in = null;
PrintWriter out = null;
try{
in = new BufferedReader(new
InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("in or out failed");
System.exit(-1);
}
while(true){
try{
//read data from client
commandString = in.readLine();
if (commandString.equals("OctaveTerminal_EndClient")){
break;
}
//outputTextArea.append("Action>" + commandString + "\n");
runOctaveCommand(commandString);
}catch (IOException e) {
System.out.println("Failed to read from Client!");
System.exit(-1);
}
//Send data back to client
out.println(commandString);
}//end of while(true) loop
try{
in.close();
out.close();
client.close();
}catch (IOException e) {
System.out.println("Failed to close Client!");
System.exit(-1);
}
}
}
public void runOctaveActionCommand(String command) {
outputTextArea.append("Action>"+command+"\n");
runOctaveCommand(command);
}
public void runOctaveCommand(String command) {
try {
//execute command
pw.println(command);
//wait until Octave has finished the command execution and read streams
int Bytes =1;
int n=0;
int n1=0;
int n2=1;
int en=0;
int en1=0;
int en2=1;
int outputflag=0;
int errorflag=0;
outputText="";
errorText="";
while (Bytes>0){
//Wait until available Bytes of output are constant
while(n1!=n2){
n1 = outputstream.available();
Thread.sleep(500);
n2 = outputstream.available();
}
//read octave output
if (n2>0){
byte buf[] = new byte[128];
int bn = outputstream.read(buf);
outputText = outputText + new String(buf);
n=n+bn;
//System.out.println("String: "+ outputText +"\n");
outputflag = 1;
}
//Wait until available Bytes of error are constant
while(en1!=en2){
en1 = errorstream.available();
Thread.sleep(500);
en2 = errorstream.available();
}
//read octave errors
if (en2>0){
byte buf[] = new byte[128];
int bn= errorstream.read(buf);
errorText = errorText + new String(buf);
en = en+bn;
//System.out.println("String: "+ errorText +"\n");
errorflag=1;
}
//check again if all Octave output could be read
Bytes = outputstream.available();
if (Bytes==0){
Bytes = errorstream.available();
}
}
//add output to text area
if (outputflag==1){
//cut octave seperator
outputText=outputText.substring(0,n-1);
//write octave output to text area
outputTextArea.append(outputText+"\n");
}
//add errors to text area
if (errorflag==1){
//cut octave seperator
errorText=errorText.substring(0,en-1);
//write octave output to text area
outputTextArea.append(errorText+"\n");
}
//set curser to end of text area
outputTextArea.setCaretPosition(outputTextArea.getDocument().getLength());
//clear text field
TextField.setText("");
}catch (Exception e) {
System.out.println("Error writing to output stream " + e);
e.printStackTrace();
}
}
protected void finalize(){
//Clean up
try{
listenflag = false;
server.close();
}catch (IOException e) {
System.out.println("Could not close Server.");
System.exit(-1);
}
}
} http://octave.1599824.n4.nabble.com/file/n3027214/Action.java Action.java
=================================================================
--
View this message in context: http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps-with-octave-tp2019418p3027214.html
Sent from the Octave - General mailing list archive at Nabble.com.