quinta-feira, 25 de julho de 2013

Guice para todos

Olá, hoje vamos falar um pouco sobre DI e Guice, além de discorrermos por que esta é uma tecnologia importante.

Observem o seguinte programa hipotético de tratamento de arquivos:
  • O usuário indica uma pasta onde vamos procurar por arquivos .txt
  • O usuário indica uma pasta para onde os arquivos .txt devem ser movidos
  • O usuário coloca o programa em operação ou em pausa
  • O usuário é notificado das seguintes informações:
    • Arquivos encontrados 
    • Erros (ao mover, ao ler)
    • Data e hora da mensagem
E só. Afinal quero ser didático, ;-)

Comecemos criando um projeto java normal, chamar de filewatcher. Ele começa humilde e simples, vamos fazer um JFrame. A dica aqui é instalar o WindowBuilder.


O código desta janela ficará assim:

package sample.filewatcher.view;

import java.awt.EventQueue;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.EmptyBorder;

public class TheFrame extends JFrame {

 /**
  * 
  */
 private static final long serialVersionUID = -6742814419164072401L;
 private JPanel contentPane;
 private JTextField textField;
 private JTextField textField_1;
 private JTextArea textArea;
 private JToggleButton tglbtnIniciar;

 /**
  * Launch the application.
  */
 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {
     TheFrame frame = new TheFrame();
     frame.setVisible(true);
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  });
 }

 /**
  * Create the frame.
  */
 public TheFrame() {
  setTitle("Filewatcher");
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setBounds(100, 100, 450, 300);
  contentPane = new JPanel();
  contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  setContentPane(contentPane);
  
  JLabel lblOrigem = new JLabel("Origem");
  
  textField = new JTextField();
  textField.setColumns(10);
  
  JButton button = new JButton("...");
  
  JLabel lblDestino = new JLabel("Destino");
  
  textField_1 = new JTextField();
  textField_1.setColumns(10);
  
  JButton button_1 = new JButton("...");
  
  tglbtnIniciar = new JToggleButton("Iniciar");
  
  JScrollPane scrollPane = new JScrollPane();
  GroupLayout gl_contentPane = new GroupLayout(contentPane);
  gl_contentPane.setHorizontalGroup(
   gl_contentPane.createParallelGroup(Alignment.LEADING)
    .addGroup(gl_contentPane.createSequentialGroup()
     .addContainerGap()
     .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
      .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE)
      .addGroup(gl_contentPane.createSequentialGroup()
       .addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING)
        .addComponent(lblDestino)
        .addComponent(lblOrigem))
       .addPreferredGap(ComponentPlacement.RELATED)
       .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
        .addComponent(textField_1, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 313, Short.MAX_VALUE)
        .addComponent(textField, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE))
       .addPreferredGap(ComponentPlacement.RELATED)
       .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
        .addComponent(button, Alignment.TRAILING)
        .addComponent(button_1, Alignment.TRAILING)))
      .addComponent(tglbtnIniciar, Alignment.TRAILING))
     .addContainerGap())
  );
  gl_contentPane.setVerticalGroup(
   gl_contentPane.createParallelGroup(Alignment.LEADING)
    .addGroup(gl_contentPane.createSequentialGroup()
     .addContainerGap()
     .addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
      .addComponent(lblOrigem)
      .addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
      .addComponent(button))
     .addPreferredGap(ComponentPlacement.RELATED)
     .addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
      .addComponent(lblDestino)
      .addComponent(textField_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
      .addComponent(button_1))
     .addPreferredGap(ComponentPlacement.RELATED)
     .addComponent(tglbtnIniciar)
     .addPreferredGap(ComponentPlacement.RELATED)
     .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 143, Short.MAX_VALUE)
     .addContainerGap())
  );
  
  textArea = new JTextArea();
  scrollPane.setViewportView(textArea);
  contentPane.setLayout(gl_contentPane);
 }
}


É código automático, é feio mesmo.
Faça agora uma classe que desempenhará o papel de controle. Eis o esqueleto dela:

package sample.filewatcher.controller;

import java.io.File;

public class MyFileWatcher {

 private File source, destiny;

 public void setSource(String src) {

 }

 public void setDestiny(String dst) {

 }

 public void startWatch() {
  
 }

 public void stopWatch() {
  
 }
}

E, por fim, vamos fazer uma classe que entende do negócio:

package sample.filewatcher.business;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class TheTxtFileBusiness {

 public void moveTxts(File src, File dst) throws IOException {
  File[] files = src.listFiles(new FilenameFilter() {
   @Override
   public boolean accept(File arg0, String arg1) {
    return arg1.endsWith(".txt");
   }
  });
  for (File f : files) {
   Path destiny = Paths.get(dst.getCanonicalPath(), f.getName());
   Files.move(f.toPath(), destiny);
  }
 }
}

Podemos dizer que o negócio de mover arquivos é, em resumo, isso aí.

Ainda não funciona, mas vamos mudar nosso código, hora de integrar:

package sample.filewatcher.view;

import java.awt.EventQueue;

public class TheFrame extends JFrame {

 /**
  * 
  */
 private static final long serialVersionUID = -6742814419164072401L;
 private JPanel contentPane;
 private JTextField txtOrigem;
 private JTextField txtDestino;
 private JTextArea textArea;
 private JToggleButton tglbtnIniciar;
 private MyFileWatcher watcher = new MyFileWatcher();

 private static final Logger LOG = Logger.getAnonymousLogger();
 
 /**
  * Launch the application.
  */
 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {
     TheFrame frame = new TheFrame();
     frame.setVisible(true);
    } catch (Exception e) {
     LOG.info(e.getMessage());
     e.printStackTrace();
    }
   }
  });
 }

 private String getPath() {
  JFileChooser jfc = new JFileChooser();
  jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
  int i = jfc.showOpenDialog(this);
  if (i == JFileChooser.APPROVE_OPTION)
   return jfc.getSelectedFile().getAbsolutePath();
  return null;
 }

 private void msg(Object message) {
  JOptionPane.showMessageDialog(this, message);
  LOG.info(message.toString());
 }

 /**
  * Create the frame.
  */
 public TheFrame() {
  setTitle("Filewatcher");
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setBounds(100, 100, 450, 300);
  contentPane = new JPanel();
  contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  setContentPane(contentPane);

  JLabel lblOrigem = new JLabel("Origem");

  txtOrigem = new JTextField();
  txtOrigem.setColumns(10);

  JButton button = new JButton("...");
  button.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    String orig = getPath();
    if (orig != null)
     txtOrigem.setText(orig);
   }
  });

  JLabel lblDestino = new JLabel("Destino");

  txtDestino = new JTextField();
  txtDestino.setColumns(10);

  JButton button_1 = new JButton("...");
  button_1.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    String orig = getPath();
    if (orig != null)
     txtDestino.setText(orig);
   }
  });

  tglbtnIniciar = new JToggleButton("Iniciar");
  tglbtnIniciar.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    try {
     String orig = txtOrigem.getText();
     String dest = txtDestino.getText();
     if (orig.equals(dest)) {
      String s = "Origem não pode ser igual ao destino";
      throw new Exception(s);
     }
     watcher.setSource(orig);
     watcher.setDestiny(dest);
     if (tglbtnIniciar.isSelected()) {
      watcher.startWatch();
      tglbtnIniciar.setText("Parar");
     } else {
      watcher.stopWatch();
      tglbtnIniciar.setText("Iniciar");
     }
    } catch (Exception ex) {
     ex.printStackTrace();
     tglbtnIniciar.setSelected(false);
     watcher.stopWatch();
     msg(ex);
    }
   }
  });

  JScrollPane scrollPane = new JScrollPane();
  GroupLayout gl_contentPane = new GroupLayout(contentPane);
  gl_contentPane
    .setHorizontalGroup(gl_contentPane
      .createParallelGroup(Alignment.LEADING)
      .addGroup(
        gl_contentPane
          .createSequentialGroup()
          .addContainerGap()
          .addGroup(
            gl_contentPane
              .createParallelGroup(
                Alignment.LEADING)
              .addComponent(
                scrollPane,
                GroupLayout.DEFAULT_SIZE,
                404,
                Short.MAX_VALUE)
              .addGroup(
                gl_contentPane
                  .createSequentialGroup()
                  .addGroup(
                    gl_contentPane
                      .createParallelGroup(
                        Alignment.TRAILING)
                      .addComponent(
                        lblDestino)
                      .addComponent(
                        lblOrigem))
                  .addPreferredGap(
                    ComponentPlacement.RELATED)
                  .addGroup(
                    gl_contentPane
                      .createParallelGroup(
                        Alignment.LEADING)
                      .addComponent(
                        txtDestino,
                        Alignment.TRAILING,
                        GroupLayout.DEFAULT_SIZE,
                        313,
                        Short.MAX_VALUE)
                      .addComponent(
                        txtOrigem,
                        Alignment.TRAILING,
                        GroupLayout.DEFAULT_SIZE,
                        315,
                        Short.MAX_VALUE))
                  .addPreferredGap(
                    ComponentPlacement.RELATED)
                  .addGroup(
                    gl_contentPane
                      .createParallelGroup(
                        Alignment.LEADING)
                      .addComponent(
                        button,
                        Alignment.TRAILING)
                      .addComponent(
                        button_1,
                        Alignment.TRAILING)))
              .addComponent(
                tglbtnIniciar,
                Alignment.TRAILING))
          .addContainerGap()));
  gl_contentPane
    .setVerticalGroup(gl_contentPane
      .createParallelGroup(Alignment.LEADING)
      .addGroup(
        gl_contentPane
          .createSequentialGroup()
          .addContainerGap()
          .addGroup(
            gl_contentPane
              .createParallelGroup(
                Alignment.BASELINE)
              .addComponent(lblOrigem)
              .addComponent(
                txtOrigem,
                GroupLayout.PREFERRED_SIZE,
                GroupLayout.DEFAULT_SIZE,
                GroupLayout.PREFERRED_SIZE)
              .addComponent(button))
          .addPreferredGap(
            ComponentPlacement.RELATED)
          .addGroup(
            gl_contentPane
              .createParallelGroup(
                Alignment.BASELINE)
              .addComponent(
                lblDestino)
              .addComponent(
                txtDestino,
                GroupLayout.PREFERRED_SIZE,
                GroupLayout.DEFAULT_SIZE,
                GroupLayout.PREFERRED_SIZE)
              .addComponent(button_1))
          .addPreferredGap(
            ComponentPlacement.RELATED)
          .addComponent(tglbtnIniciar)
          .addPreferredGap(
            ComponentPlacement.RELATED)
          .addComponent(scrollPane,
            GroupLayout.DEFAULT_SIZE, 143,
            Short.MAX_VALUE)
          .addContainerGap()));

  textArea = new JTextArea();
  scrollPane.setViewportView(textArea);
  contentPane.setLayout(gl_contentPane);
 }
}


package sample.filewatcher.controller;

import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;

import sample.filewatcher.business.TheTxtFileBusiness;

public class MyFileWatcher {

 private File source, destiny;
 private boolean watching;
 private TheTxtFileBusiness business = new TheTxtFileBusiness();

 private static final Logger LOG = Logger.getAnonymousLogger();
 
 public void setSource(String src) throws Exception {
  this.source = getFolder(src);
 }

 public void setDestiny(String dst) throws Exception {
  this.destiny = getFolder(dst);
 }

 public void startWatch() throws Exception {
  LOG.info("starting watch thread");
  watching = true;
  if (source == null)
   throw new Exception("Origem não informada");
  if (destiny == null)
   throw new Exception("Destino não informado");
  new Thread() {
   public void run() {
    while (watching) {
     try {
      business.moveTxts(source, destiny);
     } catch (IOException e) {
      e.printStackTrace();
      watching = false;
     }
     slp();
    }
   };
  }.start();
 }

 public void stopWatch() {
  LOG.info("stopping watcher");
  watching = false;
 }

 private void slp() {
  try {
   Thread.sleep(1000);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 private void valida(File folder) throws Exception {
  if (!folder.exists())
   throw new Exception("Diretório não existe");
  if (!folder.isDirectory())
   throw new Exception("Diretório não é diretório");
 }

 private File getFolder(String path) throws Exception {
  File folder = new File(path);
  valida(folder);
  return folder;
 }
}

package sample.filewatcher.business;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Logger;

public class TheTxtFileBusiness {

 private static final Logger LOG = Logger.getAnonymousLogger();
 
 public void moveTxts(File src, File dst) throws IOException {
  File[] files = src.listFiles(new FilenameFilter() {
   @Override
   public boolean accept(File arg0, String arg1) {
    return arg1.endsWith(".txt");
   }
  });
  LOG.info("Files found: "+files.length);
  for (File f : files) {
   Path destiny = Paths.get(dst.getCanonicalPath(), f.getName());
   Files.move(f.toPath(), destiny);
  }
 }
}

Adicionamos uns poucos registros de log. Se você testar, verá que já temos funcionamento básico... Ocorre que algo ainda não está funcionando: como notificar, a partir do controle e do model, a camada de visão?

A primeira saída é escrever uma estrutura de listeners (acessores de registro, implementação de interface, por aí vai). Esta saída envolve, infelizmente uma boa mão de obra no tocante a código e manutenção das instâncias. Para nosso pequeno exemplo serviria, mas e em um projeto de pequeno porte? E em um projeto maior?

Falemos do guice agora.

Faça o download do mesmo e dicione-o como dependência no projeto:

http://code.google.com/p/google-guice/downloads/detail?name=guice-3.0.zip&can=2&q=

Em seguida, façamos as seguintes modificações de código:

package sample.filewatcher.business;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Logger;

import javax.inject.Inject;

import sample.filewatcher.view.TheFrame;

public class TheTxtFileBusiness {

 private static final Logger LOG = Logger.getAnonymousLogger();
 @Inject
 private TheFrame frame;

 public void moveTxts(File src, File dst) throws IOException {
  File[] files = src.listFiles(new FilenameFilter() {
   @Override
   public boolean accept(File arg0, String arg1) {
    return arg1.endsWith(".txt");
   }
  });
  String s = "Files found: " + files.length;
  LOG.info(s);
  frame.log(s);
  for (File f : files) {
   Path destiny = Paths.get(dst.getCanonicalPath(), f.getName());
   Files.move(f.toPath(), destiny);
  }
 }
}


package sample.filewatcher.controller;

import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;

import javax.inject.Inject;

import sample.filewatcher.business.TheTxtFileBusiness;
import sample.filewatcher.view.TheFrame;

public class MyFileWatcher {

 private File source, destiny;
 private boolean watching;
 @Inject
 private TheTxtFileBusiness business;// = new TheTxtFileBusiness();
 @Inject
 private TheFrame frame;

 private static final Logger LOG = Logger.getAnonymousLogger();
 
 public void setSource(String src) throws Exception {
  this.source = getFolder(src);
 }

 public void setDestiny(String dst) throws Exception {
  this.destiny = getFolder(dst);
 }

 public void startWatch() throws Exception {
  String s = "starting watch thread";
  LOG.info(s);
  frame.log(s);
  watching = true;
  if (source == null)
   throw new Exception("Origem não informada");
  if (destiny == null)
   throw new Exception("Destino não informado");
  new Thread() {
   public void run() {
    while (watching) {
     try {
      business.moveTxts(source, destiny);
     } catch (IOException e) {
      e.printStackTrace();
      watching = false;
     }
     slp();
    }
   };
  }.start();
 }

 public void stopWatch() {
  String s = "stopping watcher";
  LOG.info(s);
  frame.log(s);
  watching = false;
 }

 private void slp() {
  try {
   Thread.sleep(1000);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 private void valida(File folder) throws Exception {
  if (!folder.exists())
   throw new Exception("Diretório não existe");
  if (!folder.isDirectory())
   throw new Exception("Diretório não é diretório");
 }

 private File getFolder(String path) throws Exception {
  File folder = new File(path);
  valida(folder);
  return folder;
 }
}


package sample.filewatcher.view;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Logger;

import javax.inject.Inject;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.EmptyBorder;

import sample.filewatcher.controller.MyFileWatcher;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class TheFrame extends JFrame {

 /**
  * 
  */
 private static final long serialVersionUID = -6742814419164072401L;
 private JPanel contentPane;
 private JTextField txtOrigem;
 private JTextField txtDestino;
 private JTextArea textArea;
 private JToggleButton tglbtnIniciar;
 private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 @Inject
 private MyFileWatcher watcher;// = new MyFileWatcher();

 private static final Logger LOG = Logger.getAnonymousLogger();

 /**
  * Launch the application.
  */
 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {
     Injector in = Guice.createInjector();
     // TheFrame frame = new TheFrame();
     TheFrame frame = in.getInstance(TheFrame.class);
     frame.setVisible(true);
    } catch (Exception e) {
     LOG.info(e.getMessage());
     e.printStackTrace();
    }
   }
  });
 }

 public void log(Object message) {
  String tst = "[" + sdf.format(new Date()) + "] ";
  textArea.append(tst + message + "\n");
 }

 private String getPath() {
  JFileChooser jfc = new JFileChooser();
  jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
  int i = jfc.showOpenDialog(this);
  if (i == JFileChooser.APPROVE_OPTION)
   return jfc.getSelectedFile().getAbsolutePath();
  return null;
 }

 private void msg(Object message) {
  JOptionPane.showMessageDialog(this, message);
  LOG.info(message.toString());
 }

 /**
  * Create the frame.
  */
 public TheFrame() {
  setTitle("Filewatcher");
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setBounds(100, 100, 450, 300);
  contentPane = new JPanel();
  contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  setContentPane(contentPane);

  JLabel lblOrigem = new JLabel("Origem");

  txtOrigem = new JTextField();
  txtOrigem.setColumns(10);

  JButton button = new JButton("...");
  button.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    String orig = getPath();
    if (orig != null)
     txtOrigem.setText(orig);
   }
  });

  JLabel lblDestino = new JLabel("Destino");

  txtDestino = new JTextField();
  txtDestino.setColumns(10);

  JButton button_1 = new JButton("...");
  button_1.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    String orig = getPath();
    if (orig != null)
     txtDestino.setText(orig);
   }
  });

  tglbtnIniciar = new JToggleButton("Iniciar");
  tglbtnIniciar.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    try {
     String orig = txtOrigem.getText();
     String dest = txtDestino.getText();
     if (orig.equals(dest)) {
      String s = "Origem não pode ser igual ao destino";
      throw new Exception(s);
     }
     watcher.setSource(orig);
     watcher.setDestiny(dest);
     if (tglbtnIniciar.isSelected()) {
      watcher.startWatch();
      tglbtnIniciar.setText("Parar");
     } else {
      watcher.stopWatch();
      tglbtnIniciar.setText("Iniciar");
     }
    } catch (Exception ex) {
     ex.printStackTrace();
     tglbtnIniciar.setSelected(false);
     watcher.stopWatch();
     msg(ex);
     log(ex.getMessage());
     
    }
   }
  });

  JScrollPane scrollPane = new JScrollPane();
  GroupLayout gl_contentPane = new GroupLayout(contentPane);
  gl_contentPane
    .setHorizontalGroup(gl_contentPane
      .createParallelGroup(Alignment.LEADING)
      .addGroup(
        gl_contentPane
          .createSequentialGroup()
          .addContainerGap()
          .addGroup(
            gl_contentPane
              .createParallelGroup(
                Alignment.LEADING)
              .addComponent(
                scrollPane,
                GroupLayout.DEFAULT_SIZE,
                404,
                Short.MAX_VALUE)
              .addGroup(
                gl_contentPane
                  .createSequentialGroup()
                  .addGroup(
                    gl_contentPane
                      .createParallelGroup(
                        Alignment.TRAILING)
                      .addComponent(
                        lblDestino)
                      .addComponent(
                        lblOrigem))
                  .addPreferredGap(
                    ComponentPlacement.RELATED)
                  .addGroup(
                    gl_contentPane
                      .createParallelGroup(
                        Alignment.LEADING)
                      .addComponent(
                        txtDestino,
                        Alignment.TRAILING,
                        GroupLayout.DEFAULT_SIZE,
                        313,
                        Short.MAX_VALUE)
                      .addComponent(
                        txtOrigem,
                        Alignment.TRAILING,
                        GroupLayout.DEFAULT_SIZE,
                        315,
                        Short.MAX_VALUE))
                  .addPreferredGap(
                    ComponentPlacement.RELATED)
                  .addGroup(
                    gl_contentPane
                      .createParallelGroup(
                        Alignment.LEADING)
                      .addComponent(
                        button,
                        Alignment.TRAILING)
                      .addComponent(
                        button_1,
                        Alignment.TRAILING)))
              .addComponent(
                tglbtnIniciar,
                Alignment.TRAILING))
          .addContainerGap()));
  gl_contentPane
    .setVerticalGroup(gl_contentPane
      .createParallelGroup(Alignment.LEADING)
      .addGroup(
        gl_contentPane
          .createSequentialGroup()
          .addContainerGap()
          .addGroup(
            gl_contentPane
              .createParallelGroup(
                Alignment.BASELINE)
              .addComponent(lblOrigem)
              .addComponent(
                txtOrigem,
                GroupLayout.PREFERRED_SIZE,
                GroupLayout.DEFAULT_SIZE,
                GroupLayout.PREFERRED_SIZE)
              .addComponent(button))
          .addPreferredGap(
            ComponentPlacement.RELATED)
          .addGroup(
            gl_contentPane
              .createParallelGroup(
                Alignment.BASELINE)
              .addComponent(
                lblDestino)
              .addComponent(
                txtDestino,
                GroupLayout.PREFERRED_SIZE,
                GroupLayout.DEFAULT_SIZE,
                GroupLayout.PREFERRED_SIZE)
              .addComponent(button_1))
          .addPreferredGap(
            ComponentPlacement.RELATED)
          .addComponent(tglbtnIniciar)
          .addPreferredGap(
            ComponentPlacement.RELATED)
          .addComponent(scrollPane,
            GroupLayout.DEFAULT_SIZE, 143,
            Short.MAX_VALUE)
          .addContainerGap()));

  textArea = new JTextArea();
  scrollPane.setViewportView(textArea);
  contentPane.setLayout(gl_contentPane);
 }
}


Observe como a anotação é basta para que tenhamos uma instância para nosso uso.

Não há necessidade sequer de get/set, apenas precisamos da anotação.

Adicionalmente, dou foco na modificação feita no entry point da aplicação:

 /**
  * Launch the application.
  */
 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {
     Injector in = Guice.createInjector();
     // TheFrame frame = new TheFrame();
     TheFrame frame = in.getInstance(TheFrame.class);
     frame.setVisible(true);
    } catch (Exception e) {
     LOG.info(e.getMessage());
     e.printStackTrace();
    }
   }
  });
 }

No lugar de instanciarmos a classe diretamente, pedimos ao injetor de dependências uma instância da mesma.
E assim temos resolvidas de forma transparente todas as referências.
Caso você seja purista e decida descer para as camadas mais profundas (controller/business) uma interface em vez da referência para a view, o injetor permite que você forneça um módulo, e num módulo você pode dizer quem implementa qual interface, conforme você vai ler na documentação oficial do guice.

Sem mais, e boa sorte.

Nenhum comentário :

Postar um comentário