• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

안녕하세요. 하나의 컨트롤러 내에서 다른 컨트롤러 호출에 관한 질문입니다.

21.02.20 22:48 작성 조회수 738

0

현재 이런 어플리케이션을 만들고 있습니다. 해당 화면에서 File > Open을 누르게 되면 아래와 같이 모달이 나오는데요,

해당 모달의 확인 버튼을 눌렀을 때, 모달이 닫히면서 이곳에서 선택한 파일 4개의 경로를 가지고
아래 깔려있는 HDX Viewer라는 Scene의 왼쪽 흰색 영역에 TreeView를 그려주고 싶습니다.

저는 현재 2개의 뷰 파일을 가지고 있고, (아래쪽이 MainView.fxml, 위의 모달이 FileSelectView.fxml 입니다.)
각 뷰에 따른 컨트롤러 클래스를 2개 가지고 있습니다. (MainViewController.java, FileSelectViewController.java)

해당 로직은 이렇게 진행됩니다.

[모달이 열리지 않은 상태]

MainViewController에서 onClickOpen() =>  showFileModal()

[모달이 열린 상태]
FileSelectViewController에서 확인 버튼 클릭 => onConfirm()실행 => mainViewController의 setTreeItem()을 부름 

이때, mainViewController의 setTreeItem에서 제가 분명히 TreeItem을 잘 적용했으나, mainView에서 해당 변경 사항이 반영되지 않았습니다. 혹시 해당 뷰의 상태를 바꿔주려면 어떻게 해야 하나요?

제가 어떤 부분을 놓쳤는지 궁금합니다. 혹시 괜찮으시다면 한번 검토해주실 수 있을까요? 더 필요한 사항이 있으시면 적어주신다면 제가 더 첨부하겠습니다. 감사합니다.

MainViewController.java

package application;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.ResourceBundle;

import javax.xml.stream.XMLStreamException;

import org.systemsbiology.jrap.stax.MSXMLSequentialParser;
import org.systemsbiology.jrap.stax.Scan;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableView;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.MouseEvent;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class MainViewController implements Initializable {

    @FXML
    private MenuItem open;

    @FXML
    private TreeView<String> treeview;

    @FXML
    private LineChart<?, ?> linechart;

    @FXML
    private BarChart<?, ?> barchart_up;
    
    @FXML
    private Button peptide_view;

    @FXML
    private BarChart<?, ?> barchart_down;

    @FXML
    private TableView<?> tableview;

    @FXML
    void onClickOpen(ActionEvent event) {
    	Stage stage = Main.getPrimaryStage();
    	showFileModal(stage);
    }
    
    private void showFileModal(Stage parentStage) {
    	try {
    	Stage stage = new Stage();
        Parent root = FXMLLoader.load(getClass().getResource("FileSelectView.fxml"));
        stage.setScene(new Scene(root, 600, 400));
        stage.setTitle("file select");
        stage.initModality(Modality.WINDOW_MODAL);
        stage.initOwner(parentStage);
        stage.showAndWait();
    	}
    	catch(Exception e){
    		System.out.println(e);
    	}
    }

    @FXML
    void onClickTableView(MouseEvent event) {

    }

	@Override
	public void initialize(URL arg0, ResourceBundle arg1) {
		barchart_up.setLegendVisible(false);
		barchart_up.getXAxis().setAnimated(false);
		barchart_up.getYAxis().setAnimated(false);
		barchart_down.setLegendVisible(false);
		barchart_down.getXAxis().setAnimated(false);
		barchart_down.getYAxis().setAnimated(false);
		
		treeview.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
    	    if(newValue != null && newValue != oldValue){
    	    	   try {
        	    	MSXMLSequentialParser parser = new MSXMLSequentialParser();
					parser.open(newValue.getValue());
					
					Scan scan = parser.getNextScan();

					double[][] array = scan.getMassIntensityList();
					XYChart.Series data = new XYChart.Series();
					
					for (int j = 0; j < array[0].length; j++) {
						double key = array[1][j];
						String s = String.format("%.2f", key);
						double value = array[0][j];
						data.getData().add(new XYChart.Data(s, value));
					}	

					barchart_up.getData().add(data);
				} catch (FileNotFoundException | XMLStreamException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
    	    }
    	});
	}
	
	public void setTreeItem() {
    	peptide_view.setText("aaaaa");
		try {
		TreeItem<String> Root = new TreeItem<String>("FILES");
		TreeItem<String> newItem = new TreeItem<String>("condition1");
		Root.getChildren().add(newItem);

    	treeview.setRoot(Root);
    	treeview.refresh();
		
		System.out.println(peptide_view);
		System.out.println(treeview);
		} catch(Exception e) {
			
		}
	}
}

FileSelectViewController.java

package application;

import java.io.File;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

public class FileSelectViewController {

    private FileChooser.ExtensionFilter extFilter = 
    		new FileChooser.ExtensionFilter("MZXML FILES (*.mzxml)", "*.mzxml");
	
    @FXML
    private Button confirm_button;

    @FXML
    private Button control_button;

    @FXML
    private TextField control_field;

    @FXML
    private Button f1_button;

    @FXML
    private TextField f1_field;

    @FXML
    private Button f2_button;

    @FXML
    private TextField f2_field;

    @FXML
    private Button f3_button;

    @FXML
    private TextField f3_field;

    @FXML
    void onConfirm(ActionEvent event) {
    	try {
    	Node node = (Node) event.getSource();
    	Stage thisStage = (Stage) node.getScene().getWindow();
    	
//    	String[] filePaths = new String[4];
//    	filePaths[0] = control_field.getText();
//    	filePaths[1] = f1_field.getText();
//    	filePaths[2] = f2_field.getText();
//    	filePaths[3] = f3_field.getText();
    	
    	FXMLLoader loader = new FXMLLoader(getClass().getResource("MainView.fxml"));
        loader.load();
        
    	MainViewController mainViewController = (MainViewController) loader.getController();
    	mainViewController.setTreeItem();

    	thisStage.close();
    	} catch(Exception e) {
    		System.out.println(e);
    	}
    }
    
    void selectFile(FileChooser.ExtensionFilter filter, TextField field) {
    	Stage stage = Main.getPrimaryStage();
    	
    	FileChooser fileChooser = new FileChooser();
		fileChooser.setTitle("Open File");
		
		// Set extension filter
        fileChooser.getExtensionFilters().add(filter); 
        
		File file = fileChooser.showOpenDialog(stage);
		if (file != null) field.setText(file.getPath());
    }
    
    @FXML
    void onSelectControlFile(ActionEvent event) {
    	selectFile(extFilter, control_field);
    }

    @FXML
    void onSelectF1File(ActionEvent event) {
    	selectFile(extFilter, f1_field);
    }

    @FXML
    void onSelectF2File(ActionEvent event) {
    	selectFile(extFilter, f2_field);
    }

    @FXML
    void onSelectF3File(ActionEvent event) {
    	selectFile(extFilter, f3_field);
    }

}

Main.java

package application;

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

public class Main extends Application {
	private static Stage primaryStage;
	
	private void setPrimaryStage(Stage stage) {
        Main.primaryStage = stage;
    }

    static public Stage getPrimaryStage() {
        return Main.primaryStage;
    }
	
	@Override
	public void start(Stage primaryStage) {
		try {
			setPrimaryStage(primaryStage);
			Parent root = FXMLLoader.load(getClass().getResource("MainView.fxml"));
			Scene scene = new Scene(root, 1280, 720);
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			primaryStage.setScene(scene);
			primaryStage.setTitle("HDX Viewer");
			primaryStage.setResizable(false);
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

답변 2

·

답변을 작성해보세요.

0

딩제이님의 프로필

딩제이

질문자

2021.02.21

강의 의외의 답변에도 친절하게 답변해주셔서 정말 고맙습니다.
전역변수로 선언해서 문제를 해결했습니다.

알고보니 처음에  만들어지는 컨트롤러 객체와

FXMLLoader로 불러오는 객체의 id가 다르더군요. 아마 새로운 컨트롤러 객체를

만들어서 가져오는 듯 합니다.

정말 고맙습니다. 덕분에 막혀있던 부분이 잘  진행될 것 같아요.

0

일단 다음과 같이 해보시길 바랍니다.(완벽하게 소스를 테스트하고 답변을 드리는 것이 아닙니다.)

(사실, 강의에서 다루는 영역 이외의 질문에 대한 답변은 해드리지 않고 있습니다. 앞으로 양해부탁드립니다.) 

답변:

FileViewSelectController에서 MainController를 받을 수 있는 setMainController(MainController mainController)메쏘드를 만드신 후

(전역으로 "MainController mainController;"를 두고, 새로 만든 함수안에 "this.mainController = mainController;"를 넣어줍니다.)

MainController쪽의 ShowFileModal메쏘드안에 자신을(this) 넘겨줄 수 있도록 소스를 바꿔준 후,

onConfirm메쏘드안에서  

if(mainController != null){

 mainController.setTreeItem();

}

이라고 해줘야 작동할 것 같습니다.

(주의할 점은 loader변수를 만들고 나서 load메쏘드를 호출하기 전에 controller를 등록해야 합니다.)

(즉,  showFileModal메쏘드안의 일부를        

FXMLLoader loader = new FXMLLoader(getClass().getResource("FileSelectView.fxml"));

loader.setController(this);

Parent root = loader.load();

와 같이 수정해 줄 필요가 있습니다.

)