2013-08-09 29 views
6

Lý tưởng nhất, câu trả lời sẽ là nền tảng độc lập, nhưng nền tảng cụ thể, đặc biệt là Oracle JVM, cũng hữu ích. Dự án mà tôi đang làm vẫn đang chạy JVM phiên bản 6.Làm cách nào để báo cáo độ dài hàng đợi sự kiện AWT/Swing theo lập trình?

Nhu cầu cụ thể phải làm với một GUI thỉnh thoảng "đóng băng". Tôi biết rõ về việc thực hiện công việc GUI trên EDT. Chương trình hoạt động tốt trên Windows, nhưng sau khi chuyển sang Linux, các vấn đề GUI "lạ" này bắt đầu xảy ra. Trên thực tế, vấn đề này đã xảy ra trên hai ứng dụng, cả sau khi di chuyển Windows sang Linux. JVisualVM hiển thị hơn 10 triệu đối tượng java.awt.EventQueueItem. Sự nghi ngờ là hàng đợi AWT đang phát triển nhanh hơn so với nó đang được phục vụ trên Linux, do đó, ý tưởng là đặt một chỉ số độ dài hàng đợi AWT trên ứng dụng và xem những gì nó hiển thị khi hàng đợi tăng/co lại.

Một chút Googling tìm thấy this, nhưng nó thực hiện quét tuyến tính của hàng đợi. Có lẽ có một số cách tốt hơn?

+1

Để khám phá, bạn có thể chặn các sự kiện, như được hiển thị [ở đây] (http://stackoverflow.com/q/3158254/230513). – trashgod

+0

Mười _million_! 'setCoalesce (sai)'? – trashgod

+0

Không. Đã nghĩ về điều đó và quét cho nó. Không tắt logic kết hợp. –

Trả lời

3

Chủ đề thú vị. Tôi đã điều tra mã EventQueue một chút và trong khi tôi chưa giải quyết được vấn đề của bạn, tôi có thể có một số gợi ý hữu ích:

  1. Việc triển khai EventQueue của Oracle không giữ một biến kích thước, vì vậy trừ khi bạn tiếp quản hoàn toàn kiểm soát EventQueue (xem 3), không có cách nào bạn sẽ làm tốt hơn so với quét tuyến tính của hàng đợi khi sử dụng JRE của Oracle.
  2. Bạn có thể viết EventQueue của riêng bạn (có thể sao chép quá trình triển khai của Oracle cùng với một số chỉnh sửa ** sẽ dễ nhất) và sử dụng EventQueue.push(EventQueue) để cài đặt triển khai của riêng bạn. Tất cả các sự kiện trong hàng đợi sẽ được chuyển đến hàng đợi của bạn, vì vậy bạn có thể đếm chúng khi chúng được đăng lên hàng đợi của bạn. Thật không may, đây vẫn là một lần quét tuyến tính, nhưng ít nhất giờ nó là nền tảng độc lập. Ngoài ra, bạn có thể cài đặt EventQueue của riêng bạn (xem 2) càng sớm càng tốt sau khi hàng đợi sự kiện ban đầu được tạo (thực hiện điều này trong một khối mã tĩnh ở đầu lớp chứa phương thức chính của bạn). Sau đó, việc triển khai của bạn có thể đếm tất cả các sự kiện khi chúng được đăng và bạn không phải quét hàng đợi khi muốn biết kích thước. Bạn sẽ chỉ phải hy vọng không ai khác đẩy EventQueue của họ lên trên của bạn;)

** Một số điều chỉnh: Tôi chưa thử, nhưng tôi sẽ loại bỏ tất cả mã số công cộng/được bảo vệ (mọi người tham khảo các phương thức/biến đó sử dụng java.awt.EventQueue, và bạn cũng có thể), thêm biến kích thước và cập nhật biến này theo bốn phương pháp sau: postEvent(AWTEvent, int), getNextEventPrivate(), getNextEvent(int)removeSourceEvent(Object, boolean).

Một vấn đề lớn với sửa đổi này là EventQueue thực hiện một số cuộc gọi đến phương thức AWT với khả năng hiển thị mặc định (ví dụ: Toolkit.getEventQueue()Component.getAccessControlContext()). . Bạn sẽ phải tìm cách giải quyết riêng cho từng trường hợp.

+0

"copy-paste" là gì ??, anh ta có thể mở rộng 'EventQueu' và sau đó' push' thực hiện riêng của mình .. – nachokk

+0

Vấn đề là bạn cần phải sửa đổi phương thức riêng, có nghĩa là thực hiện lại chúng. Vì tất cả các mã từ java.awt.EventQueue đều gọi các phương thức riêng tư của riêng chúng, bạn cũng cần phải triển khai lại các phương thức đó. Chuỗi triển khai lại này chỉ dừng lại khi bạn tiếp cận các phương pháp công cộng hoặc được bảo vệ. Hơn nữa, nếu chuỗi chứa các phương thức có khả năng hiển thị mặc định được gọi từ các nơi khác trong java.awt, nó sẽ trở thành không thể chuyển hướng tất cả các invocations đến các phương pháp riêng để triển khai của riêng bạn. Đối với tất cả các mục đích thực tế, tôi nghĩ tốt hơn là sao chép-dán. –

Các vấn đề liên quan