본문 바로가기
자바

자바 자바fx 프로그레스인디게이터 progressIndicator [북붙따라하기]

by 세상 모든 것 들은 그 자신을 위해 존재한다. 2021. 1. 7.

progressIndicator   예제는 아래 링크의  지난

미디어 플레이어 MediaPlayer 사용법과 예제

 

를 기반으로 작업했습니다.

위의 링크로 가셔서 설명을 보고 오셔야 됩니다.

예제는 지난번과 연결이 되어 그대로 복붙 하시고 

사용하면 되나 미디어 플레이어의 예제에서 

사용한 소스파일 (동영상 파일)이 있어야 되고

그 소스 파일이 정확하게 예제와 일치하는 곳에 있어야 됩니다.

그래서 꼭 지난번 예제를 실행해 보지 않더라도 설명은 꼭 봐야

요번 ProgressBar 사용법과 예제가 제대로 실행이 됩니다.

 

사용 예제 ) 코드를 복붙 하여 실행해 보시기 바랍니다.

설명은  주석과 코드 아랫부분에  있습니다.

1. 메인 파일 예제입니다.(title 만 다르고 내용이 거의 변하지 않습니다.)

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class AppMain extends Application {
	@Override
	public void start(Stage primaryStage) throws Exception {
		Parent root = (Parent)FXMLLoader.load(getClass().getResource("main.fxml"));
		Scene scene = new Scene(root);
		
		primaryStage.setTitle("progressIndicator 예제 입니다.");
		primaryStage.setScene(scene);
		primaryStage.show();
		primaryStage.setAlwaysOnTop(true);
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

 

 

 

2. main.fxml  파일 예제입니다.

그대로 복붙 하여 테스트해보시면 됩니다.

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.media.MediaView?>
<?import javafx.scene.text.Font?>

<AnchorPane prefHeight="662.0" prefWidth="792.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainHandler">
	<children>
		<StackPane layoutX="114.0" layoutY="115.0">
		   <children>
      		      <ImageView fx:id="imageView" fitHeight="257.0" fitWidth="528.0" preserveRatio="false">
               <image>
                  <Image url="@audio.png" />
               </image>
            </ImageView>  
      		      <MediaView fx:id="mediaView" fitHeight="200.0" fitWidth="360.0" preserveRatio="false" />    
		   </children>
		</StackPane>
		<Button fx:id="buttonPlay" layoutX="25.0" layoutY="372.0" prefHeight="40.0" prefWidth="60.0" text="재생" />
		<Button fx:id="buttonPause" layoutX="255.0" layoutY="372.0" prefHeight="40.0" prefWidth="60.0" text="멈춤" />      
		<Button fx:id="buttonStop" layoutX="474.0" layoutY="372.0" prefHeight="40.0" prefWidth="60.0" text="중지" />
      <Label alignment="CENTER" layoutX="70.0" layoutY="36.0" prefHeight="47.0" prefWidth="414.0" style="-fx-border-color: gray;" text="동영상 출력 예제 입니다.">
         <font>
            <Font size="36.0" />
         </font>
      </Label>
      <TextField fx:id="textfield" layoutX="75.0" layoutY="580.0" prefHeight="40.0" prefWidth="202.0" />
      <Label alignment="CENTER" layoutX="14.0" layoutY="412.0" prefHeight="47.0" prefWidth="550.0" style="-fx-border-color: gray;" text="progressIndicator예제 입니다.">
         <font>
            <Font size="36.0" />
         </font>
      </Label>
      <ProgressIndicator fx:id="progressIndicator" layoutX="333.0" layoutY="479.0" prefHeight="165.0" prefWidth="360.0" progress="0.0" />	
	</children>
</AnchorPane>

 

3. MainHandler.java 핸들러 파일입니다.

그대로 복붙 하여 테스트하시길 바랍니다.

import java.net.URL;
import java.util.ResourceBundle;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.util.Duration;

public class MainHandler implements Initializable {
	@FXML
	private MediaView mediaView;
	@FXML
	private ImageView imageView;
	@FXML
	private Button buttonPlay;
	@FXML
	private Button buttonPause;
	@FXML
	private Button buttonStop;
	

//---------------------------------progressIndicator----------------------------
	@FXML private ProgressIndicator progressIndicator;
//------------------------------------------------------------------------------
	
	
	@FXML
	private TextField textfield;

	private boolean booEnd;

	@Override
	public void initialize(URL location, ResourceBundle resources) {
		// 미디어 객체를 소스 폴더의 video.mp4를 이용해만들어 줍니다.
		// 미디어 플레이어에 사용할 파일을 정해 줍니다.
		Media media = new Media(getClass().getResource("source/video.mp4").toString());

		// 미디어 플레이어 생성 및 미디어 뷰에 설정
		MediaPlayer mediaPlayer = new MediaPlayer(media);
		mediaView.setMediaPlayer(mediaPlayer);

		// 해당 상태가 되면 실행할 Runnable 설정
		mediaPlayer.setOnReady(new Runnable() {

			// 화면이 동영상이 실행 되는 쓰레드 사용합니다.
			@Override
			public void run() {

				//리스너를 사용 변화하는 값(현재 위치값)을 프로그레스 바에 적용하는 부분
				mediaPlayer.currentTimeProperty().addListener(new ChangeListener<Duration>() {
					
					//변화 하는 값을 더블변수에 전달하기 위해 사용하는 부분
					//대부분 똑같은 코드로 이루어져 있으므로 변호 하는 값을 얻고 싶을 때 사용하시면 됩니다.
					//이구문을 자주 사용하시는 분은 암기 하겠지만 굳이 그럴필요가 없는 구문 입니다.
					//사용하다보면 금방 암기가 됩니다.
					@Override
					public void changed(ObservableValue<? extends Duration> observable, Duration oldValue,
							Duration newValue) {
						//정형화된 부분입니다.실행되고 있는 미디어의 현재 진행시간을 얻을 때
						//사용하는 구문입니다. 복붙하여 사용하시면 되겠습니다.
						
//-----------------------------progressIndicator  -----------------------------------------
						
						double dCurTime = mediaPlayer.getCurrentTime().toSeconds();
						double dDurTime = mediaPlayer.getTotalDuration().toSeconds();
						
						//총시간과 실행 시간이 정확하게 맞지 않아 내림으로 처리 하여 조정하는 부분
						double dDurTime2 = Math.floor(dDurTime);
						double dLastTime = dCurTime / dDurTime2;
						//이부분도 정형화된 부분입니다.실행되고 있는 미디어의 현재 진행시간을 얻을 때
						//사용하는 구문입니다. 복붙하여 사용하시면 되겠습니다.
						progressIndicator.setProgress(dLastTime);
						
						// int로 형변환 하지 않으면 소수점 아래자리 까지 나옵니다.
						//필요하신 경우에는 (int) 형변환을 없애고 사용하시면  됩니다.
						//textfield.setText("현재 진행 : "+(int) dCurTime + " 초/ 총길이 : " + (int) dDurTime + " 초");
						textfield.setText("현재 진행 : "+ dCurTime + " 초/ 총길이 : " + dDurTime2 + " 초");
						
						
						
						
						
						
					}
				});

				// 시작시 플레이 버튼만 활성화 하고
				// 나머지는 비활성화 함.
				buttonPlay.setDisable(false);
				buttonPause.setDisable(true);
				buttonStop.setDisable(true);

			}
		});

		// 플레이 뒤고 있을 경우의 버튼 활성 비활성의 상태
		// 아래의 경우도 똑 같은 경우입니다.

		mediaPlayer.setOnPlaying(() -> {
			buttonPlay.setDisable(true);
			buttonPause.setDisable(false);
			buttonStop.setDisable(false);
		});

		mediaPlayer.setOnPaused(() -> {
			buttonPlay.setDisable(false);
			buttonPause.setDisable(true);
			buttonStop.setDisable(false);
		});

		// 비디오가 끝났을 경우의 처리
		// booEnd 변수에 true 를 넣어 재생 버튼을 눌렀을 때
		// 처음 부터 실행 할것인지를 결정 하게 한다.

		mediaPlayer.setOnEndOfMedia(() -> {
			booEnd = true;
			buttonPlay.setDisable(false);
			buttonPause.setDisable(true);
			buttonStop.setDisable(true);
		});
		mediaPlayer.setOnStopped(() -> {
			mediaPlayer.seek(mediaPlayer.getStartTime());
			buttonPlay.setDisable(false);
			buttonPause.setDisable(true);
			buttonStop.setDisable(true);
		});

		// 버튼 ActionEvent 처리
		buttonPlay.setOnAction(event -> {

			// 플레이 버튼을 눌렀을때
			// 동영상이 끝날상태 즉 booEnd 에 true 가 들어 가있을 경우에는
			// 종료하고 처음으로 재생시점을 이동한다.
			// 그리고 다시booEnd에 false 를 대입해 지금 동영상이
			// 끝이 아니라는 것을 알려준다.
			if (booEnd) {
				mediaPlayer.stop();
				mediaPlayer.seek(mediaPlayer.getStartTime());
			}
			mediaPlayer.play();
			booEnd = false;
		});

		// 각가의 버튼을 선택 했을 때의 기능을 설정 하는 부분
		buttonPause.setOnAction(event -> mediaPlayer.pause());
		buttonStop.setOnAction(event -> mediaPlayer.stop());
	}
}

 

 

있어 보이는 효과가 큰 파트입니다.

동영상이나 음악 아니면 작업현황 등을 표현할 때 한 번씩 사용합니다.

자주는 사용을 안 하게 됩니다.

 

아래는 실행 영상입니다.

 

 

세상 모든 것들은 그 자신을 위해 존재한다.

728x90
반응형

댓글