在java中扩展一个类,但它不会从超类继承属性
好吧,在我的程序中,我有一些标签(在数组和其他东西中)无论如何,我想将我自己的属性添加到内置的 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(){})
和 setImage
i 再次未定义
类型 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)
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 setImage
i 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
你这里有几个问题。
首先,您混淆了 org.eclipse.swt.widgets.Label 和 java.awt.Label。您(我认为)试图覆盖 org.eclipse.swt.widgets.Label,这意味着您需要有一个合适的构造函数。这意味着:
您不需要任何采用
String
参数的构造函数。这适用于java.awt.Label
,不适用于 SWT。其次,您确定要覆盖
Label
吗? 推荐的 SWT 工作流程 是构建一个包装或包含Label
的Composite
并在包装类中执行您的自定义工作。实际上,您需要重写一些内置检查才能子类化 SWT 小部件。您必须重写以下方法:第三,我不确定
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
andjava.awt.Label
. You're (I think) trying to overrideorg.eclipse.swt.widgets.Label
, this means that you need to have a suitable constructor for that. This means:You do not need any of the constructors that take a
String
argument. This is suitable forjava.awt.Label
, not for SWT.Second, are you sure you want to override
Label
? The recommended SWT workflow is to build aComposite
that wraps or contains aLabel
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:Third, I'm not sure what the
createContents
method onLabel
is. Since SWT is a wrapper around the native window system, the differentLabel
s may have different private implementations on different platforms. On Mac OS, for example, there is notcreateContents
method onLabel
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 ownComposite
? 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 countlessComposite
s that contain or wrap other widgets.构造函数不是继承的,因此您确实需要为子类定义自己的构造函数。我想,如果您仔细再试一次,您会发现您所显示的代码有效(假设您在
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 regularLabel
s as well aslabelMod
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.
编辑:
java.awt.Label 有 3 种类型的构造函数
,org.eclipse.swt.widgets.Label 有 1 种类型的构造函数
你如何能够同时调用它
我认为你正在混合SWT 和 AWT。这是真的吗?
EDIT:
java.awt.Label has 3 types of constructor
and org.eclipse.swt.widgets.Label has 1 type of constructor
How you were able to call this at the same time
I think you are mixing SWT and AWT. Could this be true?
我是一个摇摆人,所以我没有使用过 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.
我认为可能发生的情况是,当您最初创建 LabelMod 时,您导入了错误的内容,可能是 java.awt.Label 而不是 swt。您使用的工具(我假设是 Eclipse)根据所选的超类(即 Label 但不是 org.eclipse.swt.widgets.Label)为您创建了所有构造函数。
因此,要回答这个问题,扩展 org.eclipse.swt.widgets.Label 并添加您自己的属性和方法或覆盖现有方法应该没有问题,但是,特别是如果使用为您创建大量“存根”代码的工具,您需要首先确保您拥有正确的超类。也许这就是您正在寻找的:
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:
没有与构造函数的签名匹配的构造函数(请查看 此处),因此当您调用
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.
子类确实继承了,但是超类访问器方法本质上是不可访问的。从超类获取/设置值的一种简单方法是在子类中设置委托方法。
例如,如果超类有一个属性“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:
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.