gpt4 book ai didi

java - 需要更新变量,主线程还是不同线程?

转载 作者:行者123 更新时间:2023-12-01 22:55:50 25 4
gpt4 key购买 nike

抱歉,如果这个问题听起来很愚蠢,我编程的时间不长,所以我有这样的新手问题......

我有一个带有一些变量(arrayList、int...)的 JFrame(来自 netBeans 的 JFrame 形式)。经过一个过程后,这个变量会发生变化。该过程是通过 JCDB 驱动程序进行 mySQL 查询,使用数据更新一些 arrayList,我用它来填充 Jtable...等等...

起初(可怜的我)我做了一个 SwingWorker。通过 SwingWorker 构造函数,我传递这些变量(大约 6 个变量或多或少),并使用它们进行处理和填充表格。

我以为我能够在重写的 Done() 方法中更新这些变量的值(又可怜我了),而不仅仅是 GUI 组件。

从这次失败中我学到了很多东西:1)即使我通过构造函数传递了变量,但这并不意味着它们会在它们来自的地方进行更新。2) SwingWorker只能返回1个变量,并且可以修改GUI组件。

所以,这是我的要点,我怎样才能做我想做的事?我了解到 SwingWorker 类无法完成此操作,但是如何才能完成呢?

我不想像那样将代码放入鼠标单击事件中,因为它会阻止我的 EDT,并且不会通知用户正在发生的情况。

我想做这样的事情:将代码放在鼠标单击事件中,并显示一个对话框,以便用户知道当前正在发生一个进程。

private void jButton_calcular_rutaMousePressed(java.awt.event.MouseEvent evt) {                                                   
// BOTON CALCULAR RUTA

int index = jL_empGeo.getSelectedIndex();

JOptionPane optionPane = new JOptionPane("Descargando ruta, espere por favor.", JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[]{}, null);
JDialog dialog = new JDialog();
dialog.setTitle("Descarga");
dialog.setModalityType(Dialog.DEFAULT_MODALITY_TYPE);

dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
dialog.setLocation(dim.width / 2 - dialog.getSize().width / 2, dim.height / 2 - dialog.getSize().height / 2);
dialog.setContentPane(optionPane);

dialog.pack();

dialog.setLocationRelativeTo(this);

dialog.setVisible(true);

//
// THE PROCESSING TAKES PLACE HERE
//
//
// mySQL query
//
// update arrayLists and variables
//
// update GUI components
//
//

dialog.setVisible(false);
}

这有什么意义吗?有没有办法在不同的线程中进行处理,然后将数组列表和变量返回主线程?

预先感谢您的帮助。

编辑

SwingWorker 类

package descargas;

import clases.Empleados;
import clases.InfoPuntoRuta;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
import java.awt.Dimension;
import java.awt.Image;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.SwingWorker;
import javax.swing.table.DefaultTableModel;
import maps.java.Geocoding;
import maps.java.Route;
import maps.java.StaticMaps;

public class ActualizarRuta2 extends SwingWorker<Void, Void> {

int index;
ArrayList<Empleados> arrayEmpleados;
ArrayList<InfoPuntoRuta> listaPuntosRuta;
DefaultTableModel modeloTablaRutas;
JDialog dialog;
ArrayList<String> listaIntermedios;
JLabel jLab_RutaMAP;
ImageIcon icono;
int origenInt;
int destinoInt;
int destinoMax;

public ActualizarRuta2(int index, int origenInt, int destinoInt, int destinoMax, ArrayList<Empleados> arrayEmpleados, ArrayList<InfoPuntoRuta> listaPuntosRuta, DefaultTableModel modeloTablaRutas, JDialog dialog, JLabel jLab_RutaMAP) {
this.index = index;
this.arrayEmpleados = arrayEmpleados;
this.listaPuntosRuta = listaPuntosRuta;
this.modeloTablaRutas = modeloTablaRutas;
this.dialog = dialog;
this.jLab_RutaMAP = jLab_RutaMAP;
this.origenInt = origenInt;
this.destinoInt = destinoInt;
this.destinoMax = destinoMax;
}

@Override
protected Void doInBackground() throws Exception {

listaIntermedios = new ArrayList<String>();

// recogemos la fecha actual
DateFormat formatoFecha = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
String dateMIN = formatoFecha.format(cal.getTime()) + " 00:00:01";
String dateMAX = formatoFecha.format(cal.getTime()) + " 23:59:59";

// GENERAR MAPA DE LA RUTA DEL DIA
Connection conexion;
conexion = conexiondb.ConexionDB.getConnection();
if (conexion != null) {
try {
Statement st;
ResultSet rs;

st = (Statement) conexion.createStatement();
rs = st.executeQuery("SELECT * \n"
+ "FROM position\n"
+ "WHERE nombre = '" + arrayEmpleados.get(index) + "'\n"
+ "AND position_date BETWEEN '" + dateMIN + "' AND '" + dateMAX + "'\n"
+ "ORDER BY position_date;");

// vaciamos la lista
//listaPuntosRuta.clear();
//System.out.println(rs.);
// rellenamos la lista
rs.beforeFirst();

while (rs.next()) {
InfoPuntoRuta punto = new InfoPuntoRuta(rs.getString("nombre"),
rs.getString("position_date"), rs.getDouble("latitud"),
rs.getDouble("longitud"));

Geocoding ObjGeocod = new Geocoding();
ArrayList<String> resultadoCI = ObjGeocod.getAddress(punto.getLatitud(), punto.getLongitud());
String direccion = resultadoCI.get(0);

punto.setDireccion(direccion);

listaIntermedios.add(direccion);
listaPuntosRuta.add(punto);
}

//
// DESCARGAR MAPA RUTA
//
int posicionUltimo = (listaIntermedios.size()) - 1;
String origen, destino;

ArrayList<String> waypoints = new ArrayList<String>();
if (listaIntermedios.size() < 10) {
origen = listaIntermedios.get(0);
destino = listaIntermedios.get(posicionUltimo);
for (int i = 1; i < posicionUltimo; i++) {
waypoints.add(listaIntermedios.get(i));
}
} else {
origen = listaIntermedios.get(0);
destino = listaIntermedios.get(9);
for (int i = 1; i < 9; i++) {
waypoints.add(listaIntermedios.get(i));
}
}

// ArrayList<String> prueba = new ArrayList<String>();
// prueba.add("coruña avenida finisterre 65");
// prueba.add("coruña ronda de outeiro 125");
// prueba.add("coruña avenida del ejercito 20");
Route ObjRout = new Route();

String[][] resultadoRuta = ObjRout.getRoute(origen, destino, waypoints, Boolean.TRUE, Route.mode.driving, Route.avoids.nothing);
//String[][] resultadoRuta = ObjRout.getRoute("Madrid", "Barcelona", prueba, Boolean.TRUE, Route.mode.driving, Route.avoids.nothing);
// String[][] resultadoRuta = ObjRout.getRoute("coruña virrey ossorio 25", "pla y cancela, 16, 15005 la coruña, españa", prueba, Boolean.TRUE, Route.mode.driving, Route.avoids.nothing);
String polylinea = ObjRout.getGeneralPolyline();
StaticMaps ObjStatMap = new StaticMaps();
Image resultadoMapa = ObjStatMap.getStaticMapRoute(new Dimension(585, 405), 1, StaticMaps.Format.png, StaticMaps.Maptype.hybrid, polylinea);
icono = new ImageIcon(resultadoMapa);

// RELLENAR TABLA DETALLES DE LA RUTA
modeloTablaRutas.setRowCount(0);

} catch (SQLException | UnsupportedEncodingException | MalformedURLException ex) {
Logger.getLogger(ActualizarRuta2.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
conexion.close();
} catch (SQLException ex) {
Logger.getLogger(ActualizarRuta2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}

@Override
protected void done() {

dialog.dispose();

// RELLENAR TABLA DETALLES DE LA RUTA
for (InfoPuntoRuta p : listaPuntosRuta) {
modeloTablaRutas.addRow(new Object[]{
p.getNombre(), p.getFecha(), p.getDireccion()});
}

// ponemos la imagen de la ruta
jLab_RutaMAP.setIcon(icono);

//
listaIntermedios.clear();

// listaPuntosRuta.clear();
origenInt = 0;
destinoMax = listaPuntosRuta.size() - 1;
if (destinoMax < 9) {
destinoInt = destinoMax;
} else {
destinoInt = 9;
}

}

}

我调用 SwingWorker 的鼠标事件

private void jButton_calcular_rutaMousePressed(java.awt.event.MouseEvent evt) {                                                   
// BOTON CALCULAR RUTA

int index = jL_empGeo.getSelectedIndex();

JOptionPane optionPane = new JOptionPane("Descargando ruta, espere por favor.", JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[]{}, null);
JDialog dialog = new JDialog();
dialog.setTitle("Descarga");
dialog.setModalityType(Dialog.DEFAULT_MODALITY_TYPE);

dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
dialog.setLocation(dim.width / 2 - dialog.getSize().width / 2, dim.height / 2 - dialog.getSize().height / 2);
dialog.setContentPane(optionPane);

dialog.pack();

dialog.setLocationRelativeTo(this);

listaPuntosRuta.clear();
modeloTablaRutas.setRowCount(0);
ActualizarRuta2 task = new ActualizarRuta2(index, origenInt, destinoInt, destinoMax, arrayEmpleados, listaPuntosRuta, modeloTablaRutas, dialog, jLab_RutaMAP);
task.execute();

dialog.setVisible(true);

}

最佳答案

您需要从“SwingWorker”返回到 GUI 的通信。 Java 参数按值传递——因此,您需要某种形式的值持有者

制作一个从 Observable 派生的“数据 bean”,可能是最简单的方法。

public class QueryResults extends Observable {
protected List<SomeItem> itemList;
// getters and setters.
}

从 SwingWorker 中,您需要存储结果并通知观察者。通知必须在事件分派(dispatch)线程上完成,并且 javax.swing.SwingWorker 提供内置功能来在 EDT 上调用 SwingWorker.done()。

我使用“Void”类型作为“结果”,因为数据持有者已经存在并且我们只是将数据加载到其中。 UI 应该已经绑定(bind)到(并观察)它。像这样的事情:

public class QueryWorker<Void,Void> extends SwingWorker {
protected QueryResults holder;
public QueryWorker (QueryResults holder) {
this.holder = holder; // keep the holder & put data into it.
}

@Override
protected Void doInBackground() {
// run the query..
}
@Override
protected void done() {
holder.notifyObservers();
}
}

这是一个简化的示例。例如,它忽略了 UI 在加载过程中想要读取 result-hodler(用于显示刷新)的可能性。您的替代方案是将数据bean与该bean的可观察引用分开。

关于java - 需要更新变量,主线程还是不同线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24071227/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com