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
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