Java

javafx - list View , tableView, media, chart

amungstudy 2023. 6. 7. 00:01

public class ViewController implements Initializable {

 

@FXML

private ListView<String> listView;

@FXML private TableView<PhoneVO> tableView;

@FXML private ImageView imageView;

@FXML private TextField txtName;

@FXML private Button btnUpdate;

 

 

 

@Override

public void initialize(URL location, ResourceBundle resources) {

// ListView에 출력 항목을 items 라고 함.

// 항목을 전달하는 class로 ObservableArrayList를 사용

 

String[] strs = new String[] {

"갤럭시S1","갤럭시S2","갤럭시S3","갤럭시S4",

"갤럭시S5","갤럭시S6","갤럭시S7"

};

List<String> strList = Arrays.asList(strs);

 

//ObservableList : Listener를 추가할 수 있는 List. new연산자로 생성불가. 정적메소드 써서 생성

ObservableList<String> list

= FXCollections.observableArrayList(

//"갤럭시S1","갤럭시S2","갤럭시S3","갤럭시S4","갤럭시S5","갤럭시S6","갤럭시S7"

strList

);

 

listView.setItems(list);

 

// listView 에 선택 항목을 지정 - 0번째 인덱스 번호를 선택항목으로 지정

listView.getSelectionModel().select(0);

 

// listView에 선택 항목 변경 감지

listView.getSelectionModel()

.selectedIndexProperty().addListener(new ChangeListener<Number>() {

// index번호는 숫자니까 Number로 제네릭 지정함.

@Override

public void changed(

ObservableValue<? extends Number> observable,

Number oldValue, Number newValue) {

// 나열된 항목 중 사용자가 선택한 항목이 새로 변경이 되었을 때

// 변경된 index 번호를 전달

System.out.println(oldValue);

System.out.println(newValue);

int index = newValue.intValue();

System.out.println(list.get(index));

tableView.getSelectionModel().select(index);

tableView.scrollTo(index);

}

});

 

// tableView - 항목 초기화 - PhoneVO

// tableView List정보를 저장할 List 생성

ObservableList<PhoneVO> phoneList = FXCollections.observableArrayList();

// phone01.png ~ phone.07.png

for(int i = 1; i<=7; i++) {

PhoneVO phone = new PhoneVO("갤럭시S"+i,"phone0"+i+".png");

phoneList.add(phone);

}

System.out.println(phoneList);

 

/*

TableColumn<PhoneVO,?> tColumnName = tableView.getColumns().get(0);

tColumnName.setCellValueFactory(new PropertyValueFactory<>("name")); //필드이름 가져옴

 

TableColumn<PhoneVO,?> tColumnPath = tableView.getColumns().get(1);

tColumnPath.setCellValueFactory(new PropertyValueFactory<>("path"));

*/

 

Field[] fields = PhoneVO.class.getDeclaredFields();

for(int i = 0; i < fields.length; i++) {

String fieldName = fields[i].getName();

System.out.println(fieldName);

TableColumn<PhoneVO,?> tColumn = tableView.getColumns().get(i);

tColumn.setCellValueFactory(new PropertyValueFactory<>(fieldName));

}

 

tableView.setItems(phoneList);

 

// tableView에 항목 변경 감지 Listener 추가

// 선택된 항목을 관리하는 Model class

// JavaFx에서 다양한 데이터를 관리하기 위해 모델 이라는 개념을 도입

// Model은 동적으로 조작하는 데이터를 관리하기 위한 객체

tableView.getSelectionModel()

.selectedItemProperty()

.addListener(new ChangeListener<PhoneVO>() {

@Override

public void changed(ObservableValue<? extends PhoneVO> observable,

PhoneVO oldValue,

PhoneVO newValue) {

System.out.println(oldValue);

System.out.println(newValue);

String path = "/images/"+newValue.getPath();

URL url = getClass().getResource(path);

imageView.setImage(new Image(url.toString()));

// 이름 정보 수정을 위해서

// TextField의 값을 선택된 행의 name 필드 정보로 변경

txtName.setText(newValue.getName());

 

}

 

});;

 

// tableView에서 항목을 선택하면 동일항목의 listView항목도 같이 선택되게

// listener추가

tableView.getSelectionModel().selectedIndexProperty()

.addListener((obj,o,n)->{

int index = n.intValue();

listView.getSelectionModel().select(index);

listView.scrollTo(index); // 해당되는 위치를 스크롤 최상단으로 이동

});

 

// UPDATE Button Action event

// TextField에 수정된 이름으로 스마트폰 이름 변경

btnUpdate.setOnAction(e->{

String name = txtName.getText();

 

//선택된거 가지고 오는 방법1

PhoneVO phone = tableView.getSelectionModel().getSelectedItem();

System.out.println(phone);

 

//선택된거 가지고 오는 방법2

int index = tableView.getSelectionModel().getSelectedIndex();

System.out.println(index);

// ListView list

list.set(index, name);

 

// TableView phoneList

phone.setName(name);

System.out.println(list);

System.out.println(phoneList);

 

// 새로고침

tableView.refresh();

listView.refresh();

});

 


// MediaView를 통해 재생되는 resource를 제어하는 객체

private MediaPlayer mediaPlayer;

// 재생해야할 resource 정보를 저장하는 객체

private Media media;

 

 

public class MediaController implements Initializable {

 

@FXML private Button btnPlay, btnPause, btnStop;

@FXML private ProgressBar progressBar;

@FXML private ProgressIndicator progressIndicator;

@FXML private Slider sliderVolume, sliderPlay;

@FXML private Label lblTime;

// Media 재생할 공간

@FXML private MediaView mediaView;

 

// MediaView를 통해 재생되는 resource를 제어하는 객체

private MediaPlayer mediaPlayer;

// 재생해야할 resource 정보를 저장하는 객체

private Media media;

 

@Override

public void initialize(URL location, ResourceBundle resources) {

// slider min = 0, max = 100

// media에서 volume을 0 ~ 1.0

sliderVolume.setValue(0.5);

// progress == 0~ 1.0으로 수치 표현

progressBar.setProgress(0.5);

progressIndicator.setProgress(0.5);

 

media = new Media(

getClass().getResource("/media/video.m4v").toString()

);

 

init();

} // end initialize

 

// 재생할 resource가 등록이 되면

// mediaPlayer를 초기화하는 method

public void init() {

if(mediaPlayer != null) {

mediaPlayer.stop();

mediaPlayer = null;

}

mediaPlayer = new MediaPlayer(media);

mediaView.setMediaPlayer(mediaPlayer);

// 새로운 미디어가 추가되면 프로그레스바, 인디케이터, 레이블을 초기화

setProgress(0.0,"0/0 sec");

// 미디어 플레이어 상태에 따른 부가 기능 초기화

setMediaPlayer();

 

// sliderPlay를 이용하여 미디어 재생 위치 제어

sliderPlay.valueProperty().addListener((t,o,n)->{

Duration totalDuration = mediaPlayer.getTotalDuration();

// sliderPlay 지정된 현재 수치

// 0 ~ 100 - 0 ~ 1.0

double value = sliderPlay.getValue() / 100.0;

// value = newValue

// 전체 재생시간을 1/1000 단위로 반환

double totalValue = totalDuration.toMillis();

// 재생 위치를 slider의 현재 조작 값으로 계산

double now = totalValue * value;

// 계산된 재생 시간 위치 정보로 Duration 객체 생성

Duration duration = new Duration(now);

// 미디어 플레이어에 재생 위치를

// 전달받은 duration 객체에 시간으로 변경

mediaPlayer.seek(duration);

mediaPlayer.play();

 

});

 

//mediaPlayer volume 조절

sliderVolume.valueProperty().addListener(new ChangeListener<Number>() {

 

@Override

public void changed(ObservableValue<? extends Number> observable,

Number oldValue,

Number newValue) {

// 0 ~ 1.0

double volume = newValue.doubleValue();

System.out.println("volume : " + volume);

// 미디어 플레이어 볼륨 정보 변경

// 0 ~ 1.0 까지의 실수값으로 조정

mediaPlayer.setVolume(volume);

}

 

});

 

// 재생 일시정지 멈춤 버튼 이벤트 초기화

btnPlay.setOnAction((e)->{

//미디어 재생

mediaPlayer.play();

// 미디어 플레이어 의 재생 시간 변경을 감지하여 변경 시간정보로

// progress를 변경

// 재생하고 있는 현재 시간 속성

mediaPlayer.currentTimeProperty()

// javafx.util.Duration == 시간 간격을 나타내는 클래스

// 특정 시간 단위를 기반으로 지속시간(duration)을 나타내는데 사용

.addListener(new ChangeListener<Duration>() {

@Override

public void changed(ObservableValue<? extends Duration> observable,

Duration oldValue,

Duration newValue) {

System.out.println(newValue);

// 현재 재생중인 파일의 전체 재생시간을 초단위로 읽어옴.

Duration duration = mediaPlayer.getTotalDuration();

double totalTime = duration.toSeconds();

System.out.println(duration);

System.out.println(totalTime);

double currentTime = newValue.toSeconds();

String lblTxt = (int)currentTime+"/"+(int)totalTime+" sec";

double progress = currentTime / totalTime;

lblTime.setText(lblTxt);

setProgress(progress,lblTxt);

}

 

});

});

 

btnPause.setOnAction(e->{

//일시정지

mediaPlayer.pause();

});

 

btnStop.setOnAction(e->{

//재생 중지

mediaPlayer.stop();

});

} // end init

 

// progress, Label 작성 초기화

public void setProgress(double p, String lblText) {

// 프로그래스 바 or 이디케이터는 0 ~ 1.0으로 진행 상황을 표현

progressBar.setProgress(p);

progressIndicator.setProgress(p);

lblTime.setText(lblText);

}

 

// 미디어 플레이어 상태에 따라 호출되는 method 지정

public void setMediaPlayer() {

// 재생 준비가 완료되었을 때

// 각 method들은 미디어 제어와 독립적으로 수행되어야 될 부가적인 기능을

// 전달 받기 때문에 독립적인 작업을 수행할 수 있도록 Runnable interface

// 구현 객체로 작업을 전달 받음.

mediaPlayer.setOnReady(new Runnable() {

@Override

public void run() {

// disable == 비활성화 - 사용자와 상호작용 불가능

btnPlay.setDisable(false);

btnPause.setDisable(true);

btnStop.setDisable(true);

 

}

 

});

// play 상태일 경우

mediaPlayer.setOnPlaying(()->{

btnPlay.setDisable(true);

btnPause.setDisable(false);

btnStop.setDisable(false);

});

 

// 일시 정지 상태

mediaPlayer.setOnPaused(()->{

btnPlay.setDisable(false);

btnPause.setDisable(true);

btnStop.setDisable(false);

});

 

// stop - 중지 상태

mediaPlayer.setOnStopped(()->{

//mediaPlayer에 등록된 Media의 재생 시작 시간을 가져옴

Duration duration = mediaPlayer.getStartTime();

mediaPlayer.seek(duration);

btnPlay.setDisable(false);

btnPause.setDisable(true);

btnStop.setDisable(true);

});

 

// 등록 미디어의 재생이 완료된 상태

mediaPlayer.setOnEndOfMedia(()->{

btnPlay.setDisable(false);

btnPause.setDisable(true);

btnStop.setDisable(true);

mediaPlayer.stop();

});

} // end setMediaPlayer

 

// Media 교체 이벤트 처리 - 재생 파일 변경

public void changeResource(ActionEvent e) {

Button btn = (Button)e.getTarget();

String text = btn.getText();

System.out.println(text);

 

String path = "";

switch(text) {

case "영상1" :

path="/media/video.m4v";

break;

case "영상2" :

path="/media/video.mp4";

break;

case "음악1" :

path="/media/audio.mp3";

break;

case "음악2" :

path="/media/audio.wav";

break;

} //end switch

System.out.println(path);

URL url = getClass().getResource(path);

System.out.println(url);

media = new Media(url.toString());

init();

}

}

 


// pie chart에 추가될 data를 observableList로 전달

// chart 지정되는 Data는 제네릭 타입에 맞게 Data class로 생성

ObservableList<PieChart.Data> list

= FXCollections.observableArrayList();

 

public class ChartController implements Initializable {

 

@FXML private PieChart pieChart;

@FXML private BarChart<String, Integer> barChart;

@FXML private AreaChart<String, Integer> areaChart;

@FXML private BubbleChart<Integer, Integer> bubbleChart;

 

@Override

public void initialize(URL location, ResourceBundle resources) {

// pie chart에 추가될 data를 observableList로 전달

// chart 지정되는 Data는 제네릭 타입에 맞게 Data class로 생성

ObservableList<PieChart.Data> list

= FXCollections.observableArrayList();

list.add(new PieChart.Data("AWT",5)); // data명, 적용될 수치(double)

list.add(new PieChart.Data("Swing", 25));

list.add(new PieChart.Data("SWT", 30));

list.add(new PieChart.Data("JavaFX", 60));

 

pieChart.setData(list);

 

// barChart

barChart.setTitle("평균 키");

// 막대 별로 어떤 정보를 저장하고 있는지를 표현

Series<String,Integer> series1 = new Series<>();

series1.setName("남성");

 

Series<String,Integer> series2 = new Series<>();

series2.setName("여성");

 

ObservableList<Data<String,Integer>> listBar = FXCollections.observableArrayList();

listBar.add(new Data<>("2019",173));

listBar.add(new Data<>("2020",173));

listBar.add(new Data<>("2021",174));

listBar.add(new Data<>("2022",176));

series1.setData(listBar);

 

listBar = FXCollections.observableArrayList();

listBar.add(new Data<>("2019", 160));

listBar.add(new Data<>("2020", 159));

listBar.add(new Data<>("2021", 163));

listBar.add(new Data<>("2022", 165));

series2.setData(listBar);

 

barChart.getData().add(series1);

barChart.getData().add(series2);

 

areaChart.setTitle("평균 온도");

Series<String,Integer> series3 = new Series<>();

series3.setName("서울");

 

ObservableList<Data<String,Integer>> listChart = FXCollections.observableArrayList();

listChart.add(new Data<>("2016",26));

listChart.add(new Data<>("2017",24));

listChart.add(new Data<>("2018",28));

listChart.add(new Data<>("2019",29));

listChart.add(new Data<>("2020",27));

series3.setData(listChart);

areaChart.getData().add(series3);

 

Series<String, Integer> series4 = new Series<>();

series4.setName("부산");

listChart = FXCollections.observableArrayList();

listChart.add(new Data<>("2016",29));

listChart.add(new Data<>("2017",30));

listChart.add(new Data<>("2018",31));

listChart.add(new Data<>("2019",24));

listChart.add(new Data<>("2020",32));

series4.setData(listChart);

areaChart.getData().add(series4);

 

// BubbleChart

// 체류 시간 별 상품 구매수와 판매 금액

// x : 체류시간 y : 금액, 구매수를 범위로 표현

Series<Integer,Integer> seriesA = new Series<>();

seriesA.setName("40대");

// x y scale

seriesA.getData().add(new Data<>(5,0,0));

seriesA.getData().add(new Data<>(10,5,5));

seriesA.getData().add(new Data<>(20,4,7));

seriesA.getData().add(new Data<>(30,3,2));

bubbleChart.getData().add(seriesA);

 

 

 

 

}

 

}