Total mind blank Component inheritance issue


#1

Hey everyone, I don’t know why but I’m having a hell of a time with this one problem, and I know the answer should be fairly simple but I think I’m just convoluting it. I have a fairly decent C++ background so I’m not sure why I just can’t grasp this so here it goes…

I’m just doing some sample GUIs in Juce via the Jucer in VS2010, I’ve created the main window and that all good, I’ve added a bunch of components and in my MainWindow constructor created by the Jucer I add a Component as my main component for which I pass into the setContentComponent function of the MainWindow, and away I go…

…now my issue is that I want to change my Component I declare into a custom class “CustomComponent” that inherits from Component and ButtonListener, I don’t want to change much, I just want it to contain a combination of those two classes. Now my issue is, I’m completely unsure of how to create this, I really just want to create the class such that it’s a combination of the two super classes as the tutorial on Juced states, however doing this gives me the error “cannot instantiate abstract class” when declaring mainComponent = new CustomComponent(T"(main"));

Totally unsure about how to go about this and I feel like I’m having a total mind blank, I’ve created directX projects with 30,000 of code filled to the brim with inheritance so I’m not sure where I’m going wrong…I hope this makes sense? Any help would be appreciated, thanks!


#2

Well if you’re getting that error then you must not have implemented one of the pure virtual functions in one of the classes you inherited no?

Look through the API and check to see which one is missing.


#3

There are a lot of virtual function in the component class, does that mean my CustomComponent has to somehow implement them all?


#4

Copy and paste the exact error please


#5

Hey there, I don’t have an exact error to post mostly because I think the issue is I’m trying to get my CustomComponent to also inherit from “ButtonListener” of which I can’t find any API documentation so I can’t quite figure out what to inherit from it. Is there possibly a better way of receiving messages from components and buttons in Juce as opposed to what’s in the tutorial? The exact error anyways is:

“error C2259: ‘MainComponent’ : cannot instantiate abstract class”

Thanks again for the help guys.


#6

Okay, but that’s not the whole error message…what’s the virtual function that you are missing? Copy and paste the ENTIRE compile output please!


#7

Sorry about that, here’s the output:

[quote]1>------ Build started: Project: Juce GUI test, Configuration: Debug Win32 ------
1> MainComponent.cpp
1> MainWindow.cpp
1>c:\documents and settings\iisjnh\my documents\juce projects\juce gui test\source\mainwindow.cpp(24): error C2259: ‘MainComponent’ : cannot instantiate abstract class
1> due to following members:
1> ‘void juce::Button::Listener::buttonClicked(juce::Button *)’ : is abstract
1> c:\documents and settings\iisjnh\desktop\juce\juce_amalgamated.h(36586) : see declaration of 'juce::Button::Listener::buttonClicked’
1> Main.cpp
1>c:\documents and settings\iisjnh\my documents\juce projects\juce gui test\source\main.cpp(29): warning C4100: ‘commandLine’ : unreferenced formal parameter
1>c:\documents and settings\iisjnh\my documents\juce projects\juce gui test\source\main.cpp(63): warning C4100: ‘commandLine’ : unreferenced formal parameter
1> Generating Code…
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========[/quote]

I’m having my custom component inherit from ButtonListener but I believe the output is the same if inherit from Button::Listener as well.

I don’t know if this is the right way so feel free to correct me if there’s a more appropriate way to go about callback and sending and receiving messages. Thanks again!


#8

In Xcode an example full error like the one you are getting would be:

[quote]error: cannot allocate an object of abstract type 'MainComponent’
because the following virtual functions are pure within ‘MainComponent’:
virtual void juce::Button::Listener::buttonClicked(juce::Button*)[/quote]

ButtonListener is now a member class of Button so it looks like Button::Listener. Have a look inside juce_Button.h and you should see that “virtual void buttonClicked (Button* button) = 0;” is pure so this is probably the method you are not implementing.


#9

'MainComponent' : cannot instantiate abstract class due to following members: 'void juce::Button::Listener::buttonClicked(juce::Button *)' : is abstract

Well this tells you precisely what the problem is!


#10

…derp!

Thanks guys, forgot I can’t partially implement things with C++. So am I right in assuming that having a custom component inherit from both Component and Button::Listener is the proper way for callbacks? Or is there a better way?


#11

No, this is fine you just have to implement buttonClicked(). If you have a button in your component add yourself as a listener to it using button.addListener(this) then your buttonClicked() method will be called when the user clicks on it. Do what you want to do in here (possibly making some changes to the layout) and then call repaint() to tell the component to re-draw itself.

There are tons of examples of this in the juce demo and associated projects. Without knowing anything more about what you are actually trying to achieve it’s hard to suggest different methods. Of course completely separating your control from your view is one but maybe a later step.


#12

[quote=“Jed”]…derp!

Thanks guys, forgot I can’t partially implement things with C++.[/quote]

You can, but the author of the original parent class can mark a virtual method so that a subclass must implement it. That’s done here by Jules with the ‘= 0’ at the end of the method declaration. In the Juce mix-in classes, there’s generally 2-3 methods you must implement. If you really, really don’t need them (in which case it’s odd you use them) you can define an empty method yourself.

Bruce


#13

And you can partially implement classes, even if you don’t implement everything that’s pure virtual (=0) - you just can’t instantiate classes unless all the virtual methods are implemented.

This is in fact a common programming pattern - you start with an interface where everything is pure virtual - then you have an abstract base implementation that implements some of these virtual methods but not all - then you have specific implementation that you can instantiate where all the virtual methods are implemented.


#14

jeeze thanks for all the help guys! I’m getting things up and running no problem now, and I’m sure more questions will come up, but so far I’m really loving Juce!