2016-06-12 6 views
0

JavaFX FXML 응용 기술을 탐색하기 시작합니다.JavaFX FXML 액세스가 lookup() 메소드에서는 성공하지만 @FXML 주석에서는 성공하지 않습니다.

오버라이드 된 메서드로 응용 프로그램 시작시 호출되는 Main.getStage()이있는 Main 클래스에서 액세스되는 하나의 주 스테이지를 사용합니다. 두 개의 public static Scene이 내부를 유지하면서 지속성을 유지하도록합니다.

@Override 
public void start(Stage stage) throws Exception { 
    STAGE = stage; 
    LOGIN = new Scene(FXMLLoader.load(getClass().getResource("Login.fxml"))); 
    REGISTER = new Scene(FXMLLoader.load(getClass().getResource("Register.fxml"))); 

    STAGE.setScene(LOGIN); 
    STAGE.setTitle("FXApplication"); 
    STAGE.show(); 
} 

public static Stage getStage() { 
    return STAGE; 
} 

두 영화의 컨트롤러 클래스는 모두 MainController입니다. 사용 :

  • 버튼을 fx:id="buttonLoginRegister"로하면 LOGIN 하나에 돌아가 fx:id="buttonRegisterBack"으로 REGISTER 장면
  • 버튼으로 이동합니다.

및 이들 모두는 동일한 onClick 이벤트 handleButtonAction(ActionEvent event)을 갖는다. TextField는 로그인/등록 할 사용자 이름 필드입니다.

@FXML private Button buttonLoginRegister; 
@FXML private Button buttonRegisterBack; 
@FXML private TextField fieldLoginUsername; 
@FXML private TextField fieldRegisterUsername; 

@FXML 
private void handleButtonAction(ActionEvent event) throws IOException { 

    Stage stage = Main.getStage(); 

    if (event.getSource() == buttonLoginRegister) {  
     stage.setScene(Main.REGISTER); 
     stage.show(); 

     // Setting the text, the working way 
     TextField node = (TextField) stage.getScene().lookup("#fieldRegisterUsername"); 
     node.setText(fieldLoginUsername.getText()); 

     // Setting the text, the erroneous way 
     // fieldRegisterUsername.setText(fieldLoginUsername.getText()); 

    } else { 
     stage.setScene(Main.LOGIN); 
     stage.show(); 
    } 
} 

내 목표는 REGISTER 장면의 하나에 LOGIN 텍스트 필드에서 값을 복사하는 것입니다. 위의 코드를 사용하면 잘 작동합니다. 그러나 먼저 다른 Scene의 요소에 액세스하려고 시도했습니다.

fieldRegisterUsername.setText(fieldLoginUsername.getText()); 

그리고 잘못된 것입니다. 정확히 말해 fieldRegisterUsernamenull입니다.

일부 요소는 lookup(String id) 방법으로 발견되었으며 @FXML 주석이 아닌 이유는 무엇입니까?

+0

다른 FXML (보기)에 대한 컨트롤러 공유는 일반적으로 권장되지 않습니다. 특히 JavaFX로 시작하는 경우에는 반대하는 것이 좋습니다.[이 질문] (http://stackoverflow.com/questions/17914254/javafx-multiple-fxml-and-1-shared-controller)을보십시오. – Itai

+0

많은 개발자들이이 방법을 사용하고 있으며 같은 번호는 agianst입니다. 개인적으로 2 개의 작은 장면의 경우 공유 컨트롤러에 나쁜 점이 없습니다. 나는 이전에 링크 된 질문을 읽었지만, 그것이 내 끈기의 필요성과 충돌합니다. –

+0

"지속성의 필요성"이 의미하는 바를 이해합니다. 귀하의 경우'조회 '가 왜 효과가 있었는지에 대한 설명을 보려면 제 답변을 참조하십시오. 컨트롤러를 FXMLLoader에 설정하지 않으면,'load'를 호출 할 때마다 컨트롤러 클래스의 새로운 인스턴스가 생성된다는 것을 명심하십시오. – Itai

답변

2

내 의견에서 언급했듯이 서로 다른보기간에 컨트롤러를 공유하는 것은 좋은 생각이 아니므로 각보기마다 별도의 컨트롤러를 만들 것을 강력히 권합니다.

문제 자체에 대해 컨트롤러 클래스의 인스턴스가 두 개 있습니다. FXMLLoader.load을 호출 할 때마다 하나씩입니다. 아마도 하나의보기에는 fieldLoginUsername TextField가 있고 다른보기에는 fieldRegisterUsername이 있다고 가정합니다.
if 문의 조건이 충족되면 활성 장면이 로그인 씬이라는 의미이므로 fieldLoginUsername 인 컨트롤러이므로 fieldRegisterUsername은 null이됩니다.

그러나

전화 할 시간에 의해 scene#lookup 당신이 누구의 컨트롤러 등록 컨트롤러, fieldRegisterUsername을 않는 하나 인 장면으로 언급하는, 그래서 당신이 등록 하나에 활성 장면을 변경 if 절 내부의 첫 번째 줄에.

활성 장면을 변경하기 전에 scene#lookup으로 전화 할 경우 null을 반환합니다.

컨트롤러에 동일한 클래스를 사용해야하는 경우 해당 클래스의 인스턴스가인지 확인하고 싶을 것입니다. 그것은 FXMLLoader#setController을 사용해야 할 것입니다.

+0

설명해 주셔서 감사합니다. 서로 다른 Scanes간에 하나의 컨트롤러를 사용하는 것이 좋지 않은 경우 두 개의 분리 된 컨트롤러를 사용하여 동일한 효과를 얻을 수있는 방법을 알려주십시오. 값을 쉽게 전달할 생각이 없습니다. –

+0

Arjan은 원본 질문에 대한 주석에서 두 가지 우수한 대답을 연결했습니다. – Itai