Расширение класса в Java, но он не наследует свойства от суперкласса - PullRequest
1 голос
/ 12 октября 2011

хорошо, поэтому в моей программе у меня есть несколько меток (которые находятся в массиве и прочем), так или иначе, я хочу добавить свое собственное свойство во встроенный класс 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);

iЯ использую SWT для создания графического интерфейса и несколько ярлыков на главной форме.Почему я не могу создать новый тип метки (с добавленными мною дополнительными свойствами)?

для этого конкретного примера написано «Конструктор 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;

очевидно, потому что они разных типов, но это возможно, но возможно ли их преобразовать или что-то еще?

примечание: все работает, если я просто использую обычную Label вместо моей модифицированной версии, так что я знаю, что это не проблема.

РЕДАКТИРОВАТЬ:

вот класс В полном объеме, если это поможет

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 он говорит

Метод addMouseListener (MouseListener) в компоненте типа не применим для аргументов (new MouseAdapter () {})

и для setImage я снова получаю неопределенным

Метод setImage (Image) не определен для типа labelMod

РЕДАКТИРОВАТЬ 3 Одна деталь, которую я не считал важной, но могла бы иметь жизненно важное значение для этой проблемы ... Это мой импорт для класса LabelMod - имейте в виду, что это проект SWT

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

import org.eclipse.swt.widgets.Shell;

РЕДАКТИРОВАТЬ 4

хорошо, поэтому я добавил в соответствующий импорт (на этот раз - убедился), так что теперь мой импорт:

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 для остальных

Ответы [ 7 ]

1 голос
/ 12 октября 2011

У вас здесь есть пара проблем.

Сначала вы смешиваете 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 предназначен для создания Composite, который включает или содержит Label, и выполняет пользовательскую работу в классе упаковки.На самом деле есть встроенные проверки, которые вам необходимо переопределить, чтобы иметь возможность создавать подклассы SWT-виджета.Вам придется переопределить следующий метод:

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

В-третьих, я не уверен, что такое метод createContents для Label.Поскольку SWT является оболочкой для собственной оконной системы, разные Label могут иметь разные частные реализации на разных платформах.Например, в Mac OS нет метода createContents для Label или любого из его предков, что указывало бы на то, что это закрытый метод, который нельзя переопределить.Вам нужно будет найти другой метод для переопределения, чтобы изменить поведение, которое вы видите.

С этой целью я спрошу еще раз - вы уверены, что вам действительно нужно переопределить * 1029?* Label, а не просто создать обертку вокруг него, используя свой Composite?Я пишу SWT-приложения в течение нескольких лет, и мне нужно было расширить виджет SWT ровно один раз , и только для тривиального изменения, тогда как я создал бесчисленное множество Composite, которые содержатили обернуть другие виджеты.

0 голосов
/ 13 октября 2011

Я думаю, что, возможно, произошло то, что, когда вы изначально создали 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;
}

}
0 голосов
/ 13 октября 2011

Я парни из Swing, поэтому я не использовал SWT, но похоже, что вы не должны пересекать класс Label и есть проверки, чтобы остановить вас.

Также проверьте ваши конструкторы, вы можететолько передать переменные super, которые может принимать конструктор суперкласса.Так что проверь джавадок.Вы не можете привести суперкласс к его подклассу, если он не создан как этот подкласс.

0 голосов
/ 12 октября 2011

РЕДАКТИРОВАТЬ:

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.Может ли это быть правдой?

0 голосов
/ 12 октября 2011

Не существует конструктора, соответствующего сигнатуре вашего конструктора (смотрите здесь ), поэтому при вызове

super(shlTictactoe,none)

он не может найтисоответствующий конструктор на этикетке.Вам нужно передать строку и int.

0 голосов
/ 12 октября 2011

Конструкторы не наследуются, поэтому вам нужно определить свой собственный конструктор для своего подкласса.Я думаю, что если вы попытаетесь еще раз внимательно, вы обнаружите, что код, который вы показали, работает (учитывая, что вы добавляете пропущенную точку с запятой в конце строки super.

Затем, что касается вашего массива, вы можете назначитьэкземпляр подкласса для переменной суперкласса, но не наоборот. Это говорит о том, что массив типа Label[] будет работать просто отлично, он может содержать обычные Label s, а также labelMod экземпляры.

Я должен отметить, что в Java существует ряд очень строгих соглашений об именах, классы всегда именуются начальными заглавными буквами. Если вы нарушите это, это сделает ваш код намного труднее для чтения опытным глазом.

0 голосов
/ 12 октября 2011

Подкласс наследует, однако методы доступа суперкласса по своей природе недоступны. Самый простой способ получить / установить значения из суперкласса - это настроить методы делегата в вашем подклассе.

Например, если суперкласс имеет атрибут «метка», в вашем подклассе вы бы создали метод:

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

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

У большинства IDE есть способы легко генерировать методы делегатов, не кодируя их вручную. Например, в Netbeans «alt + insert» вызовет меню опций генерации кода, в котором вы можете выбрать делегатов, а затем выбрать, какой включенный класс или суперкласс для создания методов делегата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...