Errors with Point and Pen with .x and .y methods

Hi everyone,
I’m building a GUI with userViews and the Pen object, using the Point object to handle some coordinates for placements within my window.
It looks like everything in my GUI responds and works so far, but I still get a bunch of error messages in the post window.

This is what my code looks like:

(

// this code generates a pattern draft GUI

~nShafts=4;
~nThreads=30;
~nPicks=8;
~nTreadles=4;

~space = 5; // space between sections

~threadStates = Array.new(~nThreads*~nShafts);
~tieUpStates = Array.new(~nShafts*~nTreadles);
~treadlingStates = Array.new(~nPicks*~nTreadles);

w = Window.new("Drawdown",Rect(300,300,(~nThreads+~nTreadles)*10+~space, (~nShafts+~nPicks)*10+~space), resizable: false);
w.background = Color.grey(0.7);
~point=0;

// threading view
~threading = UserView(w, Rect(0,0,~nThreads*10,~nShafts*10))
.background_(Color.white)
.clearOnRefresh_(false)
.mouseDownAction_({
	|w,x,y|
	~point = x.trunc(10)@y.trunc(10);
	// ~point.postln;
	~threading.refresh;
	~drawdown.refresh;
})
.drawFunc_{
	Pen.strokeColor = Color.grey(0.8);

	~nThreads.do{|i|
		Pen.moveTo(i*10@0);
		Pen.lineTo(i*10@(~nShafts*10));
		Pen.stroke;
	};
	~nShafts.do{|i|
		Pen.moveTo(0@i*10);
		Pen.lineTo((~nThreads)@i*10);
		Pen.stroke;
	};
	if(~threadStates.includesEqual(~point),
		{
			~threadStates.removeAllSuchThat({|item| item==~point});
			~threadStates.postln;
			Pen.fillColor=Color.white;
			Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
			Pen.fill;

		},
		{
			~threadStates.add(~point);
			~threadStates.postln;
			Pen.fillColor = Color.black;
			Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
			Pen.fill;
	});
};

// tie-up view
~tieUp = UserView(w, Rect(~threading.bounds.width+~space,0, ~nTreadles*10,~nShafts*10))
.background_(Color.white)
.clearOnRefresh_(false)
.mouseDownAction_({
	|w,x,y|
	~point = x.trunc(10)@y.trunc(10);
	// ~point.postln;
	~tieUp.refresh;
	~drawdown.refresh;
})
.drawFunc_{
	Pen.strokeColor = Color.grey(0.8);

	~nTreadles.do{|i|
		Pen.moveTo(i*10@0);
		Pen.lineTo(i*10@(~nShafts*10));
		Pen.stroke;
		// i.postln;
	};
	~nShafts.do{|i|
		Pen.moveTo(0@i*10);
		Pen.lineTo((~nTreadles)@i*10);
		Pen.stroke;
	};
	if(~tieUpStates.includesEqual(~point),
		{
			~tieUpStates.removeAllSuchThat({|item| item==~point});
			~tieUpStates.postln;
			Pen.fillColor=Color.white;
			Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
			Pen.fill;
		},
		{
			~tieUpStates.add(~point);
			~tieUpStates.postln;
			Pen.fillColor = Color.black;
			Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
			Pen.fill;
	});
};
// Treadling view
~treadling = UserView(w, Rect(~threading.bounds.width+~space,~threading.bounds.height+~space, ~nTreadles*10,~nPicks*10))
.background_(Color.white)
.clearOnRefresh_(false)
.mouseDownAction_({
	|w,x,y|
	~point = x.trunc(10)@y.trunc(10);
	~treadling.refresh;
	~drawdown.refresh;
})
.drawFunc_{
	Pen.strokeColor = Color.grey(0.8);

	~nTreadles.do{|i|
		Pen.moveTo(i*10@0);
		Pen.lineTo(i*10@(~nPicks*10));
		Pen.stroke;
		// i.postln;
	};
	~nPicks.do{|i|
		Pen.moveTo(0@i*10);
		Pen.lineTo((~nTreadles)@i*10);
		Pen.stroke;
	};
	if(~treadlingStates.includesEqual(~point),
		{
			~treadlingStates.removeAllSuchThat({|item| item==~point});
			~treadlingStates.postln;
			Pen.fillColor=Color.white;
			Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
			Pen.fill;
		},
		{
			~treadlingStates.add(~point);
			~treadlingStates.postln;
			Pen.fillColor = Color.black;
			Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
			Pen.fill;
	});
};

// drawdown view
~drawdown = UserView(w, Rect(0,~threading.bounds.height+~space, ~nThreads*10,~nPicks*10))
.background_(Color.white)
.clearOnRefresh_(false)

.drawFunc_{
	Pen.fillColor = Color.black;
	Pen.strokeColor = Color.grey(0.8);

	~nThreads.do{|i|
		Pen.moveTo(i*10@0);
		Pen.lineTo(i*10@(~nPicks*10));
		Pen.stroke;
		// i.postln;
	};
	~nPicks.do{|i|
		Pen.moveTo(0@i*10);
		Pen.lineTo((~nThreads)@i*10);
		Pen.stroke;
	};


};


w.front
)

This is one of the error messages I get, they’re all the same:

ERROR: Message 'x' not understood.
RECEIVER:
   Integer 0
ARGS:
CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	Nil:handleError
		arg this = nil
		arg error = <instance of DoesNotUnderstandError>
	Thread:handleError
		arg this = <instance of Thread>
		arg error = <instance of DoesNotUnderstandError>
	Object:throw
		arg this = <instance of DoesNotUnderstandError>
	Object:doesNotUnderstand
		arg this = 0
		arg selector = 'x'
		arg args = [*0]
	< closed FunctionDef >  (no arguments or variables)
	UserView:doDrawFunc
		arg this = <instance of UserView>
^^ ERROR: Message 'x' not understood.
RECEIVER: 0

So the thing seems to work fine but I would like to solve these errors, even if they don’t seem to affect anything.
Any ideas?

Hello, and welcome!

The error message gives a clue to where the bug is:

This means that somewhere in your code you are sending a .x message to an object whose value is 0. The only object that you send the .x message is ~point, and sure enough you have initialized ~point = 0. The reason you get the same error message 3 times is because you are calling ~point.x in 3 different drawFuncs, using this initial value of 0.

To fix this, you could set ~point equal to nil to begin with, and then, in each of your draw functions, make sure ~point is not nil before trying to draw it.

(

// this code generates a pattern draft GUI

~nShafts=4;
~nThreads=30;
~nPicks=8;
~nTreadles=4;

~space = 5; // space between sections

~threadStates = Array.new(~nThreads*~nShafts);
~tieUpStates = Array.new(~nShafts*~nTreadles);
~treadlingStates = Array.new(~nPicks*~nTreadles);

w = Window.new("Drawdown",Rect(300,300,(~nThreads+~nTreadles)*10+~space, (~nShafts+~nPicks)*10+~space), resizable: false);
w.background = Color.grey(0.7);
~point=nil;

// threading view
~threading = UserView(w, Rect(0,0,~nThreads*10,~nShafts*10))
.background_(Color.white)
.clearOnRefresh_(false)
.mouseDownAction_({
    |w,x,y|
    ~point = x.trunc(10)@y.trunc(10);
    // ~point.postln;
    ~threading.refresh;
    ~drawdown.refresh;
})
.drawFunc_{
    Pen.strokeColor = Color.grey(0.8);
    
    ~nThreads.do{|i|
        Pen.moveTo(i*10@0);
        Pen.lineTo(i*10@(~nShafts*10));
        Pen.stroke;
    };
    ~nShafts.do{|i|
        Pen.moveTo(0@i*10);
        Pen.lineTo((~nThreads)@i*10);
        Pen.stroke;
    };
    if(~point.notNil, {
        if(~threadStates.includesEqual(~point),
            {
                ~threadStates.removeAllSuchThat({|item| item==~point});
                ~threadStates.postln;
                Pen.fillColor=Color.white;
                Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
                Pen.fill;
                
            },
            {
                ~threadStates.add(~point);
                ~threadStates.postln;
                Pen.fillColor = Color.black;
                Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
                Pen.fill;
        });
    })
};

// tie-up view
~tieUp = UserView(w, Rect(~threading.bounds.width+~space,0, ~nTreadles*10,~nShafts*10))
.background_(Color.white)
.clearOnRefresh_(false)
.mouseDownAction_({
    |w,x,y|
    ~point = x.trunc(10)@y.trunc(10);
    // ~point.postln;
    ~tieUp.refresh;
    ~drawdown.refresh;
})
.drawFunc_{
    Pen.strokeColor = Color.grey(0.8);
    
    ~nTreadles.do{|i|
        Pen.moveTo(i*10@0);
        Pen.lineTo(i*10@(~nShafts*10));
        Pen.stroke;
        // i.postln;
    };
    ~nShafts.do{|i|
        Pen.moveTo(0@i*10);
        Pen.lineTo((~nTreadles)@i*10);
        Pen.stroke;
    };
    if(~point.notNil, {
        if(~tieUpStates.includesEqual(~point),
            {
                ~tieUpStates.removeAllSuchThat({|item| item==~point});
                ~tieUpStates.postln;
                Pen.fillColor=Color.white;
                Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
                Pen.fill;
            },
            {
                ~tieUpStates.add(~point);
                ~tieUpStates.postln;
                Pen.fillColor = Color.black;
                Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
                Pen.fill;
        });
    });
};
// Treadling view
~treadling = UserView(w, Rect(~threading.bounds.width+~space,~threading.bounds.height+~space, ~nTreadles*10,~nPicks*10))
.background_(Color.white)
.clearOnRefresh_(false)
.mouseDownAction_({
    |w,x,y|
    ~point = x.trunc(10)@y.trunc(10);
    ~treadling.refresh;
    ~drawdown.refresh;
})
.drawFunc_{
    Pen.strokeColor = Color.grey(0.8);
    
    ~nTreadles.do{|i|
        Pen.moveTo(i*10@0);
        Pen.lineTo(i*10@(~nPicks*10));
        Pen.stroke;
        // i.postln;
    };
    ~nPicks.do{|i|
        Pen.moveTo(0@i*10);
        Pen.lineTo((~nTreadles)@i*10);
        Pen.stroke;
    };
    if(~point.notNil, {
        if(~treadlingStates.includesEqual(~point),
            {
                ~treadlingStates.removeAllSuchThat({|item| item==~point});
                ~treadlingStates.postln;
                Pen.fillColor=Color.white;
                Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
                Pen.fill;
            },
            {
                ~treadlingStates.add(~point);
                ~treadlingStates.postln;
                Pen.fillColor = Color.black;
                Pen.addRect(Rect(~point.x, ~point.y, 10, 10));
                Pen.fill;
        });
    });
};

// drawdown view
~drawdown = UserView(w, Rect(0,~threading.bounds.height+~space, ~nThreads*10,~nPicks*10))
.background_(Color.white)
.clearOnRefresh_(false)

.drawFunc_{
    Pen.fillColor = Color.black;
    Pen.strokeColor = Color.grey(0.8);
    
    ~nThreads.do{|i|
        Pen.moveTo(i*10@0);
        Pen.lineTo(i*10@(~nPicks*10));
        Pen.stroke;
        // i.postln;
    };
    ~nPicks.do{|i|
        Pen.moveTo(0@i*10);
        Pen.lineTo((~nThreads)@i*10);
        Pen.stroke;
    };
    
    
};


w.front
)
1 Like

Hello!
This indeed fixed the issue, thanks for the informative answer! :smile:
All the best