Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java ME (J2ME) > Принцип смены содержимого экрана? |
Автор: Kalisnik 1.1.2012, 22:48 |
Допустим есть у меня форма с кнопками и текстовыми полями. Одна из кнопок формы должна вывести на экран новые кнопки и текстовые поля. Какова логика этого действа? Мне нужно создать две формы и поочередно выводить их на дисплей? |
Автор: Pawl 9.1.2012, 19:51 | ||||||||||||
Да, именно так. Создаешь класс - наследник Form и реализуешь в нем интерфейс CommandListener (например,
Первая команда ассоциирует слушатель событий с объектом MyForm, вторая - позволяет отобразить MyForm на мониторе. Этот метод надо вызвать в вызывающей форме, к примеру, как реакцию на нажатие в ней какой-нибудь кнопки, после чего MyForm и отобразится. CommandListener может понадобиться при возврате обратно в вызывающую форму:
Добавлено через 3 минуты и 59 секунд ой, опечатался! В методе show надо писать
Добавлено через 7 минут и 56 секунд В принципе, можно даже в вызывающе форме создать объект myForm класса MyForm и там же вызвать метод display.setCurrent(myForm) - результат будет тот же, но тогда
|
Автор: Kalisnik 12.1.2012, 16:26 |
Спасибо за подробный и доступный ответ! Я только начал осваивать Java и JavaME в том числе, так что думаю эта веточка форума еще оживится в самое ближайшее время. ![]() |
Автор: PiyodaiSiyo 8.2.2012, 10:11 |
А еще лучше общий Listener в мидлете чтоб ловил и команды и Displayable(от какой Form пришла команда) |
Автор: oxigen 9.2.2012, 18:30 |
Далеко не всегда это оправдано. Вводить дополнительный listener, который должен знать обо всех формах и как с какой и куда переходить. Ведь действительно часто нужно по кнопке BACK вернуть предыдущую форму. А значит этот listener должен знать не только какая форма открыта сейчас, но и какая была открыта перед ней, чтоб обеспечить возврат. А значит нужно как-то продумывать, чтоб он всегда знал о смене текущей формы... Можно, но излишних сложностей много. |
Автор: PiyodaiSiyo 19.2.2012, 01:31 | ||||
допустим у вас формы-поля в мидлете :frm1,frm2,....,frmN. (также все они являются потомками "деда" Displayable) в обработчике (один ! на все формы) мидлета после каждого уловленного события вы знаете от кого пришло событие по параметру Displayable d,а также по параметру Command c что за команда. вы же фильтруете в мидлете ,скажем
вуаля все как на ладони никакой "статики" все "закапсулированно"... я не пойму как еще проще организовать,тем более что такая схема была предложена у Пирумяна,вспомните... |
Автор: oxigen 22.2.2012, 12:46 | ||||
Простой пример. Есть 2 формы frm1 и frm2. У каждой в меню есть пункт "settings" по которому показываем форму settingsFrm. В форме settingsFrm есть пункт "back", по которому вы должны вернуться на ту форму, из которой была открыта settings И как это реализовать?
Да, конечно мы можем в листенере по нажатию на settings сохранять текущую форму и восстанавливать по back именно ее.
Но: - это как раз излишняя сложность - хранить в листенере дополнительные данные о предыдущей форме. (это в простом примере только об одной) - это будет работать ТОЛЬКО если settingsFrm будет открываться через меню. А она может и по какому-то событию открываться. |
Автор: Kalisnik 27.2.2012, 16:03 | ||||||||
Ух! - вернулся. Получилось так что с последнего поста Джаву я забросил. Но, теперь я вновь с вами! ![]() ![]() oxigen, я не знаю какие Вы увидели сложности. Я реализовал возврат на предыдущую форму с помощью стека - логика придельно проста. В коде ниже можно посмотреть. ![]() P.S. Если переход на следующую форму идет по какому-то событию, а не через меню формы, то это же событие и будет запихивать информацию о текущей форме все в тот же стек. Все классы находятся в пакете newpackage: файл Midlet.java (главный класс)
Файл Stra.java
Файл Stra2.java
Файл Stra3.java
|
Автор: oxigen 29.2.2012, 15:40 | ||||||||
Сложность будет в сложном приложении. Тут у Вас фактически паттерн MVC (Model-View-Controller) используется. Model - стек View - Stra* классы Controller - мидлет. А MVC нужно использовать очень аккуратно и только когда без этого уж никак. Потому что он имеет нехорошее свойство - Controller разростается с дикой скоростью и очень быстро становится категорически нечитаемым. Сам однажды столкнулся с таким приложением. Само приложение было не то чтоб сильно сложным, но в контроллере метод переключения между формами перевалил за пол-тысячи строк и имел 5 или 6 уровней вложености. Ну да ладно, для простых приложений это не существенно. По поводу ООП: 1. Три абсолютно одинаковых класса Stra, Stra2 и Stra3. Это не нужно. Достаточно одного.
2. Никогда не обращайтесь напрямую к полям класса.
За такое будут больно бить по рукам. Все поля класса всегда должны быть объявлены как private (иногда protected - при использовании наследования) и доступ к ним только через геттеры и сеттеры. Объяснить зачем это не так просто, просто примите это. Как то, что дорогу можно переходить только на зеленый свет.
3. Классы Stra* нужны ли вообще? Обертка вокруг формы, которая ничего по сути не делает. Тут больше подойдет наследование.
|
Автор: Kalisnik 29.2.2012, 23:56 |
oxigen, огромнейшее спасибо! Ваш крайний пост содержит бесценную информацию для моего дальнейшего понимания Java и вообще концепции ООП. Все изложенно крайне доступно, лаконично, ни чего лишнего. По Вашим постам лекции читать можно. ![]() Ну и немного конкретики. Я тоже обратил внимание, что слушатель мой берет на себя всю нагрузку со всего приложения, что уже интуитивно мне не понравилось - расценил как слабое место видимо. Как же правильно переделать мой код, что бы избежать MVC? Делать для каждого класса свой контроллер (на каджый класс по слушателю)? Т.е. по сути вместо одного MVC на все приложение, создаем и инкапсулируем кучку мелких MVC'тиков? ![]() По поводу пункта №1. Как истенно ленивый человек, любящий подумать, я все больше понимаю красату принципов ООП. По счет пункта №2. Получается, для каждого поля мне нужно писать свои get и set методы? А если эти поля в классе исчисляются десятками? Спрашиваю со ссылкой на первый пункт. ![]() И пункт №3. Комментарий "Потому что Stra теперь и есть Form" окончательно уложил и утрес мои знания о наследовании классов. До меня дошло, что наследовать можно ведь ни только свои, но и классы библиотеки Java. И то, что хоть класс и наследник, это ему ни как не мешает заниматься своими собственными делами, даже порой отличными от наследуемого класса. ![]() Как ни крути, очень информативный для меня пост. Еще раз спасибо! |
Автор: oxigen 1.3.2012, 12:05 | ||||
MVC по своей сути нарушение инкапсуляции. Принцип инкапсуляции можно сформулировать так: Если что-то возможно сделать внутри класса, то это нужно делать внутри класса. Нажатие на кнопку происходит внутри формы, значит и слушать и максимально обрабатывать его нужно внутри формы. Если есть 3 статичных формы, то хранить их можно где-то отдельно. В классе мидлета, и запрашивать по необходимости.
С back вопрос неоднозначный на самом деле. Стек более гибкое решение, позволяет возвращаться сразу на N шагов назад и класть в него одну и ту же форму несколько раз. По счет пункта №2. Получается, для каждого поля мне нужно писать свои get и set методы? А если эти поля в классе исчисляются десятками? Поля вполне могут могут исчисляться десятками. Но геттеры и сеттеры нужны только для тех полей, которые нужны снаружи класса. Часть полей - используются только внутри самого класса. геттеры и сеттеры не нужны Часть полей устанавливается только один раз при создании объекта и их значения передаются в конструкторе. геттеры и сеттеры не нужны. А если снаружи нужно получать доступ к десяткам полей, то это обычно говорит или о плохо спроектированом классе (слишком большой) или о нарушении инкапсуляции (снаружи класса делаются операции, которые могли бы быть сделаны внутри класса). Обращаясь к полям через методы мы обеспечиваем большую безопастность, стабильность с одной стороны, а с другой получаем больший контроль над кодом. Все верно? Так и есть. Сеттер может выполнять проверку значения на допустимость. Може писать в лог. Даже если сейчас это не нужно - то предсказать, понадобится ли это в дальнейшем невозможно. Кроме того методы доступа позволяют изменять реализацию класса не меняя его интерфейс. Допустим сейчас есть
и вдруг понадобилось хранить этот field как Integer(автоупаковки в ME нет) или вовсе как String. Достаточно добавить пару строк в методы доступа. А не искать по всему коду, где используется прямой доступ к полю. Остальной код вообще не узнает о том, что тип field изменился. |
Автор: Kalisnik 1.3.2012, 18:18 |
А вот пример выше не совсем понятен. Если я не ошибаюсь, класс использующий какой-либо интерфейс должен в обязательном порядке реализовывать все методы используемого интерфейса. В примере выше интерфейс CommandListener реализует класс Midlet, но не реилизует метод commandAction. А в классе Stra все с точностью наоборот. Поскольку Stra не реализует интерфейс CommandListener, метод commandAction работать не должен(?). Разве что сделать наследование, либо того, либо другого класса. З.Ы. Кстати, что-то не проверял, возможно ли множественное наследование в Java? |
Автор: oxigen 1.3.2012, 18:41 | ||
Сорь, невнимательно скопипастил. Множественно наследовать можно только интерфейсы, но не реализацию.
|
Автор: Kalisnik 1.3.2012, 18:50 |
Получается в каждом из обектов stra* будет свой отдельный слушатель? Эти слушатели слушают если форма не активна? З.Ы. т.е. вопрос касательно затрат ресурсов. З.З.Ы. Хотя с таким вопросом я наверно маху дал ))) Ок. Спасибо! На сем наверно пока все. Пойду открывать новую тему. ![]() |
Автор: oxigen 2.3.2012, 15:08 |
Угу. Слушатель ничего не слушает в фоне. Это всего лишь метод, который будет вызван после нажатия на пункт меню. И по затратам ресурсов абсолютно неважно, в каком классе этот метод находится. |
Автор: Kalisnik 2.3.2012, 15:13 | ||||
Странное дело... при нажатии на любую кнопку Command получаю исключение вида: TRACE: <at java.lang.NullPointerException: 0>, Exception caught in Display class
|
Автор: oxigen 2.3.2012, 16:41 | ||
В конструктор добавь
|
Автор: Kalisnik 2.3.2012, 18:30 | ||||
да... стыдно. Кстати, мне кажется многие неоправдано боятся использовать статику? Ну вот такой получился у меня финальный вариант версии 0.5 ![]()
|
Автор: oxigen 2.3.2012, 20:18 | ||||
Неправильный вариант получился :( У вас при каждом нажатии будут создаваться новые "Форма2" и "Форма3". Старт - создали новый Stra("Форма1"). У него поля str2 = null и str3 = null Нажали 2 создали новый Stra("Форма2"). У него поля str2 = null и str3 = null Нажали 3 создали новый Stra("Форма3"). У него поля str2 = null и str3 = null Нажали 2 создали новый Stra("Форма2"). У него поля str2 = null и str3 = null Пройдите дебагером или sysout в конструкторе поставьте - сами увидите. static поля - общие для всех объектов класса, а нестатичные - свои для каждого объекта. А вот "Форма1" создастся один раз и будет работать правильно. Вы ее через статический static Midlet midl получаете.
От метода, судя по названию ожидаю, что он должен возвращать форму. Зачем он делает еще что-то неочевидное? Принимает Displayable просто чтоб положить его в стек. Логичнее будет выглядеть
P.S. Да, излишняя статика это вроде плохо. Правда совершенно не помню, почему :( Вроде там причины не технические, а идеологические. |
Автор: Kalisnik 2.3.2012, 20:50 | ||
Да, забыл здесь static поставить
Это и называется утечкой памяти? Я создавал каждый раз новые объекты, тем самым занимая память? Пишу в NetBeans. Отладчиком пока не научился пользоваться - это ведь и есть дебагер? Метод тоже исправил. Я его у Вас же и скопипастил. Потом баловался с ним, в итоге он был скопирован из класса Midlet целиком, и не прошел проверку на актуальность. ![]() В остальном нареканий нет? |
Автор: oxigen 3.3.2012, 11:38 | ||||||
private static Stra str2, str3; Тогда возникает один вопрос, Вот есть 3 формы. Абсолютно равноправные и равноценные. Но str хранится в Midlet а str2 и str3 в Stra. Явно просится их в одном месте хранить и однотипно пользоваться. Если в Stra, то
Это и называется утечкой памяти? Я создавал каждый раз новые объекты, тем самым занимая память? Дело не столько в расходовании памяти. Если есть необходимость создавать каждый раз именно новые формы - то создавайте. Тут скорее поведение будет отличаться. Если формы статические, то вызываете
А если формы будут каждый раз через new создаваться, то
Так что все зависит от того, какое поведение Вам нужно. Ага. Отладчик это дебагер. По NetBeans ничего подсказать не смогу. Никогда не пользовался. |
Автор: Kalisnik 3.3.2012, 17:55 |
Явно просится их в одном месте хранить и однотипно пользоваться. - заметано. Дело не столько в расходовании памяти. Если я не ошибаюсь, Java имеет механизм сборки мусора, так что, в принципе, что бы произошла утечка памяти нужно постараться? ![]() |
Автор: Kalisnik 14.4.2012, 19:22 |
oxigen, а по мимо MVC какие еще модели есть? Мне как-то сложно представить приложение без единого, общего контроллера... пусть даже оно максимально инкапсулировано. Ведь в любой стране должен быть свой президент или король. У высокоразвитых организмов - голова. Иначе, хаос. Как без контроллера? |
Автор: oxigen 17.4.2012, 11:15 |
С государством хороший пример. Чем больше аспектов контролирует государство - тем больше и сложнее его бюрократический аппарат. Вы идете в магазин - покупаете хлеб. Напрямую взаимодействуете с продавцом. Просто. А если Вы даете деньги государству, а оно дает их продавцу? То государство должно иметь данные обо всех продавцах, обо всех товарах, иметь возможность передать деньги от каждого продавца к каждому покупателю... Возникающие накладные расходы представляете. А в для программы президент/король - это программист. Именно вы создаете инструкции для поведения на все случаи жизни. И вопрос в том - дать эти инструкции сразу конкретным исполнителям или ввести для них дополнительный контроллер. Мне больше нравится первый подход - из-за наглядности. Смотришь на отдельный класс и видишь, что он будет делать в конкретных случаях. |