【问题标题】:threads and swing components in javajava中的线程和swing组件
【发布时间】:2013-09-28 18:19:15
【问题描述】:

如您所见,我一直在研究并尝试在 ma​​in.java 类中设置一个线程。这是主要方法:

public static void main(String args[]) {     
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new main().setVisible(true);
            check ch = new check();
            ch.start();          
        }
    });
}

Main 方法从 check.java 类调用一个名为 ch 的线程。

这是线程类:

public class check extends Thread {

    public JTextArea estado = new JTextArea();   
    public JTextField updatedVersion = new JTextField();
    public JLabel updatedLabel = new JLabel();
    public String catchUpdatedVersion;
    int UPDATENUMBER;
    int CURRENTNUMBER;

    public void run() {
        String infURL = "https://thread.googlecode.com/svn/trunk/thread.inf";
        String name = "thread.inf";
        File file = new File(name);
        try {
            URLConnection conn = new URL(infURL).openConnection();
            conn.connect();
            estado.append("Conectando al servidor...");
            estado.append(System.getProperty("line.separator"));
            estado.append(" -- Buscando actualizaciones... --");
            estado.append(System.getProperty("line.separator"));
            InputStream in = conn.getInputStream();
            OutputStream out = new FileOutputStream(file);
            int b = 0;
            while (b != -1) {
                b = in.read();
                if (b != -1) {
                    out.write(b);
                }
            }
            out.close();
            in.close();
        } catch (MalformedURLException ex) {
        } catch (IOException ioe) { }

        String fileToReadUpdatedVersion = "thread.inf";
        try {
            BufferedReader br = new BufferedReader(
                    new FileReader(fileToReadUpdatedVersion));
            String brr = br.readLine();
            catchUpdatedVersion = brr.substring(34,42);
            String catchUpdatedShortVersion = brr.substring(15,16);
            UPDATENUMBER = Integer.parseInt(catchUpdatedShortVersion);

            String fileToReadCurrentVer = "thread.inf";
            BufferedReader brrw = new BufferedReader(
                                new FileReader(fileToReadCurrentVer));
            String brrwREAD = brrw.readLine();
            String catchCurrentShortVersion = brrwREAD.substring(15,16);
            CURRENTNUMBER = Integer.parseInt(catchCurrentShortVersion);

            if (CURRENTNUMBER >= UPDATENUMBER) {
                estado.setText("No se han encontrado actualizaciones.");
            } else {
                updatedVersion.setForeground(new Color(0,102,0));
                updatedLabel.setForeground(new Color(0,153,51));
                updatedVersion.setText(catchUpdatedVersion);
                estado.append("-------------------" +
                        "NUEVA ACTUALIZACIÓN DISPONIBLE: " +
                            catchUpdatedVersion + " -------------------");;
                estado.append(System.getProperty("line.separator"));
                estado.append("Descargando actualizaciones... " +
                            "Espere por favor, no cierre este " +
                                "programa hasta que esté completado...");
                try {
                    String updateURL = "https://thread.googlecode.com/" +
                                                    "svn/trunk/thread.inf";
                    String updatedname = (catchUpdatedVersion + ".zip");
                    File updatedfile = new File(updatedname);
                    URLConnection conn = new URL(updateURL).openConnection();
                    conn.connect();
                    estado.append(System.getProperty("line.separator"));
                    estado.append("   Archivo actual: " + updatedname);
                    estado.append(System.getProperty("line.separator"));
                    estado.append("   Tamaño: " + 
                        conn.getContentLength() / 1000 / 1000 + " MB");
                    InputStream in = conn.getInputStream();
                    OutputStream out = new FileOutputStream(updatedfile);
                    int c = 0;
                    while (c != -1) {
                        c = in.read();
                        if (c != -1) {
                            out.write(c);
                        }
                    }
                    out.close();
                    in.close();    
                } catch (MalformedURLException ex) {
                    ex.printStackTrace();
                }
            }
        } catch (IOException ioe) {
            System.out.println(ioe);
            ioe.printStackTrace();
        }
    }
}

当我运行程序时,线程无法正常工作。它应该下载一个文件,然后在 ma​​in.java 类的 JTextArea 中显示其进度。它确实下载了文件,但在 JTextArea 中没有出现任何内容。

我的错误在哪里?

编辑:显示所有代码。

【问题讨论】:

  • 问题没有显示,你没有显示应该显示的代码......
  • 注意 gui 在事件调度线程中的工作。
  • @SotiriosDelimanolis 好的。我把所有的代码
  • 你需要使用 SwingWorker (docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html) 然后使用 process 方法更新 UI (docs.oracle.com/javase/6/docs/api/javax/swing/…)。
  • 不做详细介绍 - 这段代码看起来像个大黑客。您正在混合构建 UI 的代码和从 Web 加载数据的行为/业务逻辑代码。你在非 UI 线程中做 UI 相关的事情等等。我不知道,从哪里开始......

标签: java multithreading swing


【解决方案1】:

问题 #1

您尝试更新的组件无论如何都没有连接到屏幕...

public JTextArea estado = new JTextArea();   
public JTextField updatedVersion = new JTextField();
public JLabel updatedLabel = new JLabel();

这意味着,无论您何时与这些组件交互,它都不会对屏幕上的内容产生任何影响...

问题 #2

您正在尝试从事件调度线程的上下文之外对 UI 进行修改。这严重违反了 Swing 线程规则。

public class Check extends SwingWorker<String, String> {

    private JTextArea estado;   
    Private JTextField updatedVersion;
    private JLabel updatedLabel;
    private String catchUpdatedVersion;
    int UPDATENUMBER;
    int CURRENTNUMBER;

    public Check(JTextArea estado, JTextField updatedVersion, JLabel updatedLabel) {
        this.estado = estado;
        this.updatedVersion = updatedVersion;
        this.updatedLabel = updatedLabel;
    }

    protected void process(List<String> values) {
        for (String value : values) {
            estado.append(value);
        }
    }

    protected String doInBackground() throws Exception {
        String infURL = "https://thread.googlecode.com/svn/trunk/thread.inf";
        String name = "thread.inf";
        File file = new File(name);

        URLConnection conn = new URL(infURL).openConnection();
        conn.connect();
        publish("Conectando al servidor...");
        publish(System.getProperty("line.separator"));
        publish(" -- Buscando actualizaciones... --");
        publish(System.getProperty("line.separator"));
        /*...*/          
    }
}

如果您需要进行任何后处理,那么您还需要覆盖 done,这将在 doInBackground 存在之后调用,但在 EDT 的上下文中调用

更多详情请阅读Concurrency in Swing

【讨论】:

  • 是的,我通过实现一个 swingworker 方法解决了问题 1 和 2,现在一切正常。我的程序应该下载一个文件并在进度条中表示它的百分比。它实际上下载了文件,但进度条直到下载完成才移动,然后突然标记为 100%。我看不到 0 到 100 之间的“动画”
  • SwingWorker 能够为exampleexampleexampleexample 提供自己的进度反馈
猜你喜欢
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 2011-02-03
  • 1970-01-01
  • 2014-03-31
  • 1970-01-01
相关资源
最近更新 更多