Update Children

Hi,

I have an application which consists of a main window and then some components which I created myself. I created these components by putting them into their own class to keep things tidy. So for instance, I have a texteditor in its own class called TextEditorWindow() and I add this to the main window in the main window constructor. However, the texteditor doesn’t update when I write to it; it just stays blank. I think it’s because I’m sending the data to the parent texteditor, instead of the instance I created in main window?? I’ve tried repaint() etc but to no avail. Is this an easy fix? Here’s the code for setting it up in the main window…

     TextEditorWindow* textWin;
     textWin = new TextEditorWindow();
 textWin->setBounds(500, 300, 450, 275);
 addAndMakeVisible(textWin);

Well, it’d help if you actually told us what this “TextEditorWindow” class actually is

Hi Jules, thanks for the reply. It’s basically a class that sets up a window with a texteditor for use! I keep it in its own .cpp file so that everything doesn’t get cluttered up. It’s kind of the same idea that you use in the Juce demo for setting up tabs. This texteditor is designed for outputting x, y and z coordinates from differential equations that I am solving (boring I know!). The user can adjust sliders which will affect the output etc. However, nothing is being printed at the moment! When I manually set up a texteditor in MainAppWindow it works fine but I would rather keep it in its own file if that’s possible?

Here’s its constructor…I then use this class to add a texteditor to MainAppWindow

TextEditorWindow::TextEditorWindow()
{
setSize(450, 225);

//Texteditor
textEditor= new TextEditor();
textEditor->setMultiLine(true);
textEditor->setBounds(50, 60, 400, 160);
textEditor->setColour(0x1000200, Colours::black);		//background colour
textEditor->setColour(0x1000201, Colours::lightgreen);	//text colour
textEditor->setColour(0x1000204, Colours::lightgreen);	//cursor colour
textEditor->setColour(0x1000202, Colours::lightgreen);	//highlight colour
addAndMakeVisible(textEditor);

}

There’s nothing obviously wrong with that, but you’ll just have made a silly mistake somewhere. Forgotten to make something visible, forgotten to add it, or it’s off the edge of the window or something. You just need to go through all your code carefully.

If I get stuck on things like this, I sometimes add a few paint() methods to fill all the components in bright colours, so I can see exactly where they are. That can help work out what’s going on.

I’ll go through the code and see if I have left out anything. I was thinking it’s because my TextEditorWindow class contains the function for outputting the data to the screen. However I only have a child of this class in MainAppWindow (as in my first post above) and therefore it never receives this data. From the code above, textEditor (parent) would get updated but textWin (child) wouldn’t. The same thing happens when I use this method for creating tabs or an OpenGL canvas…none of the children get updated. I hope my explanation is not too confusing…sometimes understanding someone else’s code can be a nightmare!

Thanks

Is your MainWindow a ResizableWindow?

In which case you should be using setContentComponent not addAndMakeVisible

Hi Justin, yes it’s a resizable window. I’ll try setContentComponent and see if that works…

Thanks,
Damien

That doesn’t seem to work because I think setContentComponent just puts a main component into the centre of the resizable window. I have that in my main.cpp file as follows to just draw the window…

class MyMainComponent : public DocumentWindow
{
public:
MyMainComponent():DocumentWindow(T(“Test”), Colours::black, DocumentWindow::allButtons, true)
{
MainAppWindow* mainWindow = new MainAppWindow();
setContentComponent(mainWindow);
centreWithSize (1000, 600);
setVisible(true);
}

I tried using the addChildComponent(textWin, -1) along with setVisible(true),instead of addAndMakeVisible() but it doesn’t make any difference.

Thanks

That looks right…i think you’ll need to post more code for us to see what you are doing. How are you updating the texteditor? What does that code look like? For instance you aren’t keeping a reference to TextEditorWindow in your class, so how do you get to the texteditor to set its value?

You might have a setValue method in TextEditorWindow which then sets your textEditor value text but without seeing the code we won’t know.

You mention a slider, so you have a sliderListener somewhere and is that changing your textEditor? I’d do this, give your TextEditor component a name in your constructor, then put a breakpoint whereever you setvalue, examine the pointer to the textEditor and if the componentName doesn’t match then you are sending to something else!

Here’s some simplfied code but the idea is the same. I’ve debugged this and the data is getting to the writeArray() function but it just doesn’t get displayed. If I add a texteditor normally to MainAppWindow then it will display the results, I don’t want to do that though as my file would be huge! It must be because it’s sending the data to a function in another class?? Don’t worry about the processingBlock() function…that does work!

//====================this function is in the MainAppWindow class==============
void MainAppWindow::timerCallback()
{
num = r->processingBlock(); //num is an array containing values for of x, y and z

for (int i=0; i<3; i++){
	textWin->writeArray(num[i]);
}

}

//=====================this function is part of the TextEditorWindow class=======
void TextEditorWindow::writeArray(float num)
{
String str = String(num); //casting num as String
textEditor->setText(str, false); //writing to texteditor
str.append(T("\n"), 10);
}

Sorry, but a lot of that code just looks like nonsense… What on earth is it supposed to do?? Why would you append to a string that isn’t actually used again? And why call the same function 3 times to just repeatedly replace the text with a new string?

But it is used again…next time it goes through the function. The “\n” makes it go to a new line at the start of the next iteration. I have a startTimer() somewhere that will repeatedly make it go through the methods. Basically I’m sending an array of 3 numbers, num, to the texteditor. num[1] will be written, then num[2] on a new line etc…
It’s a very simplified version of what I’m trying to do but it’s pretty much the same algorithm. As I’ve said the data is getting through to it when I debug, but the editor just isn’t refreshing from the parent I think.

um… nope.

Sorry my second function is a big jumbled up, it should read this…

//=====================this function is part of the TextEditorWindow class=======
void TextEditorWindow::writeArray(float num)
{
String data = String(num); //casting num as String
String str;
str.append(T(data, 5);
str.append(T("\n", 10);
textEditor->setText(str, false); //writing to texteditor
}

It doesn’t make a difference though to my actual problem.

Ok, first of all, let me tidy that up for you:

void TextEditorWindow::writeArray (float num) { textEditor->setText (String (num) + "\n", false); }

…now please explain what you expect to happen if you call it 3 times with different values?

I stand by my suggestion to put a breakpoint on

textEditor->setText

And follow/introspect where it goes. I can pretty much guarantee you’ll slap your forehead at some point! (You can even use the DBG macro to spit out a bunch of things about textEditor if you like…it’s bounds, its component name, etc)

It’s called 3 times as it should print each value of the array separately. That’s pretty much irrelevant though as it doesn’t work even if just pass one number through. I just put that code up to demonstate the basic idea of what’s happening. The thing is I’m having this problem with all of the classes I create…another example is that I have an OpenGLCanvas class and it doesn’t redraw when I pass coordinates through to it. It does redraw though if I just put this code into its parent class. It’s very hard to understand if you can’t see my code but I can’t really put all of that up! I’m going create some really simple apps that follow the same idea and see if I can see where I’m going wrong.

Thanks