【问题标题】:Execute JFrame from Another JFrame从另一个 JFrame 执行 JFrame
【发布时间】:2023-03-29 11:10:01
【问题描述】:

我正在制作一个客户端服务器应用程序,其中服务器代码由 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);
        }
    }

【问题讨论】:

标签: java swing sockets jframe jtable


【解决方案1】:
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);
            }
        }
}   

【讨论】:

  • 但是如果我使用另一个线程来运行 Show() 那么用户可以按任意键开始键。次。我只需要按下一次。
  • @ChandrapalSinghJhala JButton#setEnabled
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 2018-10-02
  • 2014-10-07
  • 2013-12-17
  • 1970-01-01
相关资源
最近更新 更多