Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   АddChild: инициализация неосновного субкласса (http://www.flasher.ru/forum/showthread.php?t=202778)

Fogflasher 09.08.2013 12:31

АddChild: инициализация неосновного субкласса
 
Хм, вроде бы простая вещь, но чего-то я недогоняю.

Есть основной класс:

Код AS3:

package
{
 
import flash.display.*;
import flash.text.*;
import flash.events.*;
 
        public class Main extends Sprite
        {
                        public var TextInitter:TextInit;
 
                        public function Main()
                        {
 
                                TextInitter = new TextInit();
 
                        }
 
 
        }
 
}

И есть класс TextInit:

Код AS3:

package
{
 
        import flash.display.*;
          import flash.text.*;
          import flash.events.*;
 
        public class TextInit extends TextField
                  {
 
                        public function TextInit()
                        {
 
                                trace("TextInit instance created!");
 
                                this.text = "MouseClick";
                                this.x = 50;
                                this.y = 50;
                                this.selectable = false;
                                this.autoSize  = TextFieldAutoSize.LEFT;
 
                                addChild(this);
 
                        }
 
                }
 
}

При запуске я получаю ошибку:
Цитата:

1180: Call to a possibly undefined method addChild. addChild(this);
Хорошо, значит, надо юзать что-то вроде:
Код AS3:

stage.addChild(this);

Однако тогда эта строка выдает ошибку:
Цитата:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at TextInit$iinit()
at Main$iinit()
И вот, возникает вопрос: а как же добавить на stage экземпляр класса, при его инициации функцией new();

P.S. Я понимаю, что можно в основном классе написать addChild(TextInitter); и тогда всё просто, но это уже другой подход.

belv 09.08.2013 12:40

Цитата:

P.S. Я понимаю, что можно в основном классе написать addChild(TextInitter); и тогда всё просто, но это уже другой подход.
В вашем случае только такой подход и подходит, а так как Вы хотите сделать никогда у Вас не выйдет.
Вы пытаетесь положить лист бумаги в самого себя.
Все визуальные объекты на экране располагаются, как в матрешка в матрешке.
Да и TextField не является DisplayObjectContainer-ом и у него нет метода addChild об этом Вам и пытается сказать компилятор.

Wolsh 09.08.2013 12:50

ТекстФилд — закрытый контейнер. У него НЕТ метода addChild(), о чем красноречиво написано в тексте ошибки.

Цитата:

Хорошо, значит, надо юзать что-то вроде stage.addChild(this);
1) Никогда не добавляйте ничего в stage.
2) У this свойство stage появится ТОЛЬКО ПОСЛЕ добавления this в Список Отображения.

Цитата:

но это уже другой подход.
Единственно верный, как ни странно.

pS Я уже просил Вас перестать называть переменные с большой буквы?

Fogflasher 09.08.2013 13:08

belv, Хм, просто, я хотел сделать заготовку для прдыдущей программки обрабатывающей нажатие.
И хотел сделать чтобы в конструкторе основного класса просто было:
Код AS3:

textInitter = new TextInit();
mouseInitter = new MouseInit();

И при инициализации обоих субклассов уже была готовая программа : )

Насчет TextField понял. Но ведь можно пронаследовать и от Sprite, нет?


Цитата:

Сообщение от Wolsh (Сообщение 1143142)
1) Никогда не добавляйте ничего в stage.
2) У this свойство stage появится ТОЛЬКО ПОСЛЕ добавления this в Список Отображения.

По первому пункту, а почему, кстати?
Могу предположить, что наверное нужно просто грамотно юзать AddChild и тогда в этом не будет необходимости.
Насчет второго пункта не знал, спасибо.

Насчет больших буков : ) да, было такое. В данном случае, я наверное так сделал потому, что имена то классов у нас же в кэмэл-кэйзе, и с большой буквы. Ну и вроде как почему-бы именам экземпляров не быть такими же.

P.S. По поводу единcтвенно-верности, а разве нельзя вот так:
Код AS3:

public class TextInit extends Sprite

тогда AddChild метод будет существовать, и можно будет финт провернуть используя внутреннюю переменную типа TextField.

belv 09.08.2013 13:25

Вы наследуете от TextField, чтобы Ваш объект обладал всеми свойствами TextField.Если вы унаследуете от Sprite, то Ваш TextInit будет обладать всеми свойствами Sprite.И все равно нельзя положить самого в себя, хоть у него и будет метод addChild().Добавьте в свой класс TextInit слушатель события на клик мыши и пусть он там себе живет спокойно, не надо придумывать
Код AS3:

mouseInitter = new MouseInit();


Fogflasher 09.08.2013 14:28

belv, Не совсем понимаю что вы имеете ввиду.
Ну вот например если класс TextInit сделать таким:

Код AS3:

package
{
 
        import flash.display.*;
          import flash.text.*;
          import flash.events.*;
 
        public class TextInit extends TextField
                  {
                        public var mouseInitter = new MouseInit();
//                        private var clickCounter:uint = 0;
 
                        public function TextInit()
                        {
 
                                trace("TextInit instance created!");
                                this.text = "MouseClick";
                                this.x = 50;
                                this.y = 50;
                                this.selectable = false;
                                this.autoSize  = TextFieldAutoSize.LEFT;
 
 
                                this.addEventListener(MouseEvent.CLICK, clickTrigger);
 
 
 
                        }
 
//                        private function clickTrigger(e:MouseEvent)
//                        {
//                                clickCounter ++;
//                                this.text = "MouseClick: triggered " + String(clickCounter) + " times";
//                        }
 
                }
 
}

И допустим в отдельном классе MouseInit.as находится обработчик события clickTrigger(), то нифига не понятно, как его оттуда вызвать. Произвольные, ипровизационные варианты, такие как:

Код AS3:

this.addEventListener(MouseEvent.CLICK, mouseInitter.clickTrigger);
this.addEventListener(MouseEvent.CLICK, mouseInitter.clickTrigger());
this.addEventListener(MouseEvent.CLICK, MouseInit.clickTrigger);

Не работают.

Но кстати, если убрать камменты в этом классе, и отказаться вообще от класса Мыши, то всё работает.

Однако, интересно было бы научится вызывать метод из другого класса.

Wolsh 09.08.2013 14:29

Цитата:

По первому пункту, а почему, кстати?
Потому что Stage это плеер, а не Ваша программа. Да, он наследует контейнер, чтобы Вы (а вообще-то, Вас никто и не спрашивает) могли добавить в него свою программу. Но все составляющие Вашей программы должны находиться в Вашей программе и не сбегать из дома в Страшный Черный Лес. Документ-класс — вот Ваш максимальный общий контейнер. Stage именно его позиционирует, масштабирует и тд и тп. А то что Вы туда навыкидываете из своего приложения — уже ничье. Это как если бы в магазине Вам пиво налили не В бутылку, а просто ИЗ кеги. Во Вселенную. По-русски — "на пол".

belv 09.08.2013 14:38

Я рекомендовал Вам сделать так
Код AS3:

package
{
 
import flash.display.*;
import flash.text.*;
import flash.events.*;
 
        public class Main extends Sprite
        {
                public var textInitter:TextInit;
 
                public function Main()
                {
 
                        textInitter = new TextInit();
                        addChild(textInitter);
                }
        }
}

Код AS3:

package
{
          import flash.text.*;
          import flash.events.*;
 
        public class TextInit extends TextField
                  {
                        private var clickCounter:uint = 0;
                        public function TextInit()
                        {
 
                                trace("TextInit instance created!");
                                this.text = "MouseClick";
                                this.x = 50;
                                this.y = 50;
                                this.selectable = false;
                                this.autoSize  = TextFieldAutoSize.LEFT;
 
 
                                this.addEventListener(MouseEvent.CLICK, clickTrigger);
 
 
 
                        }
 
                        private function clickTrigger(e:MouseEvent):void
                        {
                        clickCounter ++;
                        this.text = "MouseClick: triggered " + String(clickCounter) + " times";
                        }
 
                }
}


Fogflasher 09.08.2013 14:39

Вложений: 1
Wolsh, не совсем понимаю что такое контэйнер, это что-то абстрактное, или конкретный класс?

Вот если посмотреть на картинку Мука:

Вложение 29883

То, вроде как получается что Stage это и есть DisplayObjectContainer, или это не совсем так?
(Торможу, Stage на картинке есть отдельно, пардон).

Но всё еще интересно где, опираясь на эту картинку, находится мой документ-класс-контэйнер, или опять же тут нельзя прямо строить параллели.

Fogflasher 09.08.2013 14:51

belv, Ну да, ясно, то есть двухклассовое решение.

И всё-таки, остается непроясненным, можно как-то обратится из класса TextInit в отдельный класс MouseInit через слушатель?
Может в данной ситуации это вообще невозможно.
Ну или в лучшем случае, сопряжено с чем-то, о чем пока мне лучше не знать )))


Часовой пояс GMT +4, время: 12:02.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.