Вышли на финишную прямую — нам осталось совсем немного, нужно реализовать следующее:
- добавление файлов в список воспроизведения;.
- проигрывание этих файлов;
- переход по списку;
- управление звуком;
- вывод названия трека на экран;
- перемотка текущей песни.
Итак, начнем. Чтобы добавлять файлы в список воспроизведения, понадобится отдельная кнопка. Сделайте ее похожей на кнопку сворачивания окна, только изобразите на ней три точки. Если вы откроете в редакторе исходные файлы проекта, выложенные на диске, то увидите ее. Теперь подробно рассмотрим работу этой кнопки (листинг 1).
Содержание первых двух строк должно быть понятно, поскольку похожие примеры были разобраны в предыдущих частях статьи. А вот дальнейший текст требует разъяснений. Сначала создается диалоговое окно выбора файлов JFileChooser. Оно является одним из наиболее часто используемых в работе, так как почти в каждой программе требуется открывать какие-либо файлы. JFileChooser имеет множество опций, в частности использование фильтров, т. е. возможность отображать только те файлы, которые подходят условию. В рассматриваемом нами случае должны быть видны только MP3‑файлы и папки, поэтому нужно создать соответствующий класс (листинг 2).
Теперь следует указать на необходимость применения этого фильтра строкой dialogOpen.setFileFilter (new Mp3FileFilter ()). В результате при запуске окна JFileChooser будут видны только папки и файлы с расширением MP3.
Чтобы воплотить задуманное, вам понадобится несколько свойств: setMultiSelectionEnabled (true), позволяющее выбирать несколько файлов одновременно, и setAcceptAllFileFilterUsed (false), запрещающее просмотр любых файлов (мы разрешим отображение только MP3‑файлов). Далее программа проверяет, была ли нажата кнопка Open, и если была, то в переменную fileList (а она связана со списком песен) добавляются абсолютные пути выбранных файлов (file.getAbsolutePath ()).
Вот так реализуется множественный выбор MP3‑файлов с помощью диалогового окна JFileChooser.
Теперь вы готовы к решительному шагу — запуску медиафайла в проигрывателе. Сделайте это двойным щелчком на имени файла в списке воспроизведения, как принято в больших плеерах. Для этого достаточно добавить пару строк в код listviewPlaylist (листинг 3).
В данном фрагменте текста программы нужно вызвать функцию playMedia (), которая будет рассмотрена чуть позже, поскольку требует небольшой подготовки с вашей стороны. Добавить работоспособности интерфейсу можно, назначив событие onMouseClicked для кнопок перемотки (листинг 4).
Здесь представлен код для кнопки «Вперед». Он очень простой: при нажатии на кнопку проверяется условие достижения конца списка и в зависимости от результата выбирается следующий или первый трек, после чего запускается все та же незнакомая функция playMedia (). Кнопка «Назад» аналогична по функциональности, и ее код приводиться здесь не будет.
Ниже рассмотрим звук, точнее, его регулировку. Для этого следует разместить на форме Swing-компонент Slider (листинг 5).
Переменные layoutX и layoutY определяют положение слайдера на форме, min и max — минимальное и максимальное значения слайдера, value — значение по умолчанию. Параметр vertical показывает, что слайдер имеет вертикальное расположение, а height обозначает высоту компонента в пикселах. Теперь привязка к громкости MediaPlayer будет выглядеть как одна строка в переменных этого компонента:
volume: bind (9 — sliderVolume.value) / 10.
Вывести название трека на экран, оказывается, ничуть не сложнее, чем решить предыдущую задачу. Добавьте компонент Text на небольшой прямоугольник Rectangle (тот, что считается экраном вашего плеера) в центре вашей сцены (листинг 6).
Здесь самая главная строка — content: bind track. С ее помощью выводимый текст привязывается к переменной track типа String.
Чтобы не загружать статью еще одним огромным листингом, имеет смысл открыть исходные коды программы и найти то место, где на сцену нужно вывести элементы lineProgress и rectProgress. Первый из них — линия, по которой будет двигаться слайдер перемотки, второй — ползунок перемотки песни. Здесь следует применить переменную blocksMouse, запрещающую передавать событие вниз по слоям интерфейса. Данная возможность необходима для того, чтобы при перетаскивании ползунка не начинала двигаться ваша форма (напомню, что вы добавили возможность drag'n'drop для Stage во второй части статьи). Обработчик событий для этого компонента приведен в листинге 7.
В этом коде придется разобраться достаточно подробно. Во-первых, что такое timelineProgress?
TimelineProgress имеет тип TimeLine — один из базовых типов JavaFX, с которыми придется работать постоянно. TimeLine дает возможность изменять параметры вашего приложения в процессе его выполнения (листинг 8). Стоит рассмотреть его поподробнее. Ключевые переменные этого типа следующие:
- autoReverse — разрешает возврат анимации; по завершении анимации объект возвращается на исходную позицию по той же траектории;
- keyFrames — содержит последовательность KeyFrame;
- repeatCount — количество повторов Timeline;
- time — указывает, с какого времени начать проигрывание анимации.
В рассматриваемом случае repeatCount получил значение Timeline.INDEFINITE. Значит, анимация будет повторяться бесконечное количество раз.
В переменной keyFrames используется только один компонент. KeyFrame — своеобразная единица анимации, выполняющаяся необходимое количество раз с интервалом time. Action — функция, выполняющаяся в течение каждого периода времени. Ваша функция перемещает слайдер перемотки по линии, и нельзя допустить, чтобы он вышел за пределы этой полосы перемотки. Для этого и написана проверка на границы. Длина полосы перемотки — 350 пикселов.
Timeline имеет четыре функции:
- pause () — ставит анимацию на паузу, т. е. временно ее приостанавливает;
- play () — снимает анимацию с паузы либо запускает с указанной позиции;
- playFromStart () — запускает Timeline с самого начала;
- stop () — останавливает анимацию и возвращает все значения в начальные позиции.
После всей этой теории становится немного понятнее практика. В листинге 7 событие onMousePressed запоминает начальную позицию ползунка и останавливает анимацию. При перетаскивании вызывается onMouseDragged, где вы просто перемещаете ползунок по полосе перемотки. Опять же нужно постоянно следить за тем, чтобы Rectangle не выходил за границы. И наконец, когда вы отпускаете кнопку мыши, то вызываете resumeMedia() — функцию, продолжающую выполнять timelineProgress и включающую ваш трек в выбранном месте (листинг 9).
Здесь position — положение слайдера на полосе перемотки. Duration.valueOf () переводит некоторое значение в тип данных Duration — время. В данном контексте вы устанавливаете текущим временем внутри песни положение ползунка, умноженное на шаг выполнения Timeline. После чего следует возобновить выполнение timelineProgress ().
Осталась самая малость — разобраться с «Неуловимым Джо» — функцией playMedia(). Ее текст приведен в листинге 10.
Данная функция не была продемонстрирована в самом начале, так как тогда она оставила бы больше вопросов, чем ответов. Сейчас же все становится намного яснее. Эта функция вызывается при начале проигрывания песни. В качестве параметра в нее передается строка с путем и именем медиафайла. Далее следует произвести следующие шаги:
- Останавливаем проигрывание предыдущей песни.
- Слайдер перемотки устанавливаем в начальное положение.
- Переменную playPause, определяющую переключение кнопки «Пауза / Проигрывание», устанавливаем в true.
- Присваиваем переменной media новый медиафайл (здесь производится форматирование и приведение к принятому в JavaFX имени файла).
- Вычисляем media-DurStep — количество секунд, которые должны пройти между перемещением ползунка на один пиксел, для чего берем продолжительность песни и делим на длину полосы перемотки.
- Запускаем проигрывание файла.
- Запускаем наш Timeline с начала.
- Присваиваем переменной track (к ней привязано название песни, выводимое на экран) значение, которое будет выглядеть примерно как «название-песни.mp3».
Теперь все, ваша программа готова к выполнению своих непосредственных задач. Компилируйте код и проверяйте.
* * *
JavaFX предоставляет огромные возможности всем разработчикам. Эта технология совместила в себе всю мощь Java и простоту написания интерфейса для любых программ. Всего за несколько минут можно создать вполне функциональный код, а если потратить еще немного времени, то его будет не стыдно даже напечатать в журнале. Что и было продемонстрировано здесь на конкретном примере.
Исходные файлы примера размещены на «Мир ПК-диске»
JavaFX предоставляет огромные возможности всем разработчикам. Эта технология совместила в себе всю мощь Java и простоту написания интерфейса для любых программ. Всего за несколько минут можно создать вполне функциональный код, а если потратить еще немного времени, то его будет не стыдно даже напечатать в журнале.