从另一个JFrame执行JFrame

时间:2018-03-01 03:53:18

标签: java swing sockets jframe jtable

我正在制作一个客户端服务器应用程序,其中服务器代码由JFrame执行 这是我的服务器代码,当我从MyServer类的main方法调用Show方法然后它正在工作,但是当我从Jframe的Key Event调用它时,它没有显示另一个Jframe。请帮忙。

public class MyServer 
    public void Show() throws IOException {
        ServerSocket ss = new ServerSocket(6666);
        new IPScanning().dispose();
        int count = 0;
        while (true) {
            Socket s = null;
            try {
                s = ss.accept();  
                SocketThread socketThread = new SocketThread(s, count);
                socketThread.start();
            } catch (Exception e) {
                ss.close();
                s.close();
                System.out.println(e);
            } finally {
                count++;
            }
        }
    }

    class SocketThread extends Thread {
        public void run() {
            try {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        ShowTable.INSTANCE.showdata(count, host, ip, username, os_name, os_arch, pro_detail, Mac_add, disk_size, max_memory);
                    }
                });
            } catch (Exception e) {
                System.out.println("Server Problem");
                System.out.println(e);
            }
        }
    }
}`

这是我的重要活动

  private void jStartActionPerformed(java.awt.event.ActionEvent evt) {                                       
        MyServer ms=new MyServer();
        try {
            ms.Show();
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }    

通过SocketThread类调用的另一个JFrame的代码。

 public enum ShowTable{
        INSTANCE;
        private JFrame f = new JFrame();
        private JTable jt = new JTable(new DefaultTableModel());
        private DefaultTableModel model = (DefaultTableModel) jt.getModel();
        private ShowTable() {
            jt.setBounds(30, 40, 200, 300);
            jt.setFocusable(false);
            jt.setRowSelectionAllowed(false);
            JScrollPane sp = new JScrollPane(jt);
            f.add(sp);
            f.setSize(1300, 600);
        }
        public void showdata(int count,String host,String ip,String username,String os_name,String os_arch,String pro_detail,String Mac_add,float disk_size,float max_memory){        
           f.setVisible(true);
        }
    }

1 个答案:

答案 0 :(得分:3)

private void jStartActionPerformed(java.awt.event.ActionEvent evt) {                                       
    MyServer ms=new MyServer();
    try {
        ms.Show();
    } catch (IOException ex) {
        System.out.println(ex);
    }
}       

建议调用此方法以响应UI中的某些操作(如按下按钮),这意味着事件已从事件调度线程的上下文中调度。

这意味着在事件调度线程的上下文中调用了MyServer#show

所以如果我们看看......

public void Show() throws IOException {
    ServerSocket ss = new ServerSocket(6666);
    new IPScanning().dispose();
    int count = 0;
    while (true) {
        Socket s = null;
        try {
            s = ss.accept();  
            SocketThread socketThread = new SocketThread(s, count);
            socketThread.start();
        } catch (Exception e) {
            ss.close();
            s.close();
            System.out.println(e);
        } finally {
            count++;
        }
    }
}

我们可以看到Show正在创建一个无限循环并在事件调度线程的上下文中调用阻塞方法 - 阻止它并阻止UI再次更新。

Swing既是单线程的,也不是线程安全的。这意味着:

  • 您不应该在事件调度线程的上下文中执行任何长时间运行或阻塞操作
  • 您永远不应该从事件调度线程的上下文之外更新UI的状态(或UI所依赖的任何内容)

您需要仔细阅读Concurrency in Swing,以便更好地了解该问题。

您还应密切关注Worker Threads and SwingWorker,因为它们将有助于解决您的问题。

但是,一个过于简单的解决方案可能只是使用另一个Thread来运行MyServer#Show方法...

private void jStartActionPerformed(java.awt.event.ActionEvent evt) {                                       
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                MyServer ms=new MyServer();
                ms.Show();
            } catch (IOException ex) {
                System.out.println(ex);
            }
        }
}