3
I have a small application on swing
, where I would like to display progress when certain actions are executed
As an example, I have the listener
below that is run when a JComboBox
is changed. It takes the selected item(which in this case is an object Setor
with id and name), and passes the id pro CadastranteComboModel
, which, in turn, searches the bank for the list of registrants of that past 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 is executed from a network location in Stand-alone mode. So I created a JDialog
only to display a JProgressBar
infinite, but do not know how to pass the line execution CadastranteComboModel cadComboModel = new CadastranteComboModel(setorId);
, for example, for the SwingWorker
in the doInBackground()
.
Trying to get around this problem, I downloaded this code inside the listener
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, only I’ll have to repeat the same block of code in other 7 or 8 methods (some even return values), which have some action that depends on query in the bank, 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 swingworker
and can receive these "problematic" methods as an argument, passing their execution to the doInBackground
, but I don’t know how I can do it.
Is there any way to pass one method as argument to another, and its execution is not performed in the call, but within the method that received it as argument?
Note: the application (the jar, in this case) is in java7, I cannot do in java8 by IT restrictions(but java8 suggestions are welcome).
These methods you want to run on
doInBackground()
all have the same signature?– ramaral
@ramaral unfortunately not :/, only if I bar directly in the controllers, because as can be seen in that question that I did a few days ago, they have in common the interface with exactly the same methods, in the end, practically all methods call some controller and these yes are standardized by interface. Problem is I don’t know if it’s good practice to "call GUI" in a class that has nothing to do with GUI, but if that’s the only solution...
– user28595