需要更新变量,主线程还是其他线程?

jacho981

对不起,如果这个问题听起来很愚蠢,我已经编程了太长时间了,所以我有这类新手问题...

我有一个JFrame(来自netBeans的JFrame表单),其中包含一些变量(arrayList,int ...)。经过一个过程,此变量会更改。该过程是通过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);
    }

这有意义吗?有什么办法可以在不同的线程中进行处理,然后将arrayLists和变量返回到主线程中?

在此先感谢您的帮助。

编辑

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

    }     
无情

有什么办法可以在不同的线程中进行处理,然后将arrayLists和变量返回到主线程中?

就在这里。您可以(可能应该)在dialog.setVisible(true)使用后启动一个新线程

new Thread() {
    @Override
    public void run() {
        getNewValues();
    }
}.start();

一旦完成这项工作,就可以从“工作者”线程中调用

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        //overwrite existing variables, update GUI elements, trigger repaints, etc.
        dialog.setVisible(false);
    }
};

但是,您应始终尝试将数据与视图分开。这意味着:您可能不应该从工作线程中调用这些操作,而应实现观察者模式以通知GUI数据已更改并刷新自身。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

主线程等待其他线程

来自分类Dev

主线程等待其他线程

来自分类Dev

当所有其他线程在主线程之前完成时,为什么仍然需要.join?

来自分类Dev

Android主线程与其他线程之间的通信

来自分类Dev

C#中主线程和其他线程的基准

来自分类Dev

主线程和其他线程之间的C差异

来自分类Dev

等待主线程,直到其他线程未完成!

来自分类Dev

从其他线程更新GUI

来自分类Dev

从其他线程更新UI

来自分类Dev

从其他线程更新 AtomicInteger

来自分类Dev

Python Tkinter变量未在其他线程中更新

来自分类Dev

主线程中的多线程矩阵乘法是否不等到其他线程完成其工作?

来自分类Dev

Android主线程-是否与其他应用共享

来自分类Dev

为什么休眠主线程会更改Java中正在运行的其他线程的行为?

来自分类Dev

当主线程调用sys.exit()时,其他线程会怎样?

来自分类Dev

除了主线程之外,还有其他特殊线程吗?

来自分类Dev

如何从Android应用程序中的主线程以外的其他线程启动新活动?

来自分类Dev

为什么休眠主线程会更改Java中正在运行的其他线程的行为?

来自分类Dev

停止其他线程的线程

来自分类Dev

需要在主线程上执行什么

来自分类常见问题

为什么主线程不等待其他异步进程(线程)完成。allOff无法正常工作

来自分类Dev

我应该关心Lollipop中以及其他之外的主线程和UI线程之间的区别吗?

来自分类Dev

在处理其他一些线程(POSIX)时保持主线程(Qt应用程序)的响应

来自分类Dev

如何从其他线程或意图服务调用getWritableDatabase(),应用在主线程中调用时崩溃

来自分类Dev

JLabel是否不需要其他线程即可刷新?

来自分类Dev

如何访问在主线程中定义的变量?

来自分类Dev

用Java编程Hangman,主线程错误(以及其他错误)

来自分类Dev

更新主线程不起作用

来自分类Dev

如何不从主线程更新textview?

Related 相关文章

  1. 1

    主线程等待其他线程

  2. 2

    主线程等待其他线程

  3. 3

    当所有其他线程在主线程之前完成时,为什么仍然需要.join?

  4. 4

    Android主线程与其他线程之间的通信

  5. 5

    C#中主线程和其他线程的基准

  6. 6

    主线程和其他线程之间的C差异

  7. 7

    等待主线程,直到其他线程未完成!

  8. 8

    从其他线程更新GUI

  9. 9

    从其他线程更新UI

  10. 10

    从其他线程更新 AtomicInteger

  11. 11

    Python Tkinter变量未在其他线程中更新

  12. 12

    主线程中的多线程矩阵乘法是否不等到其他线程完成其工作?

  13. 13

    Android主线程-是否与其他应用共享

  14. 14

    为什么休眠主线程会更改Java中正在运行的其他线程的行为?

  15. 15

    当主线程调用sys.exit()时,其他线程会怎样?

  16. 16

    除了主线程之外,还有其他特殊线程吗?

  17. 17

    如何从Android应用程序中的主线程以外的其他线程启动新活动?

  18. 18

    为什么休眠主线程会更改Java中正在运行的其他线程的行为?

  19. 19

    停止其他线程的线程

  20. 20

    需要在主线程上执行什么

  21. 21

    为什么主线程不等待其他异步进程(线程)完成。allOff无法正常工作

  22. 22

    我应该关心Lollipop中以及其他之外的主线程和UI线程之间的区别吗?

  23. 23

    在处理其他一些线程(POSIX)时保持主线程(Qt应用程序)的响应

  24. 24

    如何从其他线程或意图服务调用getWritableDatabase(),应用在主线程中调用时崩溃

  25. 25

    JLabel是否不需要其他线程即可刷新?

  26. 26

    如何访问在主线程中定义的变量?

  27. 27

    用Java编程Hangman,主线程错误(以及其他错误)

  28. 28

    更新主线程不起作用

  29. 29

    如何不从主线程更新textview?

热门标签

归档