Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
JavaFX.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
5 Мб
Скачать
☆

3.2.3 Створення медіа програвача

Через те, що для кожної кнопки потрібно буде індивідуально налаштовувати реакцію на подію натискання, то замість циклу завантаження зображень потрібно викликати метод setButtonsActions(taskbar), в якому буде вся логіка, пов’язана із створенням кнопок.

Створити медіа програвач можна з допомогою одного рядку коду, але це не дасть необхідних навичок, отже потрібно зробити дещо складніше: наприклад розробити до програвача панель, де буде відображатися медіа джерело (шлях до файлу), регулятор гучності, кнопка старт/пауза, кнопка програвання наступного треку та кнопка програвання попереднього треку.

Для цього потрібно створити окремий клас в новому пакеті main з назвою MediaControl.

public class MediaControl extends BorderPane {

private MediaPlayer mp;

private MediaView mediaView;

private boolean stopRequested = false;

private boolean atEndOfMedia = false;

private Label errorLabel;

private Slider volumeSlider;

private HBox mediaBar;

private int fileIndex = -1;

private final StackPane mvPane = new StackPane();

private Label trackLabel = new Label();

private Button playButton = new Button(">");

private Button nextButton = new Button(">>");

private Button prevButton = new Button("<<");

public MediaControl(String mediaDir) {

}

}

MediaPlayer mp — це клас медіа програвача, в конструкторі якого вказується Media, яке буде програватися.

MediaView mediaView — це контейнер для MediaPlayer, в якому буде відображатися зображення.

StackPane mvPane — це контейнер, який буде містити в собі mediaView та mediaBar.

HBox mediaBar — це панель програвача, де будуть розміщатися кнопки, слайдер та напис.

Спочатку необхідно розробити логіку, пов’язану з медіа файлами. Через те що JavaFX має лімітовану кількість розширень медіа файлів, які можуть бути запущені у програвачі, необхідно зробити клас, який буде слугувати фільтром при пошуку файлів в каталозі за допомогою метода listFiles. Отже в пакеті utils створіть наступний клас:

public class FileFilterFx implements FileFilter{

private final String[] okFileExtensions = new String[] {"flv", "fxm", "aif", "aiff", "wav", "mp3"};

@Override

public boolean accept(File file)

{

for (String extension : okFileExtensions)

{

if (file.getName().toLowerCase().endsWith(extension))

{

return true;

}

}

return false;

}

}

Таким чином, okFileExtensions містить всі доступні розширення медіа файлів. В каталозі media потрібно створити каталог з медіа фалами, playlist наприклад.

В конструкторі класу MediaControl потрібно написати наступний код:

File dir = new File(mediaDir);

final File[] files = dir.listFiles(new FileFilterFx());

if (files.length == 0){

errorLabel = new Label("No avalible files was founded");

errorLabel.setStyle("-fx-text-fill: #ff0000;");

this.setCenter(errorLabel);

} else{

this.mp = new MediaPlayer(new Media(getNextFile(files)));

setStyle("-fx-background-color: #bfc2c7;");

changeMP();

mvPane.setStyle("-fx-background-color: black;");

setCenter(mvPane);

mediaBar = new HBox();

mediaBar.setAlignment(Pos.CENTER);

mediaBar.setPadding(new Insets(5, 10, 5, 10));

BorderPane.setAlignment(mediaBar, Pos.CENTER);

}

Якщо жодного файлу, який задовольняє умову не знайдено, то користувачеві буде виведено відповідне повідомлення. В іншому випадку зазантажується перший зі списку файл. changeMP() — це метод, який буде міняти треки, його код наведений нижче:

private void changeMP(){

mvPane.getChildren().remove(mediaView);

mediaView = new MediaView(mp);

mvPane.getChildren().add(mediaView);

mvPane.setAlignment(mediaView, Pos.CENTER);

trackLabel.setText("Track: " + mp.getMedia().getSource() + " ");

stopRequested = false;

setActions();

}

trackLabel — це напис, в якому відображається розміщення треку.

setActions — це метод, який з’вязує MediaPlayer з оброблювачами подій. Виглядає він наступним чином:

private void setActions(){

mp.setOnPlaying(new Runnable() {

public void run() {

if (stopRequested) {

mp.pause();

stopRequested = false;

} else {

playButton.setText("||");

}

}

});

mp.setOnPaused(new Runnable() {

public void run() {

playButton.setText(">");

}

});

mp.setOnEndOfMedia(new Runnable() {

public void run() {

playButton.setText("||");

stopRequested = true;

nextButton.fire();

}

});

}

В основному логіка цього метода відповідає зміненню напису на кнопці старт/пауза. Також тут присутня логіка, яка буде виконуватися після завершення програвання треку — nextButton.fire() імітує натискання користувачем на кнопку «наступний трек».

Тепер потрібно розробити методи, які реалізують логіку отримання наступного та попереднього треку:

public final String getNextFile(File[] files){

if (this.fileIndex >= files.length-1)

this.fileIndex = -1;

return files[++this.fileIndex].toURI().toString();

}

public final String getPrevFile(File[] files){

if (this.fileIndex <= 0)

this.fileIndex = files.length;

return files[--this.fileIndex].toURI().toString();

}

Також необхідно додати можливість зупиняти програвання медіа файлу ззовні:

public void stop(){

if (this.mp != null)

this.mp.stop();

}

Залишилось додати до панелі кнопки з логікою їх роботи, слайдер гучності та напис треку.

Нижче наведена логіка роботи кнопки старт/пауза, її потрібно додати в кінець конструктору класу MediaControl:

playButton.setOnAction(new EventHandler<ActionEvent>() {

public void handle(ActionEvent e) {

Status status = mp.getStatus();

if (status == Status.UNKNOWN || status == Status.HALTED) {

// don't do anything in these states

return;

}

if (status == Status.PAUSED || status == Status.READY || status == Status.STOPPED) {

mp.play();

} else {

mp.pause();

}

}

});

mediaBar.getChildren().add(playButton);

Кнопка переходу на попередній трек:

prevButton.setOnAction(new EventHandler<ActionEvent>() {

public void handle(ActionEvent e) {

mp.stop();

mp = new MediaPlayer(new Media(getPrevFile(files)));

mp.play();

changeMP();

}

});

mediaBar.getChildren().add(prevButton);

Кнопка переходу на наступний трек:

nextButton.setOnAction(new EventHandler<ActionEvent>() {

public void handle(ActionEvent e) {

mp.stop();

mp = new MediaPlayer(new Media(getNextFile(files)));

mp.play();

changeMP();

}

});

mediaBar.getChildren().add(nextButton);

Додавання до панелі пустого інтервалу, напису розміщення файлу, слайдеру гучності:

// Add spacer

Label spacer = new Label(" ");

mediaBar.getChildren().add(spacer);

// Add audio file path label

mediaBar.getChildren().add(trackLabel);

// Add the volume label

Label volumeLabel = new Label("Vol: ");

mediaBar.getChildren().add(volumeLabel);

// Add Volume slider

volumeSlider = new Slider();

volumeSlider.setPrefWidth(70);

volumeSlider.setMaxWidth(Region.USE_PREF_SIZE);

volumeSlider.setMinWidth(30);

volumeSlider.valueProperty().addListener(new InvalidationListener() {

public void invalidated(Observable ov) {

if (volumeSlider.isValueChanging()) {

mp.setVolume(volumeSlider.getValue() / 100.0);

}

}

});

volumeSlider.setValue(100);

mediaBar.getChildren().add(volumeSlider);

setBottom(mediaBar);

}

Залишилось підправити декілька моментів в файлі JavafxApp.java:

  1. Написати private MediaControl mediaControl; замість private MediaPlayer mediaPlayer;

  2. Відредагувати метод changeView

private void changeView(Node node) {

view.getChildren().clear();

if (mediaControl!=null)

mediaControl.stop();

view.getChildren().add(node);

}

  1. Створити метод setButtonsActions:

private void setButtonsActions(HBox taskbar){ taskbar.getChildren().add(ButtonCreator.createButton(getClass().getResource("media/images/icon-0.png").toString(), new Runnable() {

public void run() {

mediaControl = new MediaControl(getClass().getResource("media/playlist/").getFile());

changeView(mediaControl);

}

}));

}

Тепер можна запустити додаток і подивитись на результат (рис. 3.9, 3.10).

Рис. 3.9. Вигляд програвача при відсутності файлів