Câu hỏi của tôi có liên quan đến SwingUtilities.invokeLater
. Khi nào tôi nên sử dụng? Tôi có phải sử dụng mỗi khi tôi cần cập nhật các thành phần GUI không? Nó chính xác làm gì? Có một thay thế cho nó vì nó không âm thanh trực quan và thêm mã dường như không cần thiết?SwingUtilities.invokeLater
Trả lời
Tôi có phải sử dụng mỗi lần tôi cần cập nhật các thành phần GUI không?
Không, không phải nếu bạn đã trên thread sự kiện văn (EDT) mà luôn luôn là trường hợp khi trả lời người dùng khởi tạo các sự kiện như nhấp chuột và lựa chọn. (Các phương pháp actionPerformed
vv, luôn gọi bằng EDT.)
Nếu bạn không trên tuy nhiên EDT và muốn làm cập nhật giao diện (nếu bạn muốn cập nhật giao diện từ một số timer chủ đề, hoặc từ một số chuỗi mạng v.v.), bạn sẽ phải lịch bản cập nhật sẽ được thực hiện bởi EDT. Đó là những gì phương pháp này là dành cho.
Swing về cơ bản là chuỗi không an toàn. Tức là, tất cả sự tương tác với API đó cần được thực hiện trên một chuỗi đơn (EDT). Nếu bạn cần cập nhật GUI từ một luồng khác (chuỗi hẹn giờ, chuỗi nối mạng, ...), bạn cần sử dụng các phương thức như là bạn đã đề cập (SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, ...).
@ Jens: Điều đó có nghĩa là tôi có thể làm mà không có nó nếu tôi ở trên cùng một luồng (Swing) hoặc làm những việc trong thời gian chạy. – FadelMS
Vâng, "hoặc làm những việc trong thời gian chạy" không phải là rất chính xác. Nếu bạn làm mọi thứ trong thời gian chạy, trong, ví dụ, một chuỗi thời gian, sau đó không, bạn không thể làm mà không có các loại phương pháp này. – aioobe
Cảm ơn aioobe, hiểu rồi. – FadelMS
Mỗi ứng dụng Swing có ít nhất 2 chủ đề:
- Các chủ đề chính mà thực hiện việc áp dụng
- Các EDT (tổ chức sự kiện dispatching thread) là một chủ đề mà cập nhật giao diện người dùng (do đó giao diện người dùng sẽ không đóng băng).
Nếu bạn muốn cập nhật giao diện người dùng, bạn nên thực thi mã trong EDT. Các phương thức như SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, EventQueue.invokeLater, EventQueue.invokeAndWait cho phép bạn thực thi mã bằng EDT.
đơn giản và dễ hiểu, cảm ơn bạn – Yahya
Hầu hết các sự kiện do người dùng khởi tạo (lần nhấp, bàn phím) sẽ có trên EDT nên bạn sẽ không phải sử dụng SwingUtilities cho điều đó. Điều đó bao gồm rất nhiều trường hợp, ngoại trừ chủ đề chính và chuỗi công việc của bạn cập nhật EDT.
không nhất, _all_ – kleopatra
Vâng, người dùng có thể cập nhật tệp đang được theo dõi bởi một luồng cập nhật GUI. –
hmm ...không được tính là sự kiện bắt đầu do người dùng khởi tạo: người dùng cập nhật tệp (bên trong swing, trên EDT) và lưu nó (bằng cách nhấp vào nút, trên EDT), kích hoạt hệ điều hành tập tin cập nhật sự kiện (bên ngoài swing, off EDT) thông báo, thông báo đó đạt đến màn hình (tắt EDT) có trách nhiệm cập nhật GUI trên EDT – kleopatra
Câu hỏi của tôi lần này có liên quan đến
SwingUtilities.invokeLater
: Khi nào tôi nên sử dụng?
Điều quan trọng cần hiểu là Java có một chuỗi riêng biệt (EDT) xử lý các sự kiện liên quan đến Swing.
Bạn nên sử dụng invokeLater()
để hiển thị chính JFrame
của ứng dụng dành cho máy tính để bàn (ví dụ), thay vì cố gắng thực hiện trong luồng hiện tại. Nó cũng sẽ tạo ra bối cảnh cho việc đóng ứng dụng duyên dáng sau này.
Đó là về nó cho hầu hết các ứng dụng.
Tôi có phải sử dụng mỗi khi tôi cần cập nhật các thành phần GUI không? Nó chính xác làm gì?
No.Nếu bạn sửa đổi một thành phần GUI, nó sẽ kích hoạt một sự kiện được đăng ký để gửi đi sau đó bởi Swing. Nếu có một người nghe cho sự kiện này, chủ đề EDT sẽ gọi nó ở đâu đó trên đường. Bạn không cần sử dụng invokeLater()
, chỉ cần đặt người nghe của bạn trên các thành phần chính xác.
Hãy nhớ rằng chủ đề này là cùng một chuỗi khung vẽ vv ... trên màn hình của bạn. Do đó, người nghe không nên thực hiện các tác vụ phức tạp/dài/CPU, nếu không màn hình của bạn sẽ bị đóng băng.
Có cách nào khác vì nó không nghe trực quan và thêm mã dường như không cần thiết?
Bạn không cần phải viết nhiều mã hơn hiển thị ứng dụng của mình với invokeLater()
+ trình nghe bạn quan tâm đến thành phần. Phần còn lại được xử lý bởi Swing.
Swing is single threaded and all changes to the GUI must be done on EDT
sử dụng cơ bản cho invokeLater()
phương pháp chính nên luôn luôn được bọc trong
invokeLater()
chậm (nhưng không đồng bộ) hành động/sự kiện vào cuối
EventQueue
,Nếu EDT không tồn tại thì bạn phải tạo một EDT mới bằng cách sử dụng
invokeLater()
. Bạn có thể thử nghiệm nó vớiif (SwingUtilities.isEventDispatchThread()) {...
Có tồn tại
invokeAndWait()
, nhưng cho đến hôm nay tôi (chỉ quan điểm của tôi) không thể tìm thấy một lý do cho việc sử dụnginvokeAndWait()
thay vìinvokeLater()
, ngoại trừ những thay đổi khó khăn vào GUI (JTree & JTable), nhưng chỉ với Substance L&F (tuyệt vời để thử nghiệm tính nhất quán của các sự kiện trên EDT)Basic thứ: Concurrency in Swing
Tất cả các đầu ra từ các nhiệm vụ nền phải được bọc trong
invokeLater()
- 1. EventQueue.invokeLater vrs SwingUtilities.invokeLater
- 2. SwingUtilities.invokeLater làm gì?
- 3. Java: gỡ lỗi bằng SwingUtilities.invokeLater()
- 4. Phản hồi JavaFx với SwingUtilities.invokeLater
- 5. SwingUtilities.invokeLater() tại sao cần thiết?
- 6. Sự khác biệt giữa SwingWorker và SwingUtilities.invokeLater
- 7. Chức năng tương tự SwingUtilities.invokeLater trong android?
- 8. Java - Sự khác nhau giữa SwingWorker và SwingUtilities.invokeLater()
- 9. SwingUtilities.invokeLater trong Chủ đề Sự kiện gửi AWT
- 10. Java $ đăng nhập là gì? Hãy có một cái nhìn trong mã Java dưới đây
- 11. Thực hành tốt nhất để bắt đầu ứng dụng xoay
- 12. Java Luồng thực thi - phương pháp ghi đè được thực thi đầu tiên so với hàm tạo
- 13. setSize() không làm việc cho JFrame
- 14. Vô hiệu hóa JButton, trong khi công việc nền, để tránh nhiều nhấp chuột
- 15. JScrollPane không xuất hiện khi sử dụng nó trên JPanel
- 16. Sơn JLabel chấm
- 17. Mẫu để chặn người dùng Java Swing trong chuỗi công nhân
- 18. Swing - MaskFormatter - Nhập số từ bên phải của trường văn bản
- 19. Tại sao ngoại lệ Java của tôi không in dấu vết ngăn xếp khi được ném vào trong một SwingWorker?
- 20. Java 5 SwingWorker thay thế
- 21. Làm mới GUI bằng một chuỗi khác trong java (swing)
- 22. Làm thế nào để thực hiện công việc nền trong JComponent tùy chỉnh?
- 23. Tại sao không bao giờ thay đổi notifier trong việc tiếp nhận một sự kiện thay đổi
- 24. ràng buộc chìa khóa java swing - thiếu hành động cho khóa được phát hành
- 25. Java's Swing Threading
- 26. Làm thế nào để chọn tất cả văn bản trong ô JTable khi chỉnh sửa nhưng không phải khi gõ?
- 27. Nhận chiều cao của văn bản nhiều dòng với chiều rộng cố định để thay đổi kích thước hộp thoại một cách chính xác
- 28. Bảo quản bố cục bàn phím trong ứng dụng xoay?
- 29. Tại sao Windows LookAndFeel tạo phông chữ quá nhỏ?
- 30. Không thể thay đổi kích thước của khối trong BorderLayout
Nó tương đương với 'Control.BeginInvoke'. – SLaks
@SLaks Điều đó có nghĩa là nếu tôi có một chủ đề, tôi không phải sử dụng nó? – FadelMS
@FadelMS, Vì khung công tác Swing tạo ra một chuỗi của riêng nó (EDT), bạn sẽ luôn có chuỗi đó. (* Bạn * không có một "thông báo kiểm tra" -loop mà xử lý người dùng nhấp chuột vv, phải không? Vậy làm thế nào để các phương pháp 'actionPerformed' khác nhau được gọi là? Bởi EDT!) Vì vậy, khi bạn nói rằng bạn có * một * thread, tôi sẽ phải intepret rằng như bạn * chỉ * có EDT (tức là, bạn đã ném một GUI và rơi ra khỏi cạnh của phương pháp chính). Trong trường hợp đó, NO, bạn * sẽ không * cần sử dụng 'invokeLater'. Tuy nhiên, bạn sẽ không thể thực hiện bất kỳ quá trình xử lý nền nào. Nếu bạn làm như vậy, bạn sẽ khóa hoàn toàn GUI ... – aioobe