Discussion:
Best way to create interactive GUI apps with octave?
Miguel Bazdresch
2010-04-21 18:25:12 UTC
Permalink
Hello,

What is the best way to create interactive GUI apps with octave? For
example, I would like to have a window with three sliders controlling
the amplitude, frequency and phase of a cosine that is plotted below
the sliders. The purpose would be to make visually attractive demos
for my students.

So far, I have come up with these options:

* create a C++ application using octave as a library, and a C++ GUI
package such as Qt
* use gtk-server (http://www.gtk-server.org/)
* a couple of old and apparently unmaintained projects I found with
google, such as octave-gtk and octave-fltk

I could also, of course, do this in scipy or scilab, but I would
really like to do this with octave, since this is the language my
students know best.

Does anyone have tips or experience to share? Are there alternatives I
am missing? Will the new FLTK backend work for this purpose? (I have
found precious little information on this new backend).

Cheers,
--
Miguel Bazdresch
Jaroslav Hajek
2010-04-22 04:31:47 UTC
Permalink
Post by Miguel Bazdresch
Hello,
What is the best way to create interactive GUI apps with octave? For
example, I would like to have a window with three sliders controlling
the amplitude, frequency and phase of a cosine that is plotted below
the sliders. The purpose would be to make visually attractive demos
for my students.
* create a C++ application using octave as a library, and a C++ GUI
package such as Qt
* use gtk-server (http://www.gtk-server.org/)
* a couple of old and apparently unmaintained projects I found with
google, such as octave-gtk and octave-fltk
* make a gui app in Python (with one of those dozens of Python GUI
toolkits) and embed Octave using Pytave
(https://launchpad.net/pytave). Pytave uses NumPy so you'd be able to
actually mix Octave with SciPy pretty easily.

Note, however, that if you want to do the plotting via Octave, there's
probably no way to attach buttons to the plot windows.

hth
--
RNDr. Jaroslav Hajek, PhD
computing expert & GNU Octave developer
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz
Carlo de Falco
2010-04-22 05:20:57 UTC
Permalink
On Wed, Apr 21, 2010 at 8:25 PM, Miguel Bazdresch
Post by Miguel Bazdresch
Hello,
What is the best way to create interactive GUI apps with octave? For
example, I would like to have a window with three sliders controlling
the amplitude, frequency and phase of a cosine that is plotted below
the sliders. The purpose would be to make visually attractive demos
for my students.
* create a C++ application using octave as a library, and a C++ GUI
package such as Qt
* use gtk-server (http://www.gtk-server.org/)
* a couple of old and apparently unmaintained projects I found with
google, such as octave-gtk and octave-fltk
* make a gui app in Python (with one of those dozens of Python GUI
toolkits) and embed Octave using Pytave
(https://launchpad.net/pytave). Pytave uses NumPy so you'd be able to
actually mix Octave with SciPy pretty easily.
and why not
* write the gui app in C/C++ and wrap it into an oct file
?
Note, however, that if you want to do the plotting via Octave, there's
probably no way to attach buttons to the plot windows.
hth
c.
Riccardo Corradini
2010-04-22 07:59:30 UTC
Permalink
Hi,
may I suggest you to use Gambas (http://gambas.sourceforge.net/en/main.html)?
You don't need to use C++ and more over Basic is easier.
It has also a nice visual debugger for your students.
I think you may build a straightforward example and then post it to octave-forge if you want.
Best regards
Riccardo Corradini

--- Mer 21/4/10, Miguel Bazdresch <***@gmail.com> ha scritto:

Da: Miguel Bazdresch <***@gmail.com>
Oggetto: Best way to create interactive GUI apps with octave?
A: help-***@octave.org
Data: Mercoledì 21 Aprile 2010, 20:25

Hello,

What is the best way to create interactive GUI apps with octave? For
example, I would like to have a window with three sliders controlling
the amplitude, frequency and phase of a cosine that is plotted below
the sliders. The purpose would be to make visually attractive demos
for my students.

So far, I have come up with these options:

* create a C++ application using octave as a library, and a C++ GUI
package such as Qt
* use gtk-server (http://www.gtk-server.org/)
* a couple of old and apparently unmaintained projects I found with
google, such as octave-gtk and octave-fltk

I could also, of course, do this in scipy or scilab, but I would
really like to do this with octave, since this is the language my
students know best.

Does anyone have tips or experience to share? Are there alternatives I
am missing? Will the new FLTK backend work for this purpose? (I have
found precious little information on this new backend).

Cheers,
--
Miguel Bazdresch
Carlo de Falco
2010-04-22 10:44:00 UTC
Permalink
Post by Riccardo Corradini
Hi,
may I suggest you to use Gambas (http://gambas.sourceforge.net/en/main.html)?
You don't need to use C++ and more over Basic is easier.
It has also a nice visual debugger for your students.
I think you may build a straightforward example and then post it to
octave-forge if you want.
Best regards
Riccardo Corradini
Gambas looks cool indeed, but how do you interface it with Octave?
Have you ever done that yourself?
I would be very interested in seeing an example if you have one.
c.
Riccardo Corradini
2010-04-22 12:00:21 UTC
Permalink
Sure,
but the example is not mine
'cause is taken from
http://forum.ubuntu-it.org/index.php?topic=111537.msg756738

PUBLIC processo AS Process

PUBLIC SUB Form_Open()

  StartOctave()

END

PUBLIC SUB Process_Read()

  DIM sLine AS String
 
  READ #processo, sLine, - Lof(processo)
 
  Terminale.Text = Terminale.Text & sLine

END

PUBLIC SUB StartOctave()
 
  Processo = SHELL "octave" FOR INPUT OUTPUT
 
END


PUBLIC SUB Button1_Click()

  PRINT #Processo, Comando.Text

END

The  function StartOctave  runs the process and links pipes (Processo = SHELL "octave" FOR INPUT OUTPUT)
In this way I can read and write over a process like if it were a file
With the function Button1_Click() I print the commands that the users writes  over
the process (it is a just a sort of terminal)
While Process_Read is the function that controls if there is something to read over the stream process and adds it to text-box "terminale" in order to visualize it.

Hope my rough translation will be useful to the community.
Bests
Riccardo Corradini

--- Gio 22/4/10, Carlo de Falco <***@gmail.com> ha scritto:

Da: Carlo de Falco <***@gmail.com>
Oggetto: Re: R: Best way to create interactive GUI apps with octave?
A: "Riccardo Corradini" <***@yahoo.it>
Cc: "Miguel Bazdresch" <***@gmail.com>, help-***@octave.org
Data: Giovedì 22 Aprile 2010, 12:44
Post by Riccardo Corradini
Hi,
may I suggest you to use Gambas (http://gambas.sourceforge.net/en/main.html)?
You don't need to use C++ and more over Basic is easier.
It has also a nice visual debugger for your students.
I think you may build a straightforward example and then post it to octave-forge if you want.
Best regards
Riccardo Corradini
Gambas looks cool indeed, but how do you interface it with Octave? Have you ever done that yourself?
I would be very interested in seeing an example if you have one.
c.
Miguel Bazdresch
2010-04-22 12:45:28 UTC
Permalink
Thank you all for your suggestions; I had indeed missed quite a few
alternatives. I'll do some more research and report back if I come up with
something interesting.
--
Miguel Bazdresch
forkandwait
2010-04-22 16:21:06 UTC
Permalink
Post by Miguel Bazdresch
Thank you all for your suggestions; I had indeed missed quite a few
alternatives. I'll do some more research and report back if I come up
with something interesting.-- Miguel Bazdresch
Isn't there a Tcl/Tk solution out there too, maybe passing octave commands
through to an interpreter?

Tcl/Tk has a bad rep (Stallman's flip comment and performance issues in 1995)
but it is probably still the quickest way to hack together a GUI, esp in a Unix
environment.
Martin Helm
2010-04-22 17:34:41 UTC
Permalink
Post by Miguel Bazdresch
Thank you all for your suggestions; I had indeed missed quite a few
alternatives. I'll do some more research and report back if I come up with
something interesting.
Just to mention an additional possibility:

You can use the java package from octave forge to interface between octave and
java. It also supports callbacks between java and octave and you can look at
the jhandles package to see how this works.

Just to give a simple idea I attached some (just for fun) code to illustrate
this.

- mh
Martin Helm
2010-04-22 17:37:17 UTC
Permalink
Post by Martin Helm
Post by Miguel Bazdresch
Thank you all for your suggestions; I had indeed missed quite a few
alternatives. I'll do some more research and report back if I come up
with something interesting.
You can use the java package from octave forge to interface between octave
and java. It also supports callbacks between java and octave and you can
look at the jhandles package to see how this works.
Just to give a simple idea I attached some (just for fun) code to
illustrate this.
- mh
Forgot one file.
schnumbl
2010-10-28 14:54:55 UTC
Permalink
Hi,

I tried to run the callback example (with octave 3.2.4_gcc-4.4.0), but the
line

Octave.call(callBack, new Object[]{val}, new Object[] {});

produces an error:

Exception occured during event dispatching: java.lang.UnsatisfiedLink Error:
...

What *.jar files do I have to include to compile the *.java files?

--------

In Matlab it is possible to add an action listener to a java object like
this:

import javax.swing.*;

jb = javax.swing.JButton;
jbh = handle(jb,'CallbackProperties');
set(jbh, 'ActionPerformedCallback',@myMatlabFile)

Is there something similiar in octave for the java package?

Sunny regards,

Stefan
--
View this message in context: http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps-with-octave-tp2019418p3017394.html
Sent from the Octave - General mailing list archive at Nabble.com.
Michael Goffioul
2010-10-29 06:49:07 UTC
Permalink
Post by schnumbl
Hi,
I tried to run the callback example (with octave 3.2.4_gcc-4.4.0), but the
line
Octave.call(callBack, new Object[]{val}, new Object[] {});
...
What *.jar files do I have to include to compile the *.java files?
The error above usually means a failure to find/load a shared library.
Post by schnumbl
In Matlab it is possible to add an action listener to a java object like
import javax.swing.*;
jb = javax.swing.JButton;
jbh = handle(jb,'CallbackProperties');
Is there something similiar in octave for the java package?
No, this is currently not supported.

Michael.
schnumbl
2010-11-01 10:20:20 UTC
Permalink
Thank you for your comments. I am a beginner in octave and the
failure to find a shared library could be due to my environment variable
settings (I use Windows XP). I tried to find the settings with google,
but I am still not sure if they are ok.

Is there a tutorial for setting the environment variables for octave forge?

Some paths I found are with '/' slash and some are with '\'. Sometimes there
is a ";"
as seperator and sometimes not. This is confusing for me, see e.g:
http://www.mail-archive.com/octave-***@lists.sourceforge.net/msg02686.html


Here are my Windows environment variable settings

Windows environment system variables:

CLASSPATH = .
JAVA_HOME = C:\Programme\Java\jdk1.6.0_22
JAVA_INCS = -I:C:\Programme\Java\jdk1.6.0_22\include;
-I:C:\Programme\Java\jdk1.6.0_22\include\win32
PATH = ... ; C:\gnuplot\bin; C:\Programme\Java\jre6\bin;
C:\Octave\3.2.4_gcc-4.4.0\bin

(Hints for beginners like me: You can not directly copy my settings for your
system, but
you might want to add specific paths to your environment variables. Consider
your
specific java installation paths ect.)

- How do I have to adapt these paths?

- Do I need additional environment variables to run the GUI callback
example?

- What is the meaning of the JAVA_INCS variable? (I do not understand the
"-I". Do I have
to use forward or backward slashes? Do I have to use a ";" as separator? How
can I test
if the JAVA_INCS path is correct? Do I need it at all?)

- How can I test if octave knows the native "call" command? Do I have to
include extra *.oct
files as "shared library"?

- Do I have to somehow specify the path to the file "jni.jar" for the java
native interface?

- How can I test if the compilation of the OctSlider.java and the
ExtensionFileFilter.java are ok?


The octave environment variables settings for Windows might be interesting
for other octave users, too.
Here is some general information I found for environment variables (please
correct me if I write something wrong).

===============================================================================================
-There are octave commands to work with environment variables:
+ Show an environment variable, e.g. getenv("PATH");
+ Set an environment variable, e.g.
setenv("DUMMY_PATH","C:/Programme/Java/jdk1.6.0_22");

-The "setenv" command does not affect the (static) Windows Environment
Variables. It changes
only the dynamic Ocatave environtment variable for the current session. (If
you
restart Octave you would have to do the setenv command again.)

-The Windows Environment Variables can be changed as descriped here:
http://vlaurie.com/computers2/Articles/environment.htm

-There are different types of "slashes" or "file sperators" ('/' ,'//' ,'\',
'\\') that
can be used to specify a path. The slash depends on the operation system
and the programming language.

-There is an octave command to get the current file separator.
For my Windows XP system it works like this:

filesep
ans = \

-Windows environment variable names and paths are not case-sensitive
("PATH" is equal to "Path" or "path"). (The environment variables of
other operation systems may be case sensitive.)

-A single environment variable can include several paths. These paths are
seperated
with ";".

-A path can include other environment variables. To include a Windows path
variable,
use "%" signs at the start and at the end of the variable name, e.g.:
%SystemRoot%
(The operating system Unix uses a "$" sign at the start of the variable name
instead of "%" signs.)

-An environement variable may include a single point "." as a path. This
point represents
the current directory. If you run for example the java compiler "javac.exe"
in a directory
"c:\mycodefolder" and the environment variable "CLASSPATH" includes a ".",
the javac.exe will
include the current directory "c:\mycodefolder" to search for java classes.
===============================================================================================

Sunny regards,

Stefan
--
View this message in context: http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps-with-octave-tp2019418p3021958.html
Sent from the Octave - General mailing list archive at Nabble.com.
Michael Goffioul
2010-11-01 13:11:14 UTC
Permalink
Post by schnumbl
Thank you for your comments. I am a beginner in octave and the
failure to find a shared library could be due to my environment variable
settings (I use Windows XP). I tried to find the settings with google,
but I am still not sure if they are ok.
Is there a tutorial for setting the environment variables for octave forge?
Some paths I found are with '/' slash and some are with '\'. Sometimes there
is a ";"
Here are my Windows environment variable settings
CLASSPATH = .
JAVA_HOME = C:\Programme\Java\jdk1.6.0_22
JAVA_INCS = -I:C:\Programme\Java\jdk1.6.0_22\include;
-I:C:\Programme\Java\jdk1.6.0_22\include\win32
PATH = ... ; C:\gnuplot\bin; C:\Programme\Java\jre6\bin;
C:\Octave\3.2.4_gcc-4.4.0\bin
Under windows, you normally don't need these variables. They are computed
automatically from the registry. Moreover some of these variables are only
required if you want to compile the octave java package yourself (like
JAVA_INCS).

Michael.
schnumbl
2010-11-01 13:45:48 UTC
Permalink
Hi Michael,

I refer to the example from Martin Helm (see above, Apr 22, 2010; 07:37pm,
http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps-with-octave-td2019418.html).

Are you able to run his callback example (test_java.m, callback.m,
OctSlider.java, ExtensionFileFilter.java) ?

(I deleted the line "vtk_surf(rand(10));" in test_java.m because my octave
does not know the command.)

Maybe the problem is that the "OctSlider.java" needs something like

static {
System.loadLibrary("LibraryWithTheCallFunction");
}

??

The error message is:

==================================
Exception occurred during event dispatching:
java.lang.UnsatisfiedLinkError:
org.octave.Octave.call(Ljava/lang/String;[Ljava
/lang/Object;[Ljava/lang/Object;)Z
at org.octave.Octave.call(Native Method)
at OctSlider.stateChanged(OctSlider.java:24)
at javax.swing.JSlider.fireStateChanged(Unknown Source)
at javax.swing.JSlider$ModelListener.stateChanged(Unknown Source)
at javax.swing.DefaultBoundedRangeModel.fireStateChanged(Unknown Source)
at javax.swing.DefaultBoundedRangeModel.setRangeProperties(Unknown Source)
at javax.swing.DefaultBoundedRangeModel.setValueIsAdjusting(Unknown Source)
at javax.swing.JSlider.setValueIsAdjusting(Unknown Source)
at javax.swing.plaf.basic.BasicSliderUI$TrackListener.mousePressed(Unknown
Sou
rce)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.Dialog$1.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
===============================================================
--
View this message in context: http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps-with-octave-tp2019418p3022175.html
Sent from the Octave - General mailing list archive at Nabble.com.
Martin Helm
2010-11-01 14:03:32 UTC
Permalink
Post by schnumbl
Hi Michael,
I refer to the example from Martin Helm (see above, Apr 22, 2010; 07:37pm,
http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps
-with-octave-td2019418.html).
Please do not use this example, it is quite old and was done with a 3.0
version (where octaviz still worked -> vtk_surf is from octaviz) of octave and
I do not even remeber which version of the java package.

If you have some patience I can make a hopefully good self contained example
tomorrow evening (german time) and post it here.

- Martin
schnumbl
2010-11-01 14:56:05 UTC
Permalink
Hi Martin,
that would be great!
--
View this message in context: http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps-with-octave-tp2019418p3022266.html
Sent from the Octave - General mailing list archive at Nabble.com.
schnumbl
2010-11-04 11:10:48 UTC
Permalink
Post by Martin Helm
If you have some patience I can make a hopefully good self contained example
tomorrow evening (german time) and post it here.
Hi Martin, did you already give it a try?
Please also give me some feetback if it does not work
with the current Octave version.
--
View this message in context: http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps-with-octave-tp2019418p3026836.html
Sent from the Octave - General mailing list archive at Nabble.com.
schnumbl
2010-11-04 15:22:48 UTC
Permalink
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.
Martin Helm
2010-11-07 15:15:27 UTC
Permalink
Post by schnumbl
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.
Hi since you decided to go the opposite way (java as a master and octave as a
slave) you can probably benefit from two existing projects which use this
approach.

http://kenai.com/projects/javaoctave/pages/Home
http://jopas.sourceforge.net/

The second one I used a little bit 2 or 3 years ago. Maybe it can save you
time to cheat a little bit from that (or you consider to participate in one of
them).
schnumbl
2010-11-19 11:47:42 UTC
Permalink
Thank you for your example and the links.

If i run the OctSlider example on windows xp, the plot and the slider show
up.
Clicking on the slider results in following error:
http://octave.1599824.n4.nabble.com/file/n3050235/error.bmp
--
View this message in context: http://octave.1599824.n4.nabble.com/Best-way-to-create-interactive-GUI-apps-with-octave-tp2019418p3050235.html
Sent from the Octave - General mailing list archive at Nabble.com.
Martin Helm
2010-11-04 21:55:59 UTC
Permalink
Post by schnumbl
Post by Martin Helm
If you have some patience I can make a hopefully good self contained
example tomorrow evening (german time) and post it here.
Hi Martin, did you already give it a try?
Please also give me some feetback if it does not work
with the current Octave version.
Sorry, just came back from a travel half an hour ago which was not planned. It
is 11 p.m. here now, I doubt I will find the energy to do anything today. But I
did not forget it.
Martin Helm
2010-11-07 14:51:50 UTC
Permalink
I meanwhile tested a bit a trivila example for callbacks with the java 1.2.7
package (and octave 3.3.53 - had to change getcwd in __java__.cc to make it
compatible) and it still works as expected on gnu/linux (opensuse 11.3).

I have 3 files, 2 m files (the main script and the callback function) and one
java file

--- begin test_java.m ---

pkg load java
javaaddpath(".");

surf(rand(10));
sleep(0.1);
jd = java_new("javax.swing.JDialog");
sl = java_new("OctSlider", "Slider1", "callback", 0, 359, 0);
jd.add(sl);
jd.setModal(1);
jd.setSize(250, 50);
a = jd.setVisible(1);
disp(a)
pkg unload java

--- end test_java.m ---


--- begin callback.m ---

function callback(n)
[a, b] = view();
view(n, b)
drawnow
endfunction

--- end callback.m ---


--- begin OctSlider.java ---

import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.octave.Octave;


public class OctSlider extends JSlider implements ChangeListener {

private String callBack = "";

public OctSlider(String name, String callBack, int min, int max, int
value){
super(min, max, value);
this.callBack = callBack;
setName(name);
addChangeListener(this);
}

@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() == this && getValueIsAdjusting()) {
int val = (int)getValue();
Octave.call(callBack, new Object[]{val}, new Object[] {});
}
}

}

--- end OctSlider.java ---

all in the same folder for simplicity.
The java file is compiled with
javac -cp /home/martinh/octave/java-1.2.7/octave.jar OctSlider.java

of course on another system the classpath has to be set to the place where
octave.jar is located.

Then run it with "octave test_java.m" or make it an executable script.

It opens a gnuplot window with random surface and creates a java slider which
can be used to rotate the plot in the gnuplot window.

This code is of course not in any way a masterpiece of octave or java design,
just a trivial example to ensure that the callbacks from java work.
Michael Goffioul
2010-11-01 13:09:27 UTC
Permalink
On Fri, Oct 29, 2010 at 7:49 AM, Michael Goffioul
Post by Michael Goffioul
Post by schnumbl
Hi,
I tried to run the callback example (with octave 3.2.4_gcc-4.4.0), but the
line
Octave.call(callBack, new Object[]{val}, new Object[] {});
...
What *.jar files do I have to include to compile the *.java files?
The error above usually means a failure to find/load a shared library.
It would help if you reported the problem completely:
1) code to reproduce the problem (you mention the callback example, where
is that coming from?)
2) full java exception, including the backtrace

Michael.
Carlo de Falco
2010-04-22 13:48:46 UTC
Permalink
Post by Riccardo Corradini
Sure,
but the example is not mine
'cause is taken from
http://forum.ubuntu-it.org/index.php?topic=111537.msg756738
PUBLIC processo AS Process
PUBLIC SUB Form_Open()
StartOctave()
END
PUBLIC SUB Process_Read()
DIM sLine AS String
READ #processo, sLine, - Lof(processo)
Terminale.Text = Terminale.Text & sLine
END
PUBLIC SUB StartOctave()
Processo = SHELL "octave" FOR INPUT OUTPUT
END
PUBLIC SUB Button1_Click()
PRINT #Processo, Comando.Text
END
The function StartOctave runs the process and links pipes
(Processo = SHELL "octave" FOR INPUT OUTPUT)
In this way I can read and write over a process like if it were a file
With the function Button1_Click() I print the commands that the
users writes over the process (it is a just a sort of terminal)
While Process_Read is the function that controls if there is
something to read over the stream process and adds it to text-box
"terminale" in order to visualize it.
Hope my rough translation will be useful to the community.
Bests
Riccardo Corradini
Riccardo,
Thanks for the example.
Communication via pipes might work for simple cases but
is much less powerful than embedding Octave.
Therefore, I beleive using Gambas gives no advantage at all compared
to building the GUI in python as suggested by Jaroslav,
while it has lots of disadvantages in terms of speed, memory and
flexibility.
c.
Miguel Bazdresch
2010-06-10 18:45:01 UTC
Permalink
Post by Miguel Bazdresch
What is the best way to create interactive GUI apps with octave? For
example, I would like to have a window with three sliders controlling
the amplitude, frequency and phase of a cosine that is plotted below
the sliders. The purpose would be to make visually attractive demos
for my students.
Sorry about reviving this very old thread. I finally managed to get
gtk-server to work. I went with gtk-server since, among all suggested
options, it seemed to be the simplest to set-up and control from
inside an octave script.

Since it is not completely trivial to get to work, I put a
well-commented (IMO) demo here:

http://bitbucket.org/buo/octave-gtk-demo

I would like to suggest that, if somebody takes the time to write
similar GUI demos with some of the other alternatives (Gambas,
pyoctave, etc.), then we could put all demos together in a repository
somewhere; I think this would be a very useful resource. I'd be glad
to set up and maintain a bitbucket repo with the demos.

Also, I'd welcome any comments and improvements on my demo. In
particular, I would like to get the script to generate plots inside a
gtk canvas instead of on independent windows as it does now. This
shoud be possible but I still have no idea how.
--
Miguel Bazdresch
Loading...