viernes, 2 de mayo de 2014

Explicando DocumentListener

Si queremos controlar los cambios en el contenido de un cuadro de texto podemos emplear el evento DocumentListener -que no está contemplado en Netbeans por ejemplo- en el siguiente ejemplo se crea una clase con un par debotones y cuadros de texto.

Tras ir añadiendo botones durante la explicación, al final cualquier cambio en un cuadro de texto cambia el contenido en el cuadro de texto del otro lado. (para que no comience a realizar cambios sucesivos en los dos lados empleamos una propiedad que nos diga si se está convirtiendo ya un tipo de dato a otro (sino las operaciones podrían ser infinitas ya que los datos que mostramos no son divisiones exactas).

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package explicaciones;

import java.awt.Event;
import java.awt.event.ActionEvent;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;


/**
*
* @author juan
*/
public class VentBotonesLabel extends javax.swing.JFrame {
    private boolean cambiando;
    /**
 

    * Creates new form VentBotonesLabel
     */
    public VentBotonesLabel() {
        initComponents();
        setJTexFieldChanged(txtEuros);
        this.setJTexFieldChanged(txtPesetas);
        cambiando=false;
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
    private void initComponents() {

        panCentral = new javax.swing.JPanel();
        txtPesetas = new javax.swing.JTextField();
        btnAlaDcha = new javax.swing.JButton();
        btnAlaIzqda = new javax.swing.JButton();
        txtEuros = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        btnPesetasToEuros = new javax.swing.JButton();
        btnEurosToPesetas = new javax.swing.JButton();
        lblPesetas = new javax.swing.JLabel();
        lblEuros = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        txtPesetas.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPesetasToEurosActionPerformed(evt);
            }
        });

        btnAlaDcha.setText(">>");
        btnAlaDcha.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAlaDchaActionPerformed(evt);
            }
        });

        btnAlaIzqda.setText("<<");
        btnAlaIzqda.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAlaIzqdaActionPerformed(evt);
            }
        });

        txtEuros.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtEurosActionPerformed(evt);
            }
        });

        jButton1.setText("Borrar");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel1.setText("Pesetas:");

        jLabel2.setText("Euros:");

        btnPesetasToEuros.setText("Pesetas >> Euros");
        btnPesetasToEuros.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPesetasToEurosActionPerformed(evt);
            }
        });

        btnEurosToPesetas.setText("Pesetas << Euros");
        btnEurosToPesetas.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnEurosToPesetasActionPerformed(evt);
            }
        });

        lblPesetas.setText("jLabel3");

        lblEuros.setText("jLabel4");

        javax.swing.GroupLayout panCentralLayout = new javax.swing.GroupLayout(panCentral);
        panCentral.setLayout(panCentralLayout);
        panCentralLayout.setHorizontalGroup(
            panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panCentralLayout.createSequentialGroup()
                .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(panCentralLayout.createSequentialGroup()
                        .addGap(167, 167, 167)
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panCentralLayout.createSequentialGroup()
                        .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(panCentralLayout.createSequentialGroup()
                                .addGap(231, 231, 231)
                                .addComponent(btnAlaDcha)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                            .addGroup(panCentralLayout.createSequentialGroup()
                                .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(panCentralLayout.createSequentialGroup()
                                        .addContainerGap()
                                        .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addComponent(txtPesetas, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE)))
                                    .addGroup(panCentralLayout.createSequentialGroup()
                                        .addGap(53, 53, 53)
                                        .addComponent(lblPesetas, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)))
                                .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(panCentralLayout.createSequentialGroup()
                                        .addGap(39, 39, 39)
                                        .addComponent(btnAlaIzqda)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panCentralLayout.createSequentialGroup()
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(btnEurosToPesetas)
                                            .addComponent(btnPesetasToEuros))
                                        .addGap(50, 50, 50)))))
                        .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel2)
                            .addComponent(txtEuros, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(panCentralLayout.createSequentialGroup()
                                .addGap(14, 14, 14)
                                .addComponent(lblEuros, javax.swing.GroupLayout.PREFERRED_SIZE, 122, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                .addContainerGap())
        );
        panCentralLayout.setVerticalGroup(
            panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panCentralLayout.createSequentialGroup()
                .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(panCentralLayout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel2))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(txtPesetas, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(txtEuros, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(panCentralLayout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addComponent(btnAlaDcha)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(btnAlaIzqda)
                        .addGap(18, 18, 18)
                        .addGroup(panCentralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(btnPesetasToEuros)
                            .addComponent(lblPesetas, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblEuros, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnEurosToPesetas)
                .addGap(18, 18, 18)
                .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 57, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(panCentral, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(panCentral, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                       

     private void setJTexFieldChanged(JTextField txt)
    {
        DocumentListener documentListener = new DocumentListener() {

        @Override
        public void changedUpdate(DocumentEvent documentEvent) {
                       actualizar(documentEvent);
        }

        @Override
        public void insertUpdate(DocumentEvent documentEvent) {
            actualizar(documentEvent);
        }

        @Override
        public void removeUpdate(DocumentEvent documentEvent) {
                       actualizar(documentEvent);
        }
        };
        txt.getDocument().addDocumentListener(documentListener);

    }
    private void actualizar(DocumentEvent e){
        if (!cambiando)
            if ( e.getDocument().equals(txtEuros.getDocument())) actualizarPesetas();
            else actualizarEuros();
        else cambiando=true;
    }
    private void btnAlaDchaActionPerformed(java.awt.event.ActionEvent evt) {                                          
        txtEuros.setText(txtPesetas.getText());
        txtEuros.requestFocus();
    }                                         

    private void btnAlaIzqdaActionPerformed(java.awt.event.ActionEvent evt) {                                           
        txtPesetas.setText(txtEuros.getText());
        txtPesetas.requestFocus();
    }                                          

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                        
        txtPesetas.setText("");
        txtEuros.setText("");// TODO add your handling code here:
    }                                       

    private void btnPesetasToEurosActionPerformed(java.awt.event.ActionEvent evt) {                                                 
       
        actualizarEuros();
       
    }                                                
    private void actualizarEuros()
    {
        Double pesetas,euros;
         if (!txtPesetas.getText().equals(""))
        try {
            pesetas = Double.parseDouble(txtPesetas.getText());
            euros=pesetas /166.386;
            cambiando=true;
            txtEuros.setText(String.valueOf(euros));
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(panCentral, "Solo se admiten números","Error en la introducción de datos",JOptionPane.ERROR_MESSAGE);
            txtPesetas.selectAll();
            txtPesetas.requestFocus();
        }
         else txtEuros.setText("");
            cambiando=false;
       
   
   
   
    }
   
    private void actualizarPesetas(){
    Double pesetas,euros;
        cambiando=true;
        if (!txtEuros.getText().equals(""))
        try {
            euros = Double.parseDouble(txtEuros.getText());
            pesetas=euros*166.386;
            txtPesetas.setText(String.valueOf(pesetas));
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(panCentral, "solo se admiten números");
            txtEuros.selectAll();
            txtEuros.requestFocus();
        }
       
           
       
        else txtPesetas.setText("");
        cambiando=false;
    }
    private void btnEurosToPesetasActionPerformed(java.awt.event.ActionEvent evt) {                                                 
        actualizarPesetas();

    }                                                

    private void txtEurosActionPerformed(java.awt.event.ActionEvent evt) {                                        
      actualizarPesetas();
    }                                       

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(VentBotonesLabel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(VentBotonesLabel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(VentBotonesLabel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(VentBotonesLabel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new VentBotonesLabel().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                    
    private javax.swing.JButton btnAlaDcha;
    private javax.swing.JButton btnAlaIzqda;
    private javax.swing.JButton btnEurosToPesetas;
    private javax.swing.JButton btnPesetasToEuros;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel lblEuros;
    private javax.swing.JLabel lblPesetas;
    private javax.swing.JPanel panCentral;
    private javax.swing.JTextField txtEuros;
    private javax.swing.JTextField txtPesetas;
    // End of variables declaration                  
}



   

Referencias:
http://saforas.wordpress.com/2011/01/08/codigo-java-evento-de-cambio-de-texto-en-jtextfield/