2009-12-04 22 views
6

Trong ứng dụng Java GUI "nghiêm trọng", bạn sẽ có các mô hình đằng sau nhiều phần tử GUI của mình: A DocumentModel sao lưu JEditorPane, ví dụ hoặc ListModel đằng sau một JList.Có thể thay đổi mô hình bên ngoài chuỗi công nhân Swing không?

Chúng tôi luôn được yêu cầu không thực hiện thay đổi GUI từ bên ngoài chuỗi công nhân Swing và được cung cấp SwingUtilities.invoke...() để giải quyết vấn đề đó. Được rồi, tôi có thể sống với điều đó! Nó chắc chắn là cần thiết (và hoạt động tốt) khi thay đổi các thuộc tính của các thành phần GUI trực tiếp.

Lý tưởng nhất, hầu hết các thay đổi có thể nhìn thấy GUI của tôi sẽ là các mô hình, chứ không phải đối với JComponents. Nhưng bởi vì chúng có khả năng hiển thị GUI, chúng có "đếm" dưới dạng thay đổi GUI không? I E. thay đổi các sự kiện và người nghe cung cấp sự tách rời cần thiết, hoặc thay đổi mô hình cần phải được bao bọc trong invoke...() không?

Có lẽ chiếc mũ cũ để xoay ưu, nhưng tôi không thể tìm thấy bất kỳ tham chiếu nào nêu rõ cách này hay cách khác.

Trả lời

5

Thông thường, thay đổi mô hình phải được gói vào invokeLater (...). Không có tách trong mã của mô hình của hầu hết các lớp học swing trong đó tôi nhìn.

Tùy thuộc vào bạn để tạo mô hình có thể chứa các cuộc gọi kiểm tra xem các sửa đổi GUI có được thực hiện trên Chủ đề người điều phối sự kiện hay không.

+1

-1: Không phải là câu trả lời tôi muốn nghe! (Chỉ đùa thôi, +1) Cảm ơn bạn! –

+1

Liên quan đến việc gỡ rối các vấn đề về chuỗi Swing, tôi đặc biệt khuyên bạn nên liên kết này: http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html CheckThreadViolationRepaintManager đã lưu tôi rất nhiều thời gian. –

+1

Văn bản xoay có * một số * chuyển sự kiện sang EDT. Tất nhiên nó chỉ làm cho một mớ hỗn độn lớn hơn. –

2

Nếu các sự kiện được kích hoạt khỏi EDT và cập nhật các thành phần Swing sắp xảy ra sự cố.

Trong văn bản Swing, các sự kiện có thể hoặc không thể (!) Được chuyển sang EDT. Điều này làm cho thử nghiệm khó khăn. Không ngạc nhiên, API không hữu ích trong môi trường đa luồng.

Vì vậy: Dễ nhất giữ mô hình trên EDT và các chủ đề khác sẽ chuyển các tin nhắn (liên quan đến EventQueue.invokeLater). Ngoài ra, bạn có thể đặt một khóa lớn xung quanh tất cả mọi thứ, đó là khó khăn hơn (và bạn có lẽ sẽ vẫn cần phải vượt qua công cụ để EDT). Việc cố gắng đồng bộ hóa là rất khó.

+1

"sự đồng bộ hóa rất khó." : Tôi hoàn toàn đồng ý với điểm này. Tôi đã loại bỏ tất cả các từ khóa được đồng bộ hóa của mình và kiểm tra cẩn thận hơn rằng mọi sửa đổi trên GUI (và các mô hình của các phần tử của GUI) đã được thực hiện trên EDT. –

+1

Tôi sợ điều này. Nó có nghĩa là các mô hình của tôi về mặt kỹ thuật trở thành một phần của GUI và phải được coi là một phần của nó cho mục đích này. Nó không có vẻ "sạch" từ một quan điểm phân lớp/đóng gói, và (đây là phản đối lớn nhất của tôi, tất nhiên) nó hoạt động nhiều hơn! 1, cảm ơn! –

2

Có điều chắc chắn là OK.

Mặc dù đúng là bạn không nên sửa đổi các thành phần Swing bên ngoài EDT. Bạn chắc chắn có thể thay đổi các mô hình của họ bên ngoài EDT.

Nếu bạn đã kết nối các mô hình với các thành phần Swing của mình một cách chính xác, chế độ xem đang cập nhật và do đó việc lập lịch biểu EDT sẽ diễn ra gần như tự động.

Xem: http://java.sun.com/products/jfc/tsc/articles/architecture/#roots

Xem phần về mô hình Sự kiện JavaBeans.

Đây là cách các mô hình truyền đạt trạng thái đã thay đổi của chúng sang GUI theo cách an toàn EDT. Khi tạo các thành phần GUI mới, bạn nên làm theo mẫu thiết kế này.

Cũng lưu ý sự khác biệt giữa các mô hình trạng thái GUI và mô hình dữ liệu ứng dụng.

Thực hiện thay đổi đối với các kiểu máy từ EDT vẫn cần được chăm sóc. Trong thực tế, hầu hết các vấn đề Swing xảy ra khi lập trình viên đang sửa đổi một mô hình trong EDT khi họ nên sửa đổi nó từ một luồng riêng biệt.(Vấn đề GUI đông lạnh không nổi tiếng)

Ngoài ra, không có điều nào cản trở việc nhận thức đầy đủ các cạm bẫy đa luồng điển hình.

Nhưng bạn chắc chắn có thể thực hiện thay đổi đối với JTableModel từ bên ngoài EDT.

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