My first java external - help please

ciperlone's icon

Hello Max community!
I finally get the courage to start with Java in Max, that means understanding how mxj works, as far as I know.

I intend to make a little java external with the following description:
- It has 3 inlets (it's a sort of a configurable switch)
1st inlet - int values;
2nd inlet - accept int values, that should correspond to the number of outlets the object has. The value received should be >= 2;
3rd inlet - int value between 1 and the value of the 2nd inlet, that decides which outlet outputs the values inputed in the 1st inlet.

it should send an error message to the max window if the user chooses a value superior to the number of outlets, and it should send the values of the first inlet to the first outlet, if that error occurs.

Any help is truly appreciated!
And if you could comment the code, that would be a must!

Thank you in advance for any help

Emmanuel Jourdan's icon

You might want to post some code with question, or things that you don't know how to do instead of asking for someone to do the external of your dream... that's a good way to learn, and also a better way to get an answer.

ciperlone's icon

True!

Ok, I will try to do what I can (which is very litlle at the moment, but I'm following the tutorials), and post the java code and the max patch in the next post!

Thank you.

P.S.: Your externals are very interesting!

ciperlone's icon

I have probably a very basic noobie problem, but I can't solve it by myself.

I started the tutorials, and everything was fine at the beginning.
I compiled a class to a .java file with sucess.
Some days after I went to learn new things, but I could't get the previous program to work. I tried to move the files from my personal directory to C:Program FilesCycling '74Max 5.0Cycling '74javaclasses , but that didn't solve the problem.
The java external works properly wile inside my personal folder, but I can't get access to the code inside [mxj quickie HelloWorld1]
What am I doing wrong?

Here are the warnings at the Max Window. They appear when I bang (get access to the code) the [mxj quickie HelloWorld1]. What does this mean?

(mxj quickie) Decompiling HelloWorld1 with JODE
(mxj quickie) Be patient...decompiling HelloWorld1
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: HelloWorld1
    at jode.bytecode.ClassInfo.loadInfo(ClassInfo.java:631)
    at jode.decompiler.ClassAnalyzer.(ClassAnalyzer.java:86)
    at jode.decompiler.ClassAnalyzer.(ClassAnalyzer.java:123)
    at jode.decompiler.Decompiler.decompile(Decompiler.java:191)
    at com.cycling74.max.MXJDecompiler.decompile(MXJDecompiler.java:64)
    at quickie._get_source(quickie.java:417)
    at quickie.access$000(quickie.java:14)
    at quickie$1.run(quickie.java:87)
    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)

Here's the patch:

Max Patch
Copy patch and select New From Clipboard in Max.

and the .class and .java files are attached, inside the HelloWorld1.rar file.

Thank you in advance for anny help!

P.S.: Sorry for the "bad" language in the code. It's supposed to be funny, not rude.

Luke Hall's icon

If you create an instance of your [mxj HelloWorld1] you can send the "viewsource" message to view, edit and recompile the code. Does this help at all?

lh

ciperlone's icon

I don't know what I was doing wrong, but I found a solution:
to open the .java file again in the compiler window, and recompile it again. It's an annoying solution, but it's one!
I suspect that the problem was due to duplicated java and class files that were creating conflict...but I'm not sure.

I already made the java code that I wanted. I had the help of a friend and a teacher. And the precious tutorials, of course!
Here it is (and it works!), with some newbie comments:

Quote:
import com.cycling74.max.*;

public class comutador extends MaxObject {
                                                    //declare variables
    private int valor=0;                            //valor it's the values of the 1st inlet
    private int saida=0;                            //saida its the respective outlet that outputs the value
    private int NUM;                                //[mxj comutador~ NUM]

    public comutador() {                            //declare number of inlets and outlets
        NUM=2;                                        //default number of outlets
        declareInlets(new int[]{DataTypes.INT,DataTypes.INT});
        declareOutlets(new int[]{DataTypes.INT,DataTypes.INT});        
    }

    public comutador(int n) {                        //declare number of outlets - [mxj comutador~ n]
        if(n>=2)NUM=n;                                //if NUM ir greater than 2, changes to the number that the user gives
        else NUM=2;                                    //if NUM is smaller than 2, NUM is 2
        declareInlets(new int[]{DataTypes.INT,DataTypes.INT});//declare two inlets
        int k[]=new int[NUM];                        //vector that defines the number of outlets
        for(int i=0;i
        declareOutlets(k);                            //declare "k" outlets
    }

    public void inlet(int i) {                        //comutador - switcher
        if (getInlet() == 0) valor=i;                //i is the value received by the 1st inlet ("getInlet() == 0")
        if (getInlet() == 1) saida=i%NUM;            
        outlet(saida,valor);                        //saida= respective outlet that outputs the values (valor) received by the 1st inlet
    }    
}

Compile the java code with the quickie method (explained in Cycling '74/Max 5.0/java-doc/tutorial/html/quickie.html), and after that create a new object with this text inside [mxj comutador X] where X is the number of outlet you want the object to have. The 1st inlet accepts the values, the 2nd inlet is to choose the outlet that outputs the values.

Actually, the code is not perfect. I don't know why, but it adds one additional outlet, instead of just the outlets defined by the user. If anyone knows how to solve this, please help me.

Now I'm trying to make a DSP relative, that accepts audio signal from an inlet, and outputs the signal by a chosen outlet from the user.

The code I've made has an error:Quote:
C:Tutoriaissrccomutadortil.java[ 4 ] comutadortil is not abstract and does not override abstract method dsp(com.cycling74.msp.MSPSignal[],com.cycling74.msp.MSPSignal[]) in com.cycling74.msp.MSPObject
public class comutadortil extends MSPObject
^
1 error
[ 28/Set/2009 12:37:21 ]
compilation of C:Tutoriaissrccomutadortil.java failed.

What does this error means? Help please!

Here's the code:Quote:
import com.cycling74.max.*;
import com.cycling74.msp.*;

public class comutadortil extends MSPObject
    {
    private int valor=0;
    private int saida=0;
    private int NUM;

    public comutadortil() {
        NUM=2;
        declareInlets(new int[]{SIGNAL,SIGNAL});
        declareOutlets(new int[]{SIGNAL,SIGNAL});
    }

    public comutadortil(int n) {
        if(n>=2)NUM=n;
        else NUM=2;
        declareInlets(new int[]{SIGNAL,SIGNAL});
        int k[]=new int[NUM];
        for(int i=0;i
        declareOutlets(k);
    }

    public void inlet(int i) {
        if (getInlet() == 0) valor=i;
        if (getInlet() == 1) saida=i%NUM;
        outlet(saida,valor);
    }    
}

Please help me to correct what I'm doing wrong. Cheers!

jan.jdo's icon

Are you making an object like gate~ but with the inlets reversed?

The extra outlet you get is the info outlet -it's created by default. To remove it you call MaxObject's createInfoOutlet(false) in your constructor.

If you are going to extend MSPObject you must implement a dsp method to describe how the object will handle its signal processing.
But, it's much easier to extend MSPPerformer and override its perform method instead. This method is where your object will do the guts of its work. There is a good PDF in the java-doc folder that describes how to set up you r perform method.

hth .