Java的AWT线程 [英] Java AWT Threads

查看:331
本文介绍了Java的AWT线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在与使用NetBeans Swing GUI的线程的问题。这是我第一次真正尝试开发使用Java的文件系统通知备份程序的GUI。我有两个文件 SyncUI.java Sync.java

pretty多我希望发生的是你进入它创建,创建一个新的同步对象,然后同步线程 jTextField1 文本字段的目录路径电话的processEvents 的对象。当在该目录中的文件被改变我想补充关于变更到列表中的文本。

在当前状态下的UI不再是没有响应,但是的processEvents 不添加任何进入我的列表中。任何想法是什么问题?此外,由于我刚开始使用Java的任何建设性的批评表示欢迎。

SyncUI.java

 包不同步;
进口java.io.IOException异常;
进口java.nio.file.Path;
进口java.nio.file.Paths;
进口java.util.logging.Level中;
进口java.util.logging.Logger中;
进口javax.swing.DefaultListModel中;
进口javax.swing.JList中;
进口javax.swing.SwingUtilities中;公共类SyncUI扩展javax.swing.JFrame中{    公共SyncUI(){
        的initComponents();
    }    @燮pressWarnings(未登记)
    //<主编倍defaultstate =崩溃DESC =生成code>
    私人无效的initComponents(){
        的jButton1 =新javax.swing.JButton中的();
        jTextField1 =新javax.swing.JTextField中的();
        list1的=新java.awt.List中的();        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);        jButton1.setText(开始);
        jButton1.addActionListener(新java.awt.event.ActionListener(){
            公共无效的actionPerformed(EVT java.awt.event.ActionEvent中){
                jButton1ActionPerformed(EVT);
            }
        });        jTextField1.addActionListener(新java.awt.event.ActionListener(){
            公共无效的actionPerformed(EVT java.awt.event.ActionEvent中){
                jTextField1ActionPerformed(EVT);
            }
        });        list1.addActionListener(新java.awt.event.ActionListener(){
            公共无效的actionPerformed(EVT java.awt.event.ActionEvent中){
                list1ActionPerformed(EVT);
            }
        });        org.jdesktop.layout.GroupLayout布局=新org.jdesktop.layout.GroupLayout(的getContentPane());
    的getContentPane()的setLayout(布局)。
    layout.setHorizo​​ntalGroup(
        layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        。新增(layout.createSequentialGroup()
        .addContainerGap()
        。新增(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        。新增(list1的,org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE)
        。新增(layout.createSequentialGroup()
        。新增(jTextField1,org.jdesktop.layout.GroupLayout。preFERRED_SIZE,329,org.jdesktop.layout.GroupLayout。preFERRED_SIZE)
        。新增preferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        。新增(的jButton1)
        。新增(0,0,Short.MAX_VALUE)))
        .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        。新增(layout.createSequentialGroup()
        .addContainerGap()
        。新增(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
        。新增(的jButton1)
        。新增(jTextField1,org.jdesktop.layout.GroupLayout。preFERRED_SIZE,org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,org.jdesktop.layout.GroupLayout。preFERRED_SIZE))
        。新增preferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        。新增(list1的,org.jdesktop.layout.GroupLayout。preFERRED_SIZE,229,org.jdesktop.layout.GroupLayout。preFERRED_SIZE)
        .addContainerGap(25 Short.MAX_VALUE))
    );        包();
    } //< /编辑倍>私人无效jTextField1ActionPerformed(EVT java.awt.event.ActionEvent中){
    jButton1.doClick();
}私人无效jButton1ActionPerformed(EVT java.awt.event.ActionEvent中){
        //我试图用的invokeLater,这解决了用户界面无应答问题的问题
        SwingUtilities.invokeLater(Runnable的新(){
            公共无效的run()
            {
                //创建一个我同步的构造需要在该目录启动文件通知观察家的路径目录
                路径DIR = Paths.get(jTextField1.getText());
                尝试
                {
                    //创建传递给它在我的GUI目录和列表中的新同步对象
                    同步同步=新的同步(目录,list1的);
                    尝试
                    {
                        sync.processEvents();
                    }
                    赶上(InterruptedException的前)
                    {
                        。Logger.getLogger(SyncUI.class.getName())日志(Level.SEVERE,空,前);
                    }
                }
                赶上(IOException异常前)
                {
                    。Logger.getLogger(SyncUI.class.getName())日志(Level.SEVERE,空,前);
                }
            }        });
}私人无效list1ActionPerformed(EVT java.awt.event.ActionEvent中){
    // TODO添加处理code在这里:
}公共静态无效的主要(字符串ARGS [])抛出IOException异常
{
    了java.awt.EventQueue.invokeLater(新的Runnable()
    {
        公共无效的run()
        {
            SyncUI S =新SyncUI();
            s.setVisible(真);
        }
    });
}//变量声明 - 不修改
私人javax.swing.JButton中的jButton1;
私人javax.swing.JTextField中jTextField1;
私人java.awt.List中list1的;
//变量声明结束
}

Sync.java

 包不同步;引入静态java.nio.file.StandardWatchEventKinds *。
导入java.nio.file.attribute *。
进口java.io. *;
导入java.nio.file *。
进口的java.util。*;
进口java.util.logging.Level中;
进口java.util.logging.Logger中;
进口javax.swing.SwingUtilities中;公共类同步
{
    私人最终WatchService WS;
    私人最终地图< WatchKey,路径和GT;键;
    公共java.awt.List中的列表;    公共同步(路径目录,java.awt.List中的列表)抛出IOException异常,InterruptedException的
    {
        this.ws = FileSystems.getDefault()newWatchService()。
        this.keys =新的HashMap< WatchKey,路径>();
        this.list =清单;
        recSet(DIR);
        //this.processEvents();
    }    私人无效寄存器(路径DIR)抛出IOException异常
    {
        WatchKey键= dir.register(WS,ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);
        keys.put(键,DIR);
    }    私人无效recSet(路径开始)抛出IOException异常
    {
        Files.walkFileTree(启动,新SimpleFileVisitor<路径>()
        {
            公共FileVisitResult preVisitDirectory(路径目录,BasicFileAttributes ATTRS)抛出IOException异常
            {
                如果(!Files.isHidden(DIR))
                {
                    注册(DIR);
                    的System.out.println(DIR);
                }
            返回FileVisitResult.CONTINUE;
            }
        });
    }    无效的processEvents()抛出IOException异常,InterruptedException的
    {
        的System.out.println(输入的processEvents);
        SwingUtilities.invokeLater(Runnable的新(){
            公共无效的run()
            {
                的System.out.println(输入运行);
                list.add(测试2);
                list.repaint();
                而(真)
                {
                    WatchKey关键;
                    尝试
                    {
                        键= ws.take();
                    }
                    赶上(InterruptedException的X)
                    {
                        返回;
                    }                    路径DIR = keys.get(键);
                    如果(DIR == NULL)
                    {
                        通信System.err.println(WatchKey无法识别);
                        继续;
                    }                    对于(WatchEvent<>事件:key.pollEvents())
                    {
                        WatchEvent.Kind<> KIND = event.kind();
                        WatchEvent<路径和GT; EV =(WatchEvent<路径>)事件;
                        路径文件名= ev.context();
                        字符串名称= dir.resolve(文件名)的ToString();                        如果(一种==溢出)
                            继续;                        如果(一种== ENTRY_CREATE)
                        {
                            System.out.print(创建的词条:​​);
                            文件f =新的文件(名称);                            如果(f.isDirectory())
                                尝试{
                                    注册(dir.resolve(文件名));
                                }赶上(IOException异常前){
                                    。Logger.getLogger(Sync.class.getName())日志(Level.SEVERE,空,前);
                                }                            的System.out.println(名);
                            list.add(名);
                        }
                        否则,如果(一种== ENTRY_DELETE)
                        {
                            System.out.print(项中删除:);
                            的System.out.println(名);
                        }
                        否则,如果(一种== ENTRY_MODIFY)
                        {
                            文件f =新的文件(名称);
                            如果(!f.isDirectory())
                        {
                            System.out.print(进入修改:);
                            的System.out.println(名);
                        }
                    }                    布尔有效= key.reset();                    如果(!有效)
                        打破;
                    }
                }
            }
        });
    }
}


解决方案

Swing不是线程安全的,因此,如果您tryng更新您将有应用程序冻结的行为在同一个线程的UI。为了解决这个问题,你需要UI代理更新的过程到另一个线程。这是通过使用SwingUtilities.invokeLater(Java 5的和以前的)方法和/或SwingWorker类做(因为Java 6中)。

某些链接:

谷歌搜索:
<一href=\"https://www.google.com.br/search?q=swing+thread+safe\">https://www.google.com.br/search?q=swing+thread+safe

I'm having an issue with Threads using netbeans Swing GUI. This is my first time really trying to develop a GUI for a backup program using Java's File System Notifier. I have two files SyncUI.java and Sync.java.

Pretty much what I want to happen is you enter a directory path in the jTextField1 text field which creates a sync thread that creates a new sync object and then calls processEvents on that object. When a file in that directory is changed I want to add text about the change to the list.

In its current state the UI is no longer not responding, however the processEvents isn't adding anything into my list. Any idea what the problem is? Also since I'm just starting to use java any constructive criticism is welcomed.

SyncUI.java:

package sync;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.SwingUtilities;

public class SyncUI extends javax.swing.JFrame {

    public SyncUI() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        jButton1 = new javax.swing.JButton();
        jTextField1 = new javax.swing.JTextField();
        list1 = new java.awt.List();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("Start");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1ActionPerformed(evt);
            }
        });

        list1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                list1ActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        .add(layout.createSequentialGroup()
        .addContainerGap()
        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        .add(list1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .add(layout.createSequentialGroup()
        .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 329, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jButton1)
        .add(0, 0, Short.MAX_VALUE)))
        .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        .add(layout.createSequentialGroup()
        .addContainerGap()
        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
        .add(jButton1)
        .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(list1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 229, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(25, Short.MAX_VALUE))
    );

        pack();
    }// </editor-fold>                        

private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {                                            
    jButton1.doClick();
}                                           

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {  
        //I tried to use invokeLater, this solved the problem of the UI nonresponse issue                                       
        SwingUtilities.invokeLater(new Runnable() {
            public void run()
            {
                //Creates a path dir that my Sync constructor needs to start file   notification watcher on that directory
                Path dir = Paths.get(jTextField1.getText());
                try
                {
                    //Creates a new sync object passing it the directory and the list in my GUI
                    Sync sync = new Sync(dir, list1);
                    try
                    {
                        sync.processEvents();
                    }
                    catch (InterruptedException ex)
                    {
                        Logger.getLogger(SyncUI.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                catch (IOException ex)
                {
                    Logger.getLogger(SyncUI.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        });
}                                        

private void list1ActionPerformed(java.awt.event.ActionEvent evt) {                                      
    // TODO add your handling code here:
}                                     

public static void main(String args[]) throws IOException
{
    java.awt.EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            SyncUI s = new SyncUI();
            s.setVisible(true);               
        }
    });     
}

// Variables declaration - do not modify                     
private javax.swing.JButton jButton1;
private javax.swing.JTextField jTextField1;
private java.awt.List list1;
// End of variables declaration                   
}

Sync.java:

package sync;

import static java.nio.file.StandardWatchEventKinds.*;
import java.nio.file.attribute.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;

public class Sync
{
    private final WatchService ws;
    private final Map<WatchKey,Path> keys;
    public java.awt.List list;

    public Sync(Path dir, java.awt.List list) throws IOException, InterruptedException
    {
        this.ws = FileSystems.getDefault().newWatchService();
        this.keys = new HashMap<WatchKey,Path>();
        this.list = list;
        recSet(dir);
        //this.processEvents();
    }

    private void register(Path dir) throws IOException
    {
        WatchKey key = dir.register(ws, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
        keys.put(key, dir);
    }

    private void recSet(Path start) throws IOException
    {
        Files.walkFileTree(start, new SimpleFileVisitor<Path>()
        {     
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
            {
                if(!Files.isHidden(dir))
                {
                    register(dir);
                    System.out.println(dir);
                }
            return FileVisitResult.CONTINUE;
            }
        });
    }

    void processEvents() throws IOException, InterruptedException
    {
        System.out.println("Entered processEvents");
        SwingUtilities.invokeLater(new Runnable() {
            public void run()
            {
                System.out.println("Entered run");
                list.add("test2");
                list.repaint();
                while(true)
                { 
                    WatchKey key;           
                    try
                    {
                        key = ws.take();
                    }
                    catch (InterruptedException x)
                    {
                        return;
                    }

                    Path dir = keys.get(key);
                    if (dir == null)
                    {
                        System.err.println("WatchKey not recognized");
                        continue;
                    }

                    for (WatchEvent<?> event: key.pollEvents())
                    {
                        WatchEvent.Kind<?> kind = event.kind();
                        WatchEvent<Path> ev = (WatchEvent<Path>)event;
                        Path filename = ev.context();
                        String name = dir.resolve(filename).toString();             

                        if (kind == OVERFLOW)
                            continue;               

                        if(kind == ENTRY_CREATE)
                        {
                            System.out.print("Entry Created: ");
                            File f = new File(name);

                            if(f.isDirectory())
                                try {
                                    register(dir.resolve(filename));
                                } catch (IOException ex) {
                                    Logger.getLogger(Sync.class.getName()).log(Level.SEVERE, null, ex);
                                }

                            System.out.println(name);
                            list.add(name);     
                        }
                        else if(kind == ENTRY_DELETE)
                        {
                            System.out.print("Entry Deleted: ");
                            System.out.println(name);                          
                        }
                        else if(kind == ENTRY_MODIFY)
                        {
                            File f = new File(name);
                            if(!f.isDirectory())
                        {
                            System.out.print("Entry Modify: ");
                            System.out.println(name);
                        }
                    }

                    boolean valid = key.reset();

                    if (!valid)
                        break;
                    }
                }
            }
        });       
    }
}

解决方案

Swing is not thread safe, so, if you are tryng to update a UI in the same thread you will have the "application freeze" behavior. To solve this, you need to delegate the process of update the UI to another thread. This is made using SwingUtilities.invokeLater (Java 5 and prior) method and/or the SwingWorker class (since Java 6).

Some links:

Google search: https://www.google.com.br/search?q=swing+thread+safe

这篇关于Java的AWT线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆