在java中扩展一个类,但它不会从超类继承属性

发布于 2024-12-09 04:54:51 字数 4463 浏览 0 评论 0原文

好吧,在我的程序中,我有一些标签(在数组和其他东西中)无论如何,我想将我自己的属性添加到内置的 Label 类中,无论如何,所以我尝试扩展它,

public class LabelMod extends Label

但每当我尝试更改它,以便它创建我的新标签类型,而不是 createContents() 方法中的默认标签,它似乎没有继承原始标签属性,并且我收到一堆错误,

public void createContents()
{

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

然后有 9 个实例以下 (g1x1, g1x2、g1x3、g2x1 等)

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);

,然后将它们放入一个数组中,

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

我正在使用 SWT 创建一个 gui 并在主窗体上有一些标签。为什么我无法创建新类型的标签(带有我添加的额外属性)?

对于这个特定的例子,它说“构造函数 LabelMod(Shell, int) 未定义”,

为什么它只是从超类继承这些东西?我尝试将构造函数添加到 labelMod 类中,但它也给出了未定义的错误。然而,该错误在主类中得到修复。

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

我的另一个想法是将一些标签分配给 LabelMods,但因为它们不是它抱怨的同一类型。 这是我的意思的一个例子:

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

然后我有一个数组

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

,然后我将其分配给标签,

labelArray[0] = g1x1;

显然因为它们是不同的类型,它不起作用,但也许可以转换它或其他什么?

笔记: 如果我只使用正常的标签而不是我的修改版本,一切都会正常,所以我知道这不是问题。

编辑:

这是完整的类,如果它也有帮助的

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;
}

}

话,我发现如果我将鼠标悬停在原始(工作)Label(shlTictactoe, SWT.NONE);格式为

Label(Composite parent, int style)

<强>编辑2: 它说 addMouseListener 也有错误

Component类型中的addMouseListener(MouseListener)方法是 不适用于参数 (new MouseAdapter(){})

setImagei 再次未定义

类型 labelMod 未定义 setImage(Image) 方法

EDIT 3 我认为一个细节并不重要,但可能对问题至关重要...这些是我对 LabelMod 类的导入 - 请记住它是一个 SWT 项目

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

import org.eclipse.swt.widgets.Shell;

EDIT 4

好的,所以我添加了适当的导入(这次是 swt - 确保),所以现在我的导入是:

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

但现在我收到运行时错误,如果我进入设计器视图,所有标签都不会正确显示,这就是我得到的控制台:

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)

在错误日志中我得到这个:

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

http://pastebin.com/ru1QCU0A 其余部分

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

伴我心暖 2024-12-16 04:54:51

你这里有几个问题。

首先,您混淆了 org.eclipse.swt.widgets.Label 和 java.awt.Label。您(我认为)试图覆盖 org.eclipse.swt.widgets.Label,这意味着您需要有一个合适的构造函数。这意味着:

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

您不需要任何采用 String 参数的构造函数。这适用于 java.awt.Label,不适用于 SWT。

其次,您确定要覆盖Label吗? 推荐的 SWT 工作流程 是构建一个包装或包含LabelComposite 并在包装类中执行您的自定义工作。实际上,您需要重写一些内置检查才能子类化 SWT 小部件。您必须重写以下方法:

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

第三,我不确定 Label 上的 createContents 方法是什么。由于 SWT 是本机窗口系统的包装器,因此不同的 Label 在不同的平台上可能有不同的私有实现。例如,在 Mac OS 上,Label 或其任何祖先上没有 createContents 方法,这表明这是您无法重写的私有方法。您需要找到一种不同的方法来覆盖以更改您所看到的行为。

为此,我会再次询问 - 您确定您确实需要覆盖 Label 而不是简单地使用您自己的 Composite< 围绕它创建一个包装器< /代码>?我编写 SWT 应用程序已经有好几年了,我需要扩展 SWT 小部件一次,而且只是为了一个微不足道的更改,而我已经创建了无数Composite< /code> 包含或包装其他小部件。

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.

深陷 2024-12-16 04:54:51

构造函数不是继承的,因此您确实需要为子类定义自己的构造函数。我想,如果您仔细再试一次,您会发现您所显示的代码有效(假设您在 super 行末尾添加了缺少的分号。

然后关于您的数组,您可以分配一个实例子类变量到超类变量,但反之则不然。这表明 Label[] 类型的数组可以很好地保存常规 Label ;以及 labelMod 实例。

我应该指出,Java 有一套非常强大的命名约定;类总是以大写字母命名,如果您违反了这一点,那么对于有经验的人来说,它会使您的代码更难以阅读。

Constructors aren't inherited, so you do need to define your own constructor for your subclass. I think if you try again carefully you will find that the code you've shown works (given you add the missing semicolon at the end of the super line.

Then regarding your array, you can assign an instance of a subclass to a superclass variable, but not the other way around. This suggests that an array of type Label[] would work just fine; it could hold regular Labels as well as labelMod instances.

I should point out that Java has a set of very strong naming conventions; classes are always named with initial capital letters. If you violate this, it makes your code a lot harder to read for an experienced eye.

一场春暖 2024-12-16 04:54:51

编辑:

java.awt.Label 有 3 种类型的构造函数

Label()
Label(String)
Label(String, int)

,org.eclipse.swt.widgets.Label 有 1 种类型的构造函数

Label(Composite, int)

你如何能够同时调用它

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

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

我认为你正在混合SWT 和 AWT。这是真的吗?

EDIT:

java.awt.Label has 3 types of constructor

Label()
Label(String)
Label(String, int)

and org.eclipse.swt.widgets.Label has 1 type of constructor

Label(Composite, int)

How you were able to call this at the same time

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

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

I think you are mixing SWT and AWT. Could this be true?

这样的小城市 2024-12-16 04:54:51

我是一个摇摆人,所以我没有使用过 swt,但看起来你不应该覆盖 Label 类,并且有一些检查可以阻止你。

另请检查您的构造函数,您只能将超类构造函数可以采用的变量传递给 super 。所以检查javadock。除非将超类构造为子类,否则无法将超类强制转换为其子类。

I'm an swing guys so I haven't used swt but it looks like you are not supposed to overide the Label class and there are checks to stop you.

Also check your constructors, you can only pass variables to super that the superclass constructor can take. So check the javadock. You can't cast a superclass to its subclass unless it was constructed as that subclass.

我也只是我 2024-12-16 04:54:51

我认为可能发生的情况是,当您最初创建 LabelMod 时,您导入了错误的内容,可能是 java.awt.Label 而不是 swt。您使用的工具(我假设是 Eclipse)根据所选的超类(即 Label 但不是 org.eclipse.swt.widgets.Label)为您创建了所有构造函数。

因此,要回答这个问题,扩展 org.eclipse.swt.widgets.Label 并添加您自己的属性和方法或覆盖现有方法应该没有问题,但是,特别是如果使用为您创建大量“存根”代码的工具,您需要首先确保您拥有正确的超类。也许这就是您正在寻找的:

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

public class LabelMod extends Label {

public LabelMod(Composite parent, int style) {
    super(parent, style);
    // TODO Auto-generated constructor stub
}

public boolean isActivated;

public boolean isActivated() {
    return isActivated;
}

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

}

I think what may have happened is that when you originally created LabelMod, you had the wrong import, possibly java.awt.Label rather than swt. The tool you used, Eclipse I assume, created all the constructors for you based on the superclass chosen (ie Label but not org.eclipse.swt.widgets.Label).

So, to answer the question, you should have no problem extending org.eclipse.swt.widgets.Label and adding your own properties and methods or overriding existing methods but, especially if using tools that create a lot of "stub" code for you, you need to make sure you have the right superclass first. Maybe this is what you are looking for:

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

public class LabelMod extends Label {

public LabelMod(Composite parent, int style) {
    super(parent, style);
    // TODO Auto-generated constructor stub
}

public boolean isActivated;

public boolean isActivated() {
    return isActivated;
}

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

}
一片旧的回忆 2024-12-16 04:54:51

没有与构造函数的签名匹配的构造函数(请查看 此处),因此当您调用

super(shlTictactoe,none)

时,它无法在标签上找到适当的构造函数。您需要传入一个 String 和一个 int 。

There is no constructor that matches the signature of your constructor (look here), so when you call

super(shlTictactoe,none)

it can't find the appropriate constructor on label. You need to pass in a String and an int.

深海里的那抹蓝 2024-12-16 04:54:51

子类确实继承了,但是超类访问器方法本质上是不可访问的。从超类获取/设置值的一种简单方法是在子类中设置委托方法。

例如,如果超类有一个属性“label”,则在子类中您将创建一个方法:

public String getLabel(){
    return super.getLabel();
}

public void setLabel(String label){
    super.setLabel(label);
}

大多数 IDE 都有方法轻松生成委托方法,而无需手动编码。例如,在 Netbeans 中,“alt+insert”将显示一个代码生成选项菜单,您可以在其中选择委托,然后选择要为其创建委托方法的包含类或超类。

The subclass does inherit, however the superclass accessor methods are not inherently accessible. An easy way to be able to get/set values from the superclass is to setup delegate methods in your subclass.

For example, if the super class has an attribute "label", in your sub class you would create a method:

public String getLabel(){
    return super.getLabel();
}

public void setLabel(String label){
    super.setLabel(label);
}

Most IDEs have ways to generate delegate methods easily without hand coding them all. In Netbeans for example "alt+insert" will bring up a code generation options menu in which you can select delegates and then choose which included class or superclass to create delegate methods for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文