Как сделать кнопку неактивной javafx

Обновлено: 05.07.2024

Запросите дополнительную информацию, если это необходимо.

Это на андроиде.

Если вы хотите, чтобы кнопка не открывалась, вы можете использовать Button.setEnabled(false);

Вы можете использовать handler , Данный код делает вашу кнопку не нажатой в течение 1,5 секунд. и затем снова включите его.

Второй метод

Ты можешь использовать TimerTask который запускается в указанное время с повтором или один раз. Пожалуйста, обратитесь Обновление пользовательского интерфейса из документа таймера.

Вы можете сначала отключить кнопку с помощью setEnabled(false) и использовать postDelayed, чтобы включить его снова через определенный промежуток времени

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

Шаг 1

Для начало создаем новый JavaFX проект:


и в main.xml добавляем следующее содержимое:

Выглядеть наше окно будет так:


Шаг 2

Дальше создаем если нет класс Main.java, который будет стартовать наше приложение:

в 13 строке мы указываем созданный нами Scene в первом шаге.

Шаг 3

Теперь заходим в Controller.java и привязываемся к нашей кнопки через аннотацию @FXML по fx.id кнопки:

Метод initialize() будет вызываться как только приложение запустится.

В строке 15 мы добавляем addEventHandler, который будет определять событие и выполнять его.

MouseEvent.MOUSE_CLICKED – указывает, что это событие будет срабатывать при клике на кнопку.

handle(MouseEvent mouseEvent) – в этом методе мы описываем действие, которое выполнится при клике на кнопку.

Шаг 4

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

Для этого в файл main.fxml для компонента button добавим новый атрибут:

Для того чтобы все работало нам нужно зайти в контролер и добавить туда следующий метод:

В строке 14 мы видим метод, который и будет выполнятся при клике на кнопку, так как мы указали в разметке кнопки onAction для этого метода.

Шаг 5

Что в 3-м, что в 4-м шаге мы просто выполняем обработку события для кнопки просто разными способами.

Давайте запустим и посмотрим на результат:

ПОХОЖИЕ ПУБЛИКАЦИИ

14 комментариев к статье "JavaFX 2. Обработчик событий Button"

А что если надо увидеть Controller из Application? (Да, я понимаю, что не стоит этим злоупотреблять, но всё-таки?)

Создать переменную типа Controller и потом все что хочешь в ней делай)

Не похоже, чтобы какой-либо пример работал.

Всё прекрасно работает.

не пойму как решить данную проблему и с чем это может быть связано) может кто знает??

Кнопка - один из самых распространенных элементов управления в программировании. Наследуется от TextView и является базовым классом для класса СompoundButton. От класса CompoundButton в свою очередь наследуются такие элементы как CheckBox, ToggleButton и RadioButton. В Android для кнопки используется класс android.widget.Button. На кнопке располагается текст и на кнопку нужно нажать, чтобы получить результат. Альтернативой ей может служить компонент ImageButton (android.widget.ImageButton), у которого вместо текста используется изображение.

В студии кнопка представлена компонентом Button в разделе Widgets. Управлять размером шрифта, цветом текста и другими свойствами можно через атрибут textAppearance, который задействует системные стили. Выпадающий список данного свойства содержит огромный перечень вариантов. Также вы можете вручную задать конкретные индивидуальные настройки через отдельные свойства.

Если вы растягиваете кнопку по всей ширине экрана (android:layout_width="match_parent"), то дополнительно рекомендую использовать атрибут android:layout_margin (или родственные ему layout_marginRight и layout_marginLeft) для создания отступов от краев экрана (веб-мастера знакомы с этими терминами).

Так как кнопка является наследником TextView, то использует многие знакомые атрибуты: textColor, textSize и др.

Три способа обработки событий нажатий на кнопку

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

Первый способ - атрибут onClick

Относительно новый способ, специально разработанный для Android - использовать атрибут onClick (на панели свойств отображается как On Click):

Имя для события можно выбрать произвольное, но лучше не выпендриваться. Далее нужно прописать в классе активности придуманное вами имя метода, который будет обрабатывать нажатие. Метод должен быть открытым (public) и с одним параметром, использующим объект View. Вам нужно выучить пять слов для создания метода, а сам метод поместить в класс (если вы ещё путаетесь в структуре Java-кода, то вставьте метод перед последней фигурной скобкой):

Обратите внимание, что при подобном подходе вам не придётся даже объявлять кнопку через конструкцию (Button)findViewById(R.id.button1), так как Android сама поймёт, что к чему. Данный способ применим не только к кнопке, но и к другим элементам и позволяет сократить количество строк кода.

Второй способ - метод setOnClickListener()

Более традиционный способ в Java - через метод setOnClickListener(), который прослушивает нажатия на кнопку. Так как для начинающего программиста код может показаться сложным, то рекомендуется использовать подсказки студии. Вот как это будет выглядеть. Предположим, у вас на экране уже есть кнопка button. В коде вы объявляете её обычным способом:

Следующий шаг - написание метода для нажатия. Напечатайте имя элемента и поставьте точку button. - среда разработки покажет вам список доступных выражений для продолжения кода. Вы можете вручную просмотреть и выбрать нужный вариант, а можно продолжать набирать символы, чтобы ускорить процесс. Так как с нажатиями кнопок вам часто придётся работать, то запомните название его метода (хотя бы первые несколько символов) - набрав четыре символа (seto), вы увидите один оставшийся вариант, дальше можно сразу нажать клавишу Enter, не набирая оставшиеся символы. У вас появится строка такого вида:

Курсор будет находиться внутри скобок и появится подсказка OnClickListener l. Начинайте набирать new OnClickListener. Здесь также не обязательно набирать имя полностью. Набрав слово Oncl, вы увидете нужный вариант и снова нажимайте Enter. В результате вы получите готовую заготовку для обработки нажатия кнопки:

Теперь у вас есть рабочая заготовка и сразу внутри фигурных скобок метода onClick() вы можете писать свой код. Рекомендую потренироваться и набить руку в создании заготовки. Это не так сложно, и с практикой навык закрепится автоматически.

Как вариант, можно вынести код для OnClickListener в отдельное место, это удобно, когда кнопок на экране несколько и такой подход позволит упорядочить код. Удалите предыдущий пример и начните писать код заново. Принцип такой же, немного меняется порядок. В предыдущем примере мы сразу прописали в методе setOnClickListener слушателя new OnClickListener. с методом onClick(). Можно сначала отдельно объявить отдельную переменную myButtonClickListener:

Во время набора активно используйте подсказки через Ctrl+Space. Набрали несколько символов у первого слова и нажимайте эту комбинацию, набрали после слова new несколько символов и снова нажимайте указанную комбинацию - заготовка будет создана за несколько секунд, а вы избежите возможных опечаток.

У нас есть готовая переменная, и теперь, когда вы будете набирать код button.setOnClickListener, то вместо new OnClickListener впишите готовую переменную.

Для новичка описание может показаться сумбурным и не понятным, но лучше самостоятельно проделать эти операции и понять механизм.

Третий способ - интерфейс OnClickListener

Третий способ является родственным второму способу и также является традиционным для Java. Кнопка присваивает себе обработчика с помощью метода setOnClickListener (View.OnClickListener l), т.е. подойдет любой объект с интерфейсом View.OnClickListener. Мы можем указать, что наш класс Activity будет использовать интерфейс View.OnClickListener.

Опять стираем код от предыдущего примера. Далее после слов extends Activity дописываем слова implements OnClickListener. При появлении подсказки не ошибитесь. Обычно первым идёт интерфейс для диалогов, а вторым нужный нам View.OnClickListener.

Название вашего класса будет подчёркнуто волнистой красной чертой, щёлкните слово public и дождитесь появления красной лампочки, выберите вариант Implement methods. Появится диалоговое окно с выделенным методом onClick. Выбираем его и в коде появится заготовка для нажатия кнопки.

Метод будет реализован не в отдельном объекте-обработчике, а в Activity, который и будет выступать обработчиком. В методе onCreate() присвоим обработчик кнопке. Это будет объект this, т.е. текущий объект нашей активности.

На первых порах такой способ также покажется вам сложным и непонятным. Со временем и опытом понимание обязательно придёт.

Лично я рекомендую вам использовать первый способ, как самый простой и понятный. Использование второго и третьего способа дадут вам представление, как писать обработчики для других событий, так как кнопка может иметь и другие события. Например, кроме обычного нажатия существует долгое нажатие на кнопку (long click). Один из таких примеров с методом касания я привёл в конце этой статьи.

О том, как обрабатывать щелчки кнопки я написал отдельную статью Щелчок кнопки/Счетчик ворон. Также кнопки часто будут встречаться во многих примерах на сайте. Про обработку длительный нажатий можно прочитать в статье, посвященной ImageButton.

Плодитесь и размножайтесь - это про кошек, а не про кнопки

Когда у вас одна кнопка в окне, то у вас будет один метод, две кнопки - два метода и так далее. Если у вас несколько кнопок, то не обязательно для каждой прописывать свой метод, можно обойтись и одним, а уже в самом методе разделять код по идентификатору кнопки. Если вы посмотрите на код в предыдущих примерах, то увидите, что в методе присутствует параметр View, который и позволяет определить, для какой кнопки предназначен кусок кода:

Предположим, у вас есть три кнопки:

Как видите, мы сократили количество кода. Теперь у нас один обработчик onClick(), в котором прописаны действия для трёх кнопок.

Сделать кнопку недоступной

Иногда нужно сделать кнопку недоступной и активировать её при определённых условиях. Через XML нельзя сделать кнопку недоступной (нет подходящего атрибута). Это можно сделать программно через метод setEnabled():

Как альтернативу можете рассмотреть атрибут android:clickable, который позволит кнопке не реагировать на касания, но при этом вид кнопки останется обычным.

Сделать кнопку плоской

Стандартная кнопка на экране выглядит выпуклой. Но в некоторых случаях желательно использовать плоский интерфейс. Раньше для этих целей можно было использовать TextView с обработкой щелчка. Но теперь рекомендуют использовать специальный стиль borderlessButtonStyle:

Кнопка сохранит своё привычное поведение, будет менять свой цвет при нажатии и т.д.

С появлением Material Design добавились другие стили, например, style="@style/Widget.AppCompat.Button.Borderless", который является предпочтительным вариантом. Попробуйте также style="@style/Widget.AppCompat.Button.Borderless.Colored"

Коснись меня нежно

Если вы внимательно понаблюдаете за поведением кнопки, то увидите, что код срабатывает в тот момент, когда вы отпускаете свою лапу, извините, палец с кнопки. Для обычных приложений это вполне нормально, а для игр на скорость такой подход может оказаться слишком медленным. В подобных случаях лучше обрабатывать ситуацию не с нажатием кнопки, а с его касанием. В Android есть соответствующий слушатель OnTouchListener():

У метода onTouch() есть параметр MotionEvent, позволяющий более тонко определять касания экрана. Если произойдет событие, когда пользователь коснулся экрана, то ему будет соответствовать константа ACTION_DOWN. Соответственно, если пользователь уберёт палец, то нужно использовать константу ACTION_UP. Таким образом, можете расценивать щелчок кнопки как комбинацию двух событий - касания и отпускания.

Получить текст с кнопки

Навеяно вопросом с форума. Задача - получить текст кнопки в методе onClick(). У метода есть параметр типа View, у которого нет метода getText(). Для этого нужно привести тип к типу Button.

Если у вас несколько кнопок привязаны к методу onClick(), то щелчок покажет текст нажатой кнопки.

Хотя есть и разные версии под разные java, желательно выбрать соответствующую вашей. Например, у нас в компьютерном классе всюду java 8, поэтому лучше скачать 8 версию.

Imgur

Восьмая версия еще особенно хороша тем что ей не надо админских прав и можно ставить в компьютерных классах

Imgur

Imgur

Imgur

по завершению установки запустится SceneBuilder

Imgur

но он нам пока не нужен, так что можно его закрыть.

Делаем новый проект типа JavaFX

Imgur

назову его CustomTypeGUI

Imgur

получаем такую структуру проекта:

Imgur

Принцип организации javafx интерфейса

Кликнем дважды на файлик sample.fxml чтобы открыть его и увидим там что-то такое:

fxml – это такой аналог html, только в рамках java, тут даже есть всякие импорты. И есть тэги, определяющие что будет отображаться. Тут к нас пока только один тэг GridPane, которые используется для выравнивания компонент по сетке.

Правда пока выравнивать нечего, так что пока это по сути пустой контейнер.

Особо стоит обратить внимание на атрибут fx:controller в нем указан класс вместе с полным путем, в котором мы будем писать код для интерфейса.

И так, попробуем запустить программу. Увидим что-то такое

Imgur

Откуда же это все взялось? А на самом деле ничего хитрого нет. Открываем файлик Main.java и видим

Добавляем кнопку

Вернемся к файлу sample.fxml. Теперь запустим SceneBuidler, выбираем Open Project

Imgur

и открываем наш файлик. Увидим что-то такое

Imgur

Перетянем теперь кнопку на форму. Так как пока у нас пустой GridPane наша форма выглядит как пустота. Но тянуть можно:

Сохраним перетянутое Ctrl+S и переключимся обратно в Idea. И глянем что у нас выросло с файлике sample.fxml. Там у нас будет такое:

Видим, что тут много чего поменялось. Появились какие-то Constraints (это так называем ограничения на размеры колонок и строк, нам они пока не интересны).

Ну и главное, что тут появился тег children и внутри него наша кнопочка

  • text – это то что написано на кнопке
  • mnemonicParsing – это специальный тег для обработки горячих клавиш, но нам это сейчас неинтересно, так что можно игнорировать

Можно попробовать запустить:

Imgur

ура, есть кнопочка! =)

Добавляем реакцию на нажатие

Но кнопка — это не кнопка если нажимая на нее ничего не происходит. Попробуем добавить реакцию на клик.

Переключимся на файл Controller.java:

Помните я упомянул атрибут fx:controller=”sample.Controller” внутри sample.fxml, так вот мы сейчас в том самом классе на который указывал этот атрибут. За счет него происходит связывание интерфейса и логики (контроллера).

Чтобы добавить реакцию на клик достаточно сделать следующие операции.

Можно даже попробовать запустить. И потыкать кнопку

Imgur

хехе, очевидно ничего не произойдет. Мы ж пока функцию не привязали =)

А теперь переключимся на SceneBuilder и привяжем кнопку к функции

не забудем сохранить, и запустим проект по-новому

Кстати можно открыть файлик sample.fxml и глянуть что там произошло:

Читаем значение из текстового поля

Ну тыкать на кнопочки и выполнять всякие функции — это конечно важное умение. Но не менее важно уметь считать значение из поля, например, текстового.

Делается это в некотором роде проще чем привязка кнопки.

Например, хочу я добавить поле для ввода текста, и чтобы по нажатию на кнопку выводилось содержимое этого поля.

Что я сделаю? Сначала создам в классе поле, через которое образуется связь

теперь переключимся на SceneBuilder, перетащим текстовое поле на форму, а затем привяжем его к нашему классу, путем указания свойства fx:id:

если вдруг у вас в этом поле ничего не высветилось, то можете смело вписать туда вручную txtInput.

Сохраним в SceneBuilder и вернемся обратно в Idea. Если глянуть в файлик fxml то увидим

Imgur

теперь вернемся в наш Controller и подправим метод showMessage:

Меняем значения текстового поля

О, давайте еще научимся изменять значение в списке, но тут все просто

В принципе вот и вся наука =)

  • добавил поле в контроллер
  • добавил объект в SceneBuilder
  • связал через fx:id, либо связал с методом.

Теперь можно пилить что-нибудь посложнее.

Наверное, не будем рассматривать как делать конкретно приложение под вашу задачку. Все-таки в прошлом году мы уже пилили интерфейсы. И принцип должен быть понятен.

Но, очевидно, полезно рассмотреть, как можно добавлять разные компоненты и заставить их реагировать на ваши данные.

К тому же в JavaFX есть много хитрых особенностей, которые в WindowsForms не встречалось.

И так, попробуем добавить выпадающий список. Действуем по выше предложенному алгоритму. Сперва добавим поле в контроллер:

теперь добавляем на форму

затем подключаем по fx:id

Imgur

не забываем сохраниться в SceneBuilder.

Запускаем и проверяем:

Imgur

Ура! Есть список! Правда пустой пока…

Заполняем список (интерфейс Initializable)

И вот незадача, как же его заполнить? У нас по сути голый класс Controller, без ничего. Давайте попробуем в конструкторе:

запускаем и… бдыщь

Imgur

суть стенаний виртуальной машины заключается в том, что comboBox нулевой. А нулевой он потому что привязка полей помеченных декоратором @FXML происходит уже после вызова конструктора, где-то в терньях фреймворка JavaFX.

Поэтому добавление элемента в конструкторе не прокатит.

Что ж делать? Оказывается все просто! Надо наследоваться от некого интерфейса Initializable и переопределить одну функцию, которую используется как своего конструктор формы. Делается это так

загоним теперь в метод initialize наш вызов добавления элемента

Imgur

Добавляем реакцию на переключения списка

Давайте сначала добавим еще несколько элементов

Есть как минимум два способа добавить реакцию на переключения

Через SceneBuilder

Imgur

не забываем сохраниться.

2) Затем в IDEA тыкаем правой кнопкой мыши на название метода

Imgur

выбираем первый пункт Show Context Actions, а затем:

Imgur

3) Нас перекинет в контроллер где мы увидим новодобавленный метод

в принципе, его можно было и руками добавить >_>

Этот метод будет вызываться каждый раз, когда мы будем переключать элемент списка. Давайте чего-нибудь там будем выводить:

Через лямбда-функцию

Ну тут просто в методе инициализации привязываете лямбда-функцию к реакции на изменение свойства.

Я на лекции расскажу что тут происходит на самом деле

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

добавим в Controller:

теперь подключим checkbox к форме


ну теперь мы можем, например, управлять им кликая на кнопку:

ой, забыли кнопке указать другую функцию


Вот теперь красота! =)

кстати если хотите текст поменять то правьте поле Text:


Одним из важных принципов при разработке приложений, а особенно GUI приложений заключается в том, что состояние формы (значения в полях, размеры и положение) после закрытия приложения и при последующем открытии должно сохранятся.

Как правило для хранения состояния приложения используют простые файлы в каком-нибудь распространённом формате типа *.xml, *.ini, *.json

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

Подключаем обработчик закрытия формы

Мы будем сохранять в момент закрытия формы.

Вот мы недавно уже мучались с поиском момента создания формы, теперь так же помучаемся с определением момента закрытия формы.

К сожалению, тут простым интерфейсом не отделаешься. Вообще в JavaFX нет как такового понятия формы.

Там есть понятие stage (англ. состояние, сцена как место где происходят события), которое представляет собой окно приложения и scene (англ. тоже сцена, но уже в качестве события) которая, если немного упростить, представляет собой fxml файлик + контроллер.

Ну и ясно что именно к scene привязывается класс Controller. И так как scene за окно формы (то бишь stage) не отвечает, то из него и нельзя получить прямого доступа к событию закрытия окна.

Но можно получить не прямой. Для этого надо поймать событие закрытия формы (то бишь stage) и проксировать его в Controller. Делается это так:

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

теперь идем в Main и делаем магические пассы:

Сохраняем состояние формы в файл

И так, хотя данные на форме и так уже имеют привязанные поля, и можно считывать значения сразу с формы и сразу куда-то писать мы так делать не будем. Потому что в этом случае нам самим придется организовывать запись в файл, а затем еще учится парсить результат обратно. В общем, в современной разработке, это такой себе подход. Да и в прошлом семестре мы этого и так наелись.

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

И так создаем новый класс

Imgur

фиксируем в него поля

теперь идем в Controller и в методе закрытия формы прописываем:

а теперь добавляем сериализацию в файл. Тут все просто

теперь проверяем как работает

Так-так, файлик появился. У меня внутри такие строчки:

теперь попробуем добавить чтение из файла. Чтение стало быть делаем в инициализаторе:

Читайте также: