Search code examples
javaswtextendsuperclass

Extending a class in java but it wont inherit properties from the superclass


ok so on my program i have some labels (which are in an array and stuff) anyway i want to add my own property to the inbuilt Label class, anyway so i tried extending it

public class LabelMod extends Label

but whenever i try to change it so it creates my new type of label instead of the default in the createContents() method it doesn't seem to inherit the original label properties and i get a stack of errors

public void createContents()
{

    shlTictactoe = new Shell();
    shlTictactoe.setSize(450, 300);
    shlTictactoe.setText("TicTacToe");

there is then 9 instances of the following (g1x1, g1x2, g1x3, g2x1 etc)

LabelMod g1x1 = new LabelMod(shlTictactoe, SWT.NONE);
    g1x1.addMouseListener(new MouseAdapter()
    {
        @Override
        public void mouseDown(MouseEvent e)
        {
            changeSt(0);
        }
    });
    g1x1.setImage(SWTResourceManager.getImage(MainForm.class,
            "/res/blank.png"));
    g1x1.setBounds(10, 10, 64, 64);

and then this to place them in an array

createArray(g1x1, g1x2, g1x3, g2x1, g2x2, g2x3, g3x1, g3x2, g3x3);

i am using SWT to create a gui and a have a few labels on the main form. Why cant I create the new type of label (with the extra properties i added)?

for this particular example it says "The constructor LabelMod(Shell, int) is undefined"

why dosent it just inherit the stuff from the superclass? i tried adding the constuctor to the labelMod class but it also gives an undefined error. The error gets fixed in the main class however.

public LabelMod(Shell shlTictactoe, int none)   
    {
        super(shlTictactoe,none);
        // TODO Auto-generated constructor stub
    }

Another idea I had was to just assign some of the Labels to LabelMods but because they arent the same type it complains. hers an example of what i mean:

Label g1x1 = new Label(shlTictactoe, SWT.NONE);     
g1x1.setImage(SWTResourceManager.getImage(MainForm.class,
            "/res/blank.png"));
g1x1.setBounds(10, 10, 64, 64);

and then later on I have an array

public LabelMod[] labelArray = new LabelMod[9];

and then I assign this to the label

labelArray[0] = g1x1;

obviously because they are different types it dosent work but perhaps its possible to convert it or something?

note: everything works if I just use the normal Label instead of my modified version so i know thats not the problem.

EDIT:

here is the class In full if it helps

public class LabelMod extends Label {


public LabelMod() throws HeadlessException
{
    super();
    // TODO Auto-generated constructor stub
}

public LabelMod(String text, int alignment) throws HeadlessException
{
    super(text, alignment);
    // TODO Auto-generated constructor stub
}

public LabelMod(String text) throws HeadlessException
{
    super(text);
    // TODO Auto-generated constructor stub
}

public LabelMod(Shell shlTictactoe, int none)   
{
    super(shlTictactoe,none);
    // TODO Auto-generated constructor stub
}

public boolean isActivated;

public boolean isActivated()
{
    return isActivated;
}

public void setActivated(boolean isActivated)
{
    this.isActivated = isActivated;
}

}

also i found if i hover over the original (working) Label(shlTictactoe, SWT.NONE); the format is

Label(Composite parent, int style)

EDIT 2: there are also errors with addMouseListener it says

The method addMouseListener(MouseListener) in the type Component is not applicable for the arguments (new MouseAdapter(){})

and for setImagei get undefined again

The method setImage(Image) is undefined for the type labelMod

EDIT 3 One detail i didnt think to be important but could be vital to the issue... these are my imports for the LabelMod class - keep in mind its an SWT project

import java.awt.HeadlessException;
import java.awt.Label;

import org.eclipse.swt.widgets.Shell;

EDIT 4

okay so i added in the appropriate import (swt this time - made sure) so now my imports are:

import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

but now i get a runtime error, and if i go into the designer view all the labels dont display properly here is what i get in the console:

org.eclipse.swt.SWTException: Subclassing not allowed
at org.eclipse.swt.SWT.error(SWT.java:4282)
at org.eclipse.swt.SWT.error(SWT.java:4197)
at org.eclipse.swt.SWT.error(SWT.java:4168)
at org.eclipse.swt.widgets.Widget.error(Widget.java:468)
at org.eclipse.swt.widgets.Widget.checkSubclass(Widget.java:313)
at org.eclipse.swt.widgets.Widget.<init>(Widget.java:148)
at org.eclipse.swt.widgets.Control.<init>(Control.java:110)
at org.eclipse.swt.widgets.Label.<init>(Label.java:101)
at Main.LabelMod.<init>(LabelMod.java:16)
at Main.MainForm.createContents(MainForm.java:99)
at Main.MainForm.open(MainForm.java:39)
at Main.MainForm.main(MainForm.java:26)

and in the error log i ge this:

Designer [1.1.0.r37x201109091012.201110120013]: new Label(shell, SWT.NONE)

http://pastebin.com/ru1QCU0A for the rest


Solution

  • You've got a couple of problems here.

    First, you're mixing up org.eclipse.swt.widgets.Label and java.awt.Label. You're (I think) trying to override org.eclipse.swt.widgets.Label, this means that you need to have a suitable constructor for that. This means:

    public LabelMod(Shell parent, int style)
    {
        super(parent, style);
    }
    

    You do not need any of the constructors that take a String argument. This is suitable for java.awt.Label, not for SWT.

    Second, are you sure you want to override Label? The recommended SWT workflow is to build a Composite that wraps or contains a Label and to do your custom work in the wrapping class. There are actually built-in checks that you'll need to override to even be able to subclass an SWT widget. You'll have to override the following method:

    protected void checkSubclass()
    {
        /* Allow us to subclass this widget. */
    }
    

    Third, I'm not sure what the createContents method on Label is. Since SWT is a wrapper around the native window system, the different Labels may have different private implementations on different platforms. On Mac OS, for example, there is not createContents method on Label or any of its ancestors, which would indicate that this is a private method that you can't override. You'll need to find a different method to override to change the behavior you're seeing.

    To that end, I'll ask again - are you sure that you really need to override Label and not simply create a wrapper around it using your own Composite? I've been writing SWT applications for several years and I've had the need to extend an SWT widget exactly once, and only for a trivial change, whereas I've created countless Composites that contain or wrap other widgets.