I have a small application in swing
, where I would like to display a progress when certain actions are executed
As an example, I have the listener
below that is executed when a JComboBox
is changed. It takes the selected item (which in this case is a Setor
object with id and name ), and passes the id pro CadastranteComboModel
, which in turn searches the bank for the list of registrants of that last sector and displays in another JComboBox
of registrants:
private void comboSetorItemStateChanged(java.awt.event.ItemEvent evt) {
if (evt.getStateChange() == ItemEvent.SELECTED) {
final int setorId = ((Setor) evt.getItem()).getId();
CadastranteComboModel cadComboModel = new CadastranteComboModel(setorId);
comboUsuario.setModel(cadComboModel);
The problem is that this communication with the bank (which is in HSQL) takes a while because the application runs from a network location in Stand-alone mode. So I created a JDialog
only to display an JProgressBar
infinite, but I do not know how to pass the execution of the CadastranteComboModel cadComboModel = new CadastranteComboModel(setorId);
line, for example, to SwingWorker
in doInBackground()
.
Attempting to work around this problem, I booted this code inside the% quoted%:
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
// esta é a janela que fiz a parte
//com a JProgressBar infinita
ProgressDialog progress;
//esse método que ativa o progresso pelo publish()
// e executa a linha a seguir em uma Thread separada
@Override
protected Void doInBackground() throws Exception {
publish();
CadastranteComboModel cadComboModel = new CadastranteComboModel(setorId);
comboUsuario.setModel(cadComboModel);
return null;
}
@Override
protected void process(List<Void> chunks) {
// getInstance() é o frame da tela como referencia
//esse método é "decorativo"
changeStatusComponent(getInstance(), false);
//chama e exibe a JDialog com a JProgressBar
progress = new ProgressDialog(getInstance(), true);
progress.setLocationRelativeTo(getInstance());
progress.setVisible(true);
}
@Override
protected void done() {
//quando termina a execução no doInBackground
// fecho a tela de progresso
progress.dispose();
changeStatusComponent(getInstance(), true);
}
};
worker.execute();
It works perfectly for the case, but I'm going to have to repeat the same block of code in another 7 or 8 methods (some even return values), which have some action that depends on query in the database, like this one that excludes an office of the table and the bank:
private void btnExcluirOficioActionPerformed(java.awt.event.ActionEvent evt) {
int indiceRowModel = this.tabela.getRowSorter().convertRowIndexToModel(this.tabela.getSelectedRow());
int intOf = (int) this.tabela.getModel().getValueAt(indiceRowModel, 0);
Date date = (Date) this.tabela.getModel().getValueAt(indiceRowModel, 3);
String strAno = new SimpleDateFormat("yyyy").format(date);
String strSetor = (String) this.tabela.getModel().getValueAt(indiceRowModel, 5);
String strOficio = strSetor + " " + intOf + "-" + strAno;
int confirma = JOptionPane.showConfirmDialog(getInstance(), "Excluir o oficio " + strOficio + "?",
ListaDeOficiosUI.TITULO, JOptionPane.YES_NO_OPTION);
if (confirma == JOptionPane.YES_OPTION) {
try {
//por causa desta chamada, vou ter que inserir aquele bloco
// do swingworker
this.tableModel.removeRow(indiceRowModel);
PrintMessageUI.exibirMsg(this.getInstance(), "Oficio" + strOficio + " excluído.");
} catch (ExcecaoPadrao ex) {
PrintMessageUI.exibirError(this, ex.getMessage());
}
}
}
What I need to do is a class that inherits from listener
and can receive these "problematic" methods as arguments, passing them to swingworker
, but I do not know how I can do this.
Is there any way to pass one method as an argument to another, and its execution not be performed on the call, but within the method that received it as an argument?
Note: the application (the jar, in this case) is in java7, I can not do it in java8 for IT restrictions (but suggestions in java8 are welcome).