Is this a bug? timer will change behavior of subwindow

say componentA addAndMakeVisible componentB
if there is a timer in componentB,then only componentA shows ,and componentB disapppar when startTimer.

I think you’ll need to post some demonstration code. I’ve never seen this happen, so can only assume there is something with your particular code which is causing the behaviour?

It is most likely not the fact that there is a timer, but what you put in the timerCallback(). Maybe something, that changes the visibility or the bounds/size of the vanishing Component?

my timercallback do nothing ,just try to set true/false to a varaible so that paint even
could refresh ,i will exam a code.

I will show my code here:

/*

This file was auto-generated!

==============================================================================
*/

#pragma once

#include “…/JuceLibraryCode/JuceHeader.h”
#include “timeComponent.h”
//==============================================================================
/*
This component lives inside our window, and this is where you should put all
your controls and content.
*/
class MainComponent : public Component
{
public:
//==============================================================================
MainComponent();
~MainComponent();

//==============================================================================
void paint (Graphics&) override;
void resized() override;

private:
//==============================================================================
// Your private member variables go here…
TextButton button;
timeComponent t;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};

/*

This file was auto-generated!

==============================================================================
*/

#include “MainComponent.h”

//==============================================================================
MainComponent::MainComponent()
{
setSize (600, 400);
button.onClick=([this]{

});
addAndMakeVisible(t);

}

MainComponent::~MainComponent()
{

}

//==============================================================================
void MainComponent::paint (Graphics& g)
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));

g.setFont (Font (16.0f));
g.setColour (Colours::white);
g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true);

}

void MainComponent::resized()
{
// This is called when the MainComponent is resized.
// If you add any child components, this is where you should
// update their positions.
}

/*

This is an automatically generated GUI class created by the Projucer!

Be careful when adding custom code to these files, as only the code within
the “//[xyz]” and “//[/xyz]” sections will be retained when the file is loaded
and re-saved.

Created with Projucer version: 5.4.3


The Projucer is part of the JUCE library.
Copyright © 2017 - ROLI Ltd.

==============================================================================
*/

#pragma once

//[Headers] – You can add your own extra header files here –
#include “…/JuceLibraryCode/JuceHeader.h”
//[/Headers]

//==============================================================================
/**
//[Comments]
An auto-generated component, created by the Projucer.

Describe your class and how it works here!
                                                                //[/Comments]

*/
class timeComponent : public Component,
public MultiTimer,
public Button::Listener
{
public:
//==============================================================================
timeComponent ();
~timeComponent();

//==============================================================================
//[UserMethods]     -- You can add your own custom methods in this section.
	void timerCallback(int timerID) override;
//[/UserMethods]

void paint (Graphics& g) override;
void resized() override;
void buttonClicked (Button* buttonThatWasClicked) override;

private:
//[UserVariables] – You can add your own custom variables in this section.
Colour colour;
Rectangle ballBounds;
Point direction;
//[/UserVariables]

//==============================================================================
std::unique_ptr<TextButton> m_bt;


//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (timeComponent)

};

//[EndFile] You can add extra defines here…
//[/EndFile]

/*

This is an automatically generated GUI class created by the Projucer!

Be careful when adding custom code to these files, as only the code within
the “//[xyz]” and “//[/xyz]” sections will be retained when the file is loaded
and re-saved.

Created with Projucer version: 5.4.3


The Projucer is part of the JUCE library.
Copyright © 2017 - ROLI Ltd.

==============================================================================
*/

//[Headers] You can add your own extra header files here…
//[/Headers]

#include “timeComponent.h”

//[MiscUserDefs] You can add your own user definitions and misc code here…
//[/MiscUserDefs]

//==============================================================================
timeComponent::timeComponent ()
{
//[Constructor_pre] You can add your own custom stuff here…
//[/Constructor_pre]

m_bt.reset (new TextButton ("m_bt"));
addAndMakeVisible (m_bt.get());
m_bt->setButtonText (TRANS("test"));
m_bt->addListener (this);
m_bt->setColour (TextButton::buttonColourId, Colour (0xff42a2c8));

m_bt->setBounds (112, 120, 96, 24);


//[UserPreSize]
//[/UserPreSize]

setSize (600, 400);


//[Constructor] You can add your own custom stuff here..

// startTimer (1,60);
//[/Constructor]
}

timeComponent::~timeComponent()
{
//[Destructor_pre]. You can add your own custom destruction code here…
//[/Destructor_pre]

m_bt = nullptr;


//[Destructor]. You can add your own custom destruction code here..
stopTimer(1);
//[/Destructor]

}

//==============================================================================
void timeComponent::paint (Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here…
//[/UserPrePaint]

//[UserPaint] Add your own custom painting code here..
 if(true){
        g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));   // clear the background
}
g.fillAll(getLookAndFeel().findColour(ResizableWindow::backgroundColourId));   // clear the background
g.setColour(Colours::grey);
g.drawRect(getLocalBounds(), 1);   // draw an outline around the component
g.setColour(Colours::white);
g.setFont(14.0f);
g.setColour (colour);
g.fillEllipse (ballBounds - getPosition().toFloat());
//[/UserPaint]

}

void timeComponent::resized()
{
//[UserPreResize] Add your own custom resize code here…
//[/UserPreResize]

//[UserResized] Add your own custom resize handling here..
//[/UserResized]

}

void timeComponent::buttonClicked (Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]

if (buttonThatWasClicked == m_bt.get())
{
    //[UserButtonCode_m_bt] -- add your button handler code here..
    //[/UserButtonCode_m_bt]
}

//[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post]

}

//[MiscUserCode] You can add your own definitions of your custom methods or any other code here…
void timeComponent::timerCallback(int timerID)
{
if(timerID==1){
ballBounds += direction;

    if (ballBounds.getX() < 0)                      direction.x =  std::abs (direction.x);
    if (ballBounds.getY() < 0)                      direction.y =  std::abs (direction.y);
    if (ballBounds.getRight()  > getParentWidth())  direction.x = -std::abs (direction.x);
    if (ballBounds.getBottom() > getParentHeight()) direction.y = -std::abs (direction.y);


    setBounds (ballBounds.getSmallestIntegerContainer());
    }

}

//[/MiscUserCode]

//==============================================================================
#if 0
/* – Projucer information section –

This is where the Projucer stores the metadata that describe this GUI layout, so
make changes in here at your peril!

BEGIN_JUCER_METADATA

<JUCER_COMPONENT documentType=“Component” className=“timeComponent” componentName=""
parentClasses=“public Component, public MultiTimer” constructorParams=""
variableInitialisers="" snapPixels=“8” snapActive=“1” snapShown=“1”
overlayOpacity=“0.330” fixedSize=“0” initialWidth=“600” initialHeight=“400”>


</JUCER_COMPONENT>

END_JUCER_METADATA
*/
#endif

//[EndFile] You can add extra defines here…
//[/EndFile]

// startTimer (1,60);

when I comment this line on timeComponent,then the button of timecomponent will show normally
otherwise it will not show. seems the timeComponent hide back on the mainwindow

May I ask you to surround your code by a line of three backticks ``` before and after, so the code is layouted properly, and please strip out all those comments… then it’s easier to help.

Thanks, much appreciated :slight_smile:

I short my code as such ,will it more clear?

///////////////////////////////////////////main component///////////////////////////////
#include “timeComponent.h”

class MainComponent : public Component
{
public:
MainComponent(){
setSize (600, 400);
addAndMakeVisible(t);
}

~MainComponent();
void paint (Graphics&) override{
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));

g.setFont (Font (16.0f));
g.setColour (Colours::white);
g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true);
}
void resized() override; 
private: 
timeComponent t;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
  
void MainComponent::paint (Graphics& g)
{
// (Our component is opaque, so we must completely fill the background with a solid colour)


}   
///////////////////////////////////////////////////////////////timeComponent///////////////////////////////////////////////

class timeComponent : public Component,
public MultiTimer,
public Button::Listener
{
public:
 
timeComponent (){
m_bt.reset (new TextButton ("m_bt"));
addAndMakeVisible (m_bt.get());
m_bt->setButtonText (TRANS("test"));
m_bt->addListener (this);
m_bt->setColour (TextButton::buttonColourId, Colour (0xff42a2c8));

m_bt->setBounds (112, 120, 96, 24);


//[UserPreSize]
//[/UserPreSize]

setSize (600, 400);
// startTimer (1,60);
}
~timeComponent();
void timerCallback(int timerID) override{
if(timerID==1){
ballBounds += direction;

if (ballBounds.getX() < 0)                      direction.x =  std::abs (direction.x);
if (ballBounds.getY() < 0)                      direction.y =  std::abs (direction.y);
if (ballBounds.getRight()  > getParentWidth())  direction.x = -std::abs (direction.x);
if (ballBounds.getBottom() > getParentHeight()) direction.y = -std::abs (direction.y);


setBounds (ballBounds.getSmallestIntegerContainer());
}

}

void paint (Graphics& g) override{
if(true){
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); // clear the background
}
g.fillAll(getLookAndFeel().findColour(ResizableWindow::backgroundColourId)); // clear the background
g.setColour(Colours::grey);
g.drawRect(getLocalBounds(), 1); // draw an outline around the component
g.setColour(Colours::white);
g.setFont(14.0f);
g.setColour (colour);
g.fillEllipse (ballBounds - getPosition().toFloat());
}
void resized() override;

Colour colour;
Rectangle ballBounds;
Point direction;
std::unique_ptr m_bt;

};

That’s great, thank you. If you click on the pen symbol, you can also edit your post.
And the three back ticks will make the code show up with indent like you typed it, rather than all on the beginning of the line:

    Here is my problem:

    ```
    void foo()
    {
        bar();
    }
    ```

And for your problem, I would begin with swapping the setSize and addAndMakeVisible in the constructor, since the setSize will trigger a repaint, but I am not sure about the addAndMakeVisible…

setBounds (ballBounds.getSmallestIntegerContainer());

in your timerCallback, try adding a breakpoint there and check what is being passed into setBounds, my money is on a zero-sized bounding box.

in fact this is an example of projucer demo. what I am mean is I
want to set a transparent window with a button and a ball visible beyond the mainwindow.

the timer is to set the localtion of the ball. should setbounds set the window behind the mainwindow?

now I learn your “three dots” mean. thanks :slight_smile:

1 Like

//setBounds (ballBounds.getSmallestIntegerContainer());
comment this,shows normally .but don’t know why…

It’s difficult to really see without the code above being surrounded by ```, but from what I can tell it appears you never give Rectangle ballBounds a size, so ballBounds.getSmallestIntegerContainer() will be returning a zero size bound and your component disappears.

yes,it’s the reazon.thanks