从另一个 JFrame 执行 JFrame

Execute JFrame from Another JFrame

我正在制作一个客户端服务器应用程序,其中服务器代码由 JFrame 执行 这是我的服务器代码,当我从 MyServer class 的主要方法调用 Show 方法时它正在工作,但是当我从 Jframe 的关键事件调用它时它没有显示另一个 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);
        }
    }    

另一个JFrame通过SocketThread调用的代码class.

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