Enviar Objeto para outra tela

Ola galera , estou com outra dúvida aqui , eu tenho uma tela de listagem frmlistagem que tem um botão de edição que pega a linha selecionada e chama uma outra tela com os inputs da alteraçao frmedit como enviar o objeto que foi selecionado no frmlistagem para popular os textfield do frmedit??

segue os códigos :
FrmListVeiCont - > aqui está a lista que a partir do método abaixo pega a linha selecionada e abre o outro form

public void editar() {
try {
veiculo = new Veiculo();
veiculo = tbVeiculo.getSelectionModel().getSelectedItem();
if(tbVeiculo.getSelectionModel().getSelectedItem() == null) {
JOptionPane.showMessageDialog(null, “Selecione uma linha na tabela para edição!”);
}else{
new FrmEditVeicApp().start(new Stage());
}

Crie um método nesse FrmEditVeicApp que receba o objeto
ex:
na Classe FrmEditVeicApp:

public void receberObjeto(Veiculo veiculo){
 //ai vc faz aqui oq quiser com o Objeto.
}

ficaria assim no seu codigo:

public void editar() {
        try {
            veiculo = new Veiculo();
            veiculo = tbVeiculo.getSelectionModel().getSelectedItem();
            if(tbVeiculo.getSelectionModel().getSelectedItem() == null) {
                JOptionPane.showMessageDialog(null, "Selecione uma linha na tabela para edição!");
            }else{
              FrmEditVeicApp tela = new FrmEditVeicApp();
              tela.start(new Stage());
              tela.recebeObjeto(veiculo);
            }

Certo mas como esse metodo pode influenciar na view , tipo eu quero popular um textfield que esta no frmedit.

Simples muito simples, basta fazer isso no método

public void receberObjeto(Veiculo veiculo){
 //simples assim
 textField.setText(veiculo.getNome());
 //....
}

Eu nao estou entendendo , como a classe que extends de Application vai acessar o TextField que esta na classe controller que implements Initializable?

Oque eu quero e enviar o objeto Veiculo de um controller para outro

Eliel,
Eu acho que no seu caso vc pode trabalhar com o padrão Oberserver deve resolver o seu problema.

De alguma forma esse Objeto tem q ser Acessado, se vc quer enviar de um controle para outro, tem q usar método, eu teria q ver como está seu código, para dá melhor detalhamento esse FrmEditVeicApp não é o extends a Application? onde q vc carrega esse controle? para JavaFX tem quer se padrão MVC para ficar de fácil manipulação, Recomendação não fique criando varias Classes que estenda a Application, só é necessária Uma classe q Estenda, para mudar de tela ou surgir outra tela, vc apenas pode alterar a CENA , ou caso precise que outra tela apareça, apenas chama ela nessa única Classe! Meus Projetos em JavaFX apenas uma Classe que estende a Application e trabalho com várias telas ex:

public class PrincipalFX extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        this.palcoLogin = primaryStage;
        this.palcoLogin.setTitle("Sistema de Segurança");
        this.palcoLogin.getIcons().add(new Image(PrincipalFX.class.getClassLoader().getResource("jeanderson/br/imagens/icon_segurity.png").toExternalForm()));
        //iniciarComponentes();
        iniciarLogin();
    }
//chama a tela add Produto
public void showAddProduto() {
        if (!abriuAddProduto) {
            FXMLLoader carregar = new FXMLLoader(PrincipalFX.class.getClassLoader().getResource("jeanderson/br/view/TelaAddProduto.fxml"));
            this.palcoAddProduto = new Stage();
            this.palcoAddProduto.setTitle("Adicionar Produto");
            this.palcoAddProduto.initModality(Modality.WINDOW_MODAL);
            this.palcoAddProduto.initOwner(this.primaryStage);
            try {
                this.telaAddProduto = (AnchorPane) carregar.load();
                Scene cena = new Scene(telaAddProduto);
                this.palcoAddProduto.setScene(cena);
                this.palcoAddProduto.setResizable(false);
                TelaAddProdutoControle produtoControl = carregar.getController();
                produtoControl.pegarReferencia(this);
                if (this.controle != null) {
                    this.controle.adicionou(true);
                }
                this.abriuAddProduto = true;
                this.palcoAddProduto.showAndWait();
            } catch (IOException ex) {
                Relatorio.excecao(PrincipalFX.class.getDeclaredMethods()[1].toString(), ex.getMessage());
                Logger.getLogger(PrincipalFX.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            this.palcoAddProduto.showAndWait();
        }
     }
    //chama Tela Estoque
    public void showEstoque(){
           //.......
     }
}

Ai nós Controller eu criou um método que recebe a referencia do PrincipalFX

public void pegarReferencia(PrincipalFX fx){
  this.principalFX = fx;
}

Assim dentro dos controles eu posso chamar outra tela, ou se eu quiser pegar um Objeto que está no outro controle, já q na Classe PrincipalFX Todos os controlers e telas estão lá.
Um exemplo na minha classe PrincipalFX tem um método que chama a tela descrição de um produto, mas para isso eu preciso passar a posição do produto:

public void showDescricao(Integer id) {
        if (!abriuDescricao) {
            FXMLLoader carregar = new FXMLLoader(PrincipalFX.class.getClassLoader().getResource("jeanderson/br/view/TelaDescricao.fxml"));
            try {
                this.telaDescricao = (AnchorPane) carregar.load();
                this.palcoDescricao = new Stage();
                this.palcoDescricao.initModality(Modality.WINDOW_MODAL);
                this.palcoDescricao.initOwner(this.palcoMostrar);
                this.palcoDescricao.setTitle("Descrição do Produto");
                Scene cena = new Scene(this.telaDescricao);
                this.palcoDescricao.setScene(cena);
                this.palcoDescricao.setResizable(false);
                //Esse é a classe de controle
                this.descricaoControl = carregar.getController();
                this.descricaoControl.pegarReferencia(this);
                //Olha o método da minha Classe de controle
                this.descricaoControl.pegarDescricao(id);
                this.palcoDescricao.show();
                this.abriuDescricao = true;
            } catch (IOException ex) {
                Relatorio.excecao(PrincipalFX.class.getDeclaredMethods()[3].toString(), ex.getMessage());
                Logger.getLogger(PrincipalFX.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            this.descricaoControl.pegarDescricao(id);
            this.palcoDescricao.show();
        }

    }

Ai em uma Classe de controle, como eu tenho a Referencia da Classe PrincipalFX ai eu posso fazer isso aqui:

public class TelaEstoqueControle {
    private PrincipalFX principalFX;
    @FXML
    private void initialize(){
    }
   public void pegarReferencia(PrincipalFX fx){
        this.principalFX = fx;
    }
  //Chamo a tela pela classe de Controle
  public void chamarTelaDescricao(){
   //passo a posição do produto que eu quero q mostre
   this.principalFX.showDescricao(1);
   }
  
}

Tudo isso será meio difícil de vc entender, mas resumindo, vc tem que ter apenas uma Classe q gerencie todas as Telas e Controllers!

Oq vc ta me dizendo e que a classe q extends Application com apenas uma eu consigo rodar todas as telas (.fxml),e que cada .fxml vai ter uma classe q extends Initializable?

1 curtida

Vou colocar aqui os códigos que tenho até o momento:
FrmListVeicApp
essa é a classe que estou usando para chamar o xml feito no scene builder

public class FrmListVeicApp extends Application {

public static Stage stage;

@Override
public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FrmListVeic.fxml"));
        
        Scene scene = new Scene(root);
        
        stage.setScene(scene);
        stage.show();
        
        FrmListVeicApp.stage = stage;
}

public static void main(String[] args) {
    launch(args);
}

public static Stage getStage() {
    return stage;
}

public static void setStage(Stage stage) {
    FrmListVeicApp.stage = stage;
}

}

FrmListVeicCont
classe que faz o controller

public class FrmListVeicCont implements Initializable {

@FXML
private AnchorPane anchorListVeic;
@FXML
private Pane paneListVeic;
@FXML
private Button btnNovoVeic;
@FXML
private Button btnEditVeic;
@FXML
private Button btnDelVeic;
@FXML
private Pane paneTbVeic;
@FXML
private TableView<Veiculo> tbVeiculo;
@FXML
private TableColumn<Veiculo, Integer> columnCodVeic;
@FXML
private TableColumn<Veiculo, String> columnMarcaVeic;
@FXML
private TableColumn<Veiculo, String> columnModeloVeic;
@FXML
private TableColumn<Veiculo, String> columnPlacaVeic;
@FXML
private TableColumn<Veiculo, String> columnPropVeic;
@FXML
private TextField txtPesqVeic;
@FXML
private Button btnBuscaVeic;
@FXML
private RadioButton radioPlaca;
@FXML
private RadioButton radioProprietario;

@FXML
private Button btnRefresh;

private Veiculo veiculo;

private VeiculoController controller;

private List<Veiculo> lista;

private static Stage stage;

/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb) {
    
    initTableColumn();

    //BOTÃO PARA CADASTRAR NOVO VEICULO
    btnNovoVeic.setOnAction((ActionEvent event) -> {
        try {
            new FrmCadVeicApp().start(new Stage());
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex, "Erro ao abrir tela", JOptionPane.ERROR_MESSAGE);
        }
    });

    //BOTÃO PARA EDITAR VEICULO
    btnEditVeic.setOnAction((ActionEvent event) -> {
        try{
            editar();
        }catch(Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Erro ao Cadastrar");
        }
    });

    btnDelVeic.setOnAction((ActionEvent event) -> {
        try{
           veiculo = tbVeiculo.getSelectionModel().getSelectedItem();
           controller = new VeiculoController();
           controller.excluir(veiculo);
           initTableColumn();
        }catch(Exception e) {
            e.printStackTrace();
            if(tbVeiculo.getSelectionModel().getSelectedItem() == null) {
                JOptionPane.showMessageDialog(null, "Selecione uma linha da tabela para excluir!!");
            }else{
                JOptionPane.showMessageDialog(null, "Erro ao Excluir :"+e.getMessage());
            }
        }
    });

    btnBuscaVeic.setOnAction((ActionEvent event) -> {

    });
    
    btnRefresh.setOnAction((ActionEvent event) -> {
       initTableColumn();
    });
    
}

private void initTableColumn() {
    ObservableList<Veiculo> veiculos = FXCollections.observableArrayList(carregaLista());
    tbVeiculo.setItems(veiculos);
    columnCodVeic.setCellValueFactory(new PropertyValueFactory<>("idVeiculo"));
    columnMarcaVeic.setCellValueFactory(new PropertyValueFactory<>("marcaVeiculo"));
    columnModeloVeic.setCellValueFactory(new PropertyValueFactory<>("modeloVeiculo"));
    columnPlacaVeic.setCellValueFactory(new PropertyValueFactory<>("placaVeiculo"));
    columnPropVeic.setCellValueFactory(new PropertyValueFactory<>("nomeDonoVeiculo"));

}

public List<Veiculo> carregaLista() {
    controller = new VeiculoController();
    lista = controller.listar();
    return lista;
}

public static Stage getStage() {
    return stage;
}

public static void setStage(Stage stage) {
    FrmListVeicCont.stage = stage;
}

public void editar() {
    try {
        veiculo = new Veiculo();
        veiculo = tbVeiculo.getSelectionModel().getSelectedItem();
        if(tbVeiculo.getSelectionModel().getSelectedItem() == null) {
            JOptionPane.showMessageDialog(null, "Selecione uma linha na tabela para edição!");
        }else{
           FrmEditVeicApp tela = new FrmEditVeicApp();
           tela.start(new Stage());
           
        } 
    } catch (Exception ex) {
        Logger.getLogger(FrmListVeicCont.class.getName()).log(Level.SEVERE, null, ex);
    }
} 

}

FrmCadVeicApp
classe que chama a tela de cadastro.

public class FrmCadVeicApp extends Application {

private static Stage stage;

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FrmCadVeic.fxml"));
    
    Scene scene = new Scene(root);
    
    stage.setScene(scene);
    stage.show();
    FrmCadVeicApp.stage = stage;
}

public static void main(String[] args) {
    launch(args);
}

public static Stage getStage() {
    return stage;
}

public static void setStage(Stage stage) {
    FrmCadVeicApp.stage = stage;
}

}

FrmCadVeiculo
esse é o controller da tela do cadastro de veiculo , ainda está com o método feio que criei para atualizar a table view mas já estou estudando sobre o design observer…

public class FrmCadVeiculo implements Initializable {
@FXML
private AnchorPane anchorCadVeic;
@FXML
private Pane paneCadVeic;
@FXML
private Label lblProp;
@FXML
private TextField txtNomeDono;
@FXML
private TextField txtCpfDono;
@FXML
private Label lblMod;
@FXML
private TextField txtModelo;
@FXML
private Label lblMarc;
@FXML
private TextField txtMarca;
@FXML
private Label lblCpf;
@FXML
private Label lblUf;
@FXML
private ComboBox<?> comboUf;
@FXML
private Label lblPlaca;
@FXML
private TextField txtPlaca;
@FXML
private Label lblAno;
@FXML
private TextField txtAno;
@FXML
private Label lblCor;
@FXML
private TextField txtCor;
@FXML
private Label lblKm;
@FXML
private TextField txtKm;

@FXML
private TextField txtUfVeic;

@FXML
private Button btnCadVeic;
@FXML
private Button btnSairCadVeic;

private Veiculo veiculo;

private VeiculoController controller;

private FrmListVeicCont fmrListCtrl;

private static Stage stage;
/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb) {
    
    
    btnCadVeic.setOnAction((ActionEvent event) -> {
        veiculo = new Veiculo();
        controller = new VeiculoController();
        
        veiculo.setAnoVeiculo(Integer.valueOf(txtAno.getText()));
        veiculo.setCorVeiculo(txtCor.getText());
        veiculo.setCpfDonoVeiculo(txtNomeDono.getText());
        veiculo.setKmVeiculo(Double.valueOf(txtKm.getText()));
        veiculo.setPlacaVeiculo(txtPlaca.getText());
        veiculo.setMarcaVeiculo(txtMarca.getText());
        veiculo.setModeloVeiculo(txtModelo.getText());
        veiculo.setUfVeiculo(txtUfVeic.getText());
        veiculo.setNomeDonoVeiculo(txtNomeDono.getText());
        try{
            controller.salvar(veiculo);
            informationDialog("Information", "Cadastro de veiculo", "Veiculo cadastrado com sucesso");
            limpaTxt();
            atualizaTableView();
            FrmCadVeicApp.getStage().close();
        }catch(Exception e) {
            e.printStackTrace();
            warningDialog("Erro", "Erro ao cadastrar", "Erro ao cadastrar :"+e.getMessage());
        }
        
    });
    
    btnSairCadVeic.setOnAction((ActionEvent event) -> {
        FrmCadVeicApp.getStage().close();
    });
}

private void limpaTxt() {
    txtAno.setText("");
    txtCor.setText("");
    txtCpfDono.setText("");
    txtKm.setText("");
    txtMarca.setText("");
    txtModelo.setText("");
    txtPlaca.setText("");
    txtNomeDono.setText("");
}

public static Stage getStage() {
    return stage;
}

public static void setStage(Stage stage) {
    FrmCadVeiculo.stage = stage;
}

private void informationDialog(String titulo,String header,String content) {
    Alert alert = new Alert(Alert.AlertType.INFORMATION);
    alert.setTitle(titulo);
    alert.setHeaderText(header);
    alert.setContentText(content);
    alert.showAndWait();
}

private void warningDialog(String titulo,String header,String content) {
    Alert alert = new Alert(Alert.AlertType.WARNING);
    alert.setTitle(titulo);
    alert.setHeaderText(header);
    alert.setContentText(content);
    alert.showAndWait();
}

private void atualizaTableView() {
    try {
        FrmListVeicApp.getStage().close();
        new FrmListVeicApp().start(new Stage());
    } catch (Exception ex) {
        Logger.getLogger(FrmCadVeiculo.class.getName()).log(Level.SEVERE, null, ex);
    }
}

}

FrmEditApp
classe que chama o xml com a tela para editar

public class FrmEditVeicApp extends Application {

public static Stage stage;

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FrmEditVeic.fxml"));

    Scene scene = new Scene(root);

    stage.setScene(scene);
    stage.show();

    FrmEditVeicApp.stage = stage;
}


public static void main(String[] args) {
    launch(args);
}

public static Stage getStage() {
    return stage;
}

public static void setStage(Stage stage) {
    FrmEditVeicApp.stage = stage;
}

}

FrmEditVeicCtrl
essa classe é a controller , o meu problema está em entender isso aqui
como popular as textfields com os dados vindos do controller de listagem

public class FrmEditVeicCtrl implements Initializable {

@FXML
private AnchorPane anchorEditVeic;
@FXML
private Pane paneEditVeic;
@FXML
private Label lblEditProp;
@FXML
private TextField txtEditNomeDono;
@FXML
private TextField txtEditCpfDono;
@FXML
private Label lblEditMod;
@FXML
private TextField txtEditModelo;
@FXML
private Label lblEditMarc;
@FXML
private TextField txtEditMarca;
@FXML
private Label lblEditCpf;
@FXML
private Label lblEditUf;
@FXML
private Label lblEditPlaca;
@FXML
private TextField txtEditPlaca;
@FXML
private TextField txtEditUfVeic;
@FXML
private Label lblEditAno;
@FXML
private TextField txtEditAno;
@FXML
private Label lblEditCor;
@FXML
private TextField txtEditCor;
@FXML
private Label lblEditKm;
@FXML
private TextField txtEditKm;
@FXML
private Button btnEditVeic;
@FXML
private Button btnSairEditVeic;

private VeiculoController controller;

/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb) {

    btnEditVeic.setOnAction((ActionEvent event) -> {
        try {
             //popular textfield com dado vindo do controller de listagem
            JOptionPane.showConfirmDialog(null, "Deseja realmente editar o veiculo?");
            FrmEditVeicApp.getStage().close();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Erro ao editar");
        }
    });

    btnSairEditVeic.setOnAction((ActionEvent event) -> {
        FrmEditVeicApp.getStage().close();
    });

}

public void editar(Veiculo veiculo) {
    controller = new VeiculoController();
    controller.editar(veiculo);
}

}

Isso mesmo meu jovem, somente com uma é possível exibir todas as telas, e além do mais vc terá um controle maior sobre sua aplicação!

Se eu te disser que não precisa implementa a Initializable :slight_smile: é que vc não precisa também fazer um setOnAction no seu button :slight_smile: assim diminuindo seu código e ficando mais fácil de ler, se quiser saber como, me pergunte lá no privado :slight_smile: