0

こんにちは!NullPointerException 別の検索画面で目的のレコードを選択した後、登録画面にデータをロードしようとするとうまくいきません。私のコード.: SearchScreen:

public int retornaSelecao() {
    return (int) tablePesquisa.getValueAt(tablePesquisa.getSelectedRow(), 0);
}
private void tablePesquisaMouseClicked(java.awt.event.MouseEvent evt){                                           
    if (evt.getClickCount() == 2) {
         CadastroCliente cliente = new CadastroCliente(this.retornaSelecao());
         this.dispose();
    }
}        

この画面でレコードの ID を取得しJTable、id パラメータを渡して画面登録を呼び出します

登録画面になりました

public CadastroCliente() {
    initComponents();
    this.desabilitaCampos();
    btnAlterar.setEnabled(false);
    btnExcluir.setEnabled(false);
    btnCancelar.setEnabled(false);
    btnSalvar.setEnabled(false);
    btnNovo.setEnabled(true);
    btnPesquisa.setEnabled(true);
    btnSair.setEnabled(true);    
}

public CadastroCliente(int codigo){
    String sql = "SELECT * FROM CLIENTE WHERE CODIGO = " + codigo;
    Conexao conexao = new Conexao();
    ResultSet rst;
    //System.out.println("" + codigo);
    try {
        pstm = conexao.conectar().prepareStatement("SELECT * FROM CLIENTE WHERE CODIGO = '" + codigo + "';");
        rst = pstm.executeQuery();
        while (rst.next()) {
            txtCodigo.setText("" + rst.getString("codigo"));
            System.out.println("" + rst.getString("codigo"));
            txtDataCadastro.setText(rst.getDate("datacadastro").toString());
            txtDataNascimento.setDate(rst.getDate("datanascimento"));
            txtNome.setText(rst.getString("nome").toUpperCase());
            txtApelido.setText(rst.getString("apelido").toUpperCase());
            txtEndereco.setText(rst.getString("endereco").toUpperCase());
            txtNumero.setText(rst.getString("numero"));
            txtComplemento.setText(rst.getString("complemento").toUpperCase());
            txtBairro.setText(rst.getString("bairro").toUpperCase());
            txtCep.setText(rst.getString("cep"));
            txtNomeCidade.setText(rst.getString("cidade").toUpperCase());
            txtRg.setText(rst.getString("rg"));
            txtCpf.setText(rst.getString("cpf"));
            cbPagamento.setSelectedItem(rst.getInt("diapagamento"));
            txtMensalidade.setText("" + rst.getFloat("mensalidade"));
            txtTelefoneResidencial.setText(rst.getString("telres"));
            txtTelefoneComercial.setText(rst.getString("telcom"));
            txtTelefoneCelular.setText(rst.getString("celular"));
            txtInformacoes.setText(rst.getString("informacoes"));
        }
    } catch (SQLException ex) {
        Logger.getLogger(CadastroCliente.class.getName()).log(Level.SEVERE, null, ex);
    }
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new CadastroCliente().setVisible(true);
        }
    });
}

最初のコンストラクターがNullPointerException完了した後、JTextField. なぜこのエラーが発生するのですか? 誰でも私を助けることができますか?ありがとうございました

4

1 に答える 1

2

スタックトレースとエラーが発生している行を投稿すると役立ちます。

しかし、2 つのコンストラクターを見ると、次のようになります。

public CadastroCliente() {
    initComponents();
    this.desabilitaCampos();
    btnAlterar.setEnabled(false);
    btnExcluir.setEnabled(false);
    btnCancelar.setEnabled(false);
    btnSalvar.setEnabled(false);
    btnNovo.setEnabled(true);
    btnPesquisa.setEnabled(true);
    btnSair.setEnabled(true);
}

public CadastroCliente(int codigo){
    String sql = "SELECT * FROM CLIENTE WHERE CODIGO = " + codigo;
    Conexao conexao = new Conexao();
    ResultSet rst;
    ...
}

GUI(およびほとんどなど)を初期化する可能性が最も高いコンストラクターのようなメソッドを呼び出さないinitComponents()でください。CadastroCliente(int codigo)JTextField

そのはず:

public CadastroCliente(int codigo){
    initComponents();//initialize components
     //if the buttons need to be set do that here
    String sql = "SELECT * FROM CLIENTE WHERE CODIGO = " + codigo;
    Conexao conexao = new Conexao();
    ResultSet rst;
    ...
}

アップデート:

また、GUI イベント ディスパッチ スレッドでデータベース クエリのような長時間実行されるタスクを実行しないでください。これにより、UI がフリーズし、タスクが完了した後にのみアクティブになり、中間結果が表示されない可能性があるためです。

ResultSet rst;
//System.out.println("" + codigo);
try {
    pstm = conexao.conectar().prepareStatement("SELECT * FROM CLIENTE WHERE CODIGO = '" + codigo + "';");
    rst = pstm.executeQuery();
    while (rst.next()) {
        txtCodigo.setText("" + rst.getString("codigo"));//wont show until the while loop is done
        ...
    }
} catch (SQLException ex) {
    Logger.getLogger(CadastroCliente.class.getName()).log(Level.SEVERE, null, ex);
}

この作業をSwing Workerにオフロードし、そのpublish(..)メソッドを使用して中間結果を取得するのが最善です。

オラクルによると

SwingWorker は、多くの通信および制御機能を提供します。

  • SwingWorker サブクラスはメソッド done を定義できます。このメソッドは、バックグラウンド タスクが終了したときにイベント ディスパッチ スレッドで自動的に呼び出されます。

  • SwingWorker は java.util.concurrent.Future を実装します。このインターフェイスにより、バックグラウンド タスクは他のスレッドに戻り値を提供できます。このインターフェイスの他のメソッドを使用すると、バックグラウンド タスクをキャンセルし、バックグラウンド タスクが終了したかキャンセルされたかを検出できます。

  • バックグラウンド タスクは、SwingWorker.publish を呼び出して、イベント ディスパッチ スレッドから SwingWorker.process を呼び出すことにより、中間結果を提供できます。

  • バックグラウンド タスクは、バインドされたプロパティを定義できます。これらのプロパティを変更すると、イベントがトリガーされ、イベント ディスパッチ スレッドでイベント処理メソッドが呼び出されます。

Concurrency in Swingも読んでください。

于 2013-02-16T19:13:00.230 に答える