2012-01-13 40 views
10

Tôi kết hợp Swing và Java3D với nhau. Thao tác của các thành phần swing nên được thực hiện bằng cách sử dụng Event Dispatcher Thread, trong khi các thao tác của các thành phần Java3D nên được thực hiện trong BehaviourSchedulerThread.Kết hợp Java Swing và Java3D: các vấn đề về hiệu năng với đồng thời

Java3D hiển thị cảnh và sau đó thực thi tất cả các hành vi liên quan đến cảnh.

Tôi đã bật MouseListener trên Canvas3D. Sự kiện được đăng vào hàng đợi Sự kiện AWT. Sau đó, tôi muốn sửa đổi môi trường Java3D dựa trên các sự kiện này, vì vậy tôi sử dụng một Hành vi đặc biệt, nơi tôi có thể đăng Runnable. Điều này đảm bảo rằng các Runnable được thực thi trong chu kỳ Hành vi của Java3D (và không sửa đổi anyting trong suốt quá trình Render).

Giả sử một số thao tác trong Hành vi muốn sửa đổi mô hình Swing. Sau đó tôi phải đăng một Runnable mới cho EDT.

Đây có phải là cách đúng để thực hiện không?

Sử dụng kỹ thuật này, tôi gặp phải rất nhiều sự cố trên trình nghe chuột. Tôi cập nhật một điểm trong mô hình Java3D của mình trong hành vi, và tôi cập nhật GUI GUI cùng một lúc.

Cập nhật: vấn đề này có thể được xác định rõ ràng hơn như sau:

Tôi có một JButton "quay cube" trong đó có một ActionListener. Khi ActionListener được kích hoạt, nó sẽ đẩy AWTEvent vào một hành vi Java3D. Một khi hành vi cháy, nó sửa đổi đồ thị Scene và sau đó sửa đổi JButton actionListener và văn bản để trở thành "Stop spinning".

  1. Nhấp vào nút JButton hai lần.
  2. AWTEvent đầu tiên được gửi đến SpinActionListener. Khối lập phương bắt đầu quay và JButton actionListener được sửa đổi thành StopSpinningActionListener.
  3. AWTEvent thứ hai được gửi đến StopSpinningActionListener. Khối lập phương dừng quay và JButton actionListener được sửa đổi thành SpinActionListener.

Điều gì thực sự xảy ra như sau:

  1. Nhấn vào một JButton hai lần. Cả hai số AWTEvent đều được gửi đến SpinActionListener. Điều này tạo ra một Runnable để thực thi bên trong Hành vi J3D.
  2. AWTEvent đầu tiên bắt đầu hẹn giờ để quay khối lập phương. Sau đó nó gửi một Runnable đến EDT để sửa đổi nút.
  3. AWTEvent thứ hai bắt đầu hẹn giờ để quay khối lập phương. Khối lập phương giờ sẽ quay nhanh gấp hai lần. Sau đó nó gửi một Runnable đến EDT để sửa đổi nút.

Rõ ràng, tôi không nên phụ thuộc vào việc AWTEvent được xử lý tuần tự. Tôi không thể chờ đợi trong EDT cho hành vi cháy, bởi vì bất kỳ SwingUtilities.invokeAndWait() sau đó sẽ gây ra một bế tắc.

+1

như tôi đã biết và đã thử cho 3D_APIs dựa trên OpenGL (bản sao của nó) được yêu cầu sử dụng Thùng chứa AWT, cẩn thận với http://java.sun.com/products/jfc/tsc/articles/mixing/ được đặt trong một vùng chứa (có nghĩa là JPanel không JFrame, JDialog hoặc JWindow), – mKorbel

Trả lời

4

Loại WakeupCriterion nào được sử dụng để đánh thức đối tượng Hành vi đặc biệt của bạn?

mã nguồn Java 3D bao gồm các lớp tiện ích

com.sun.j3d.utils.behaviors.mouse.MouseBehavior/MouseRotate 

mà nghe Canvas3D của AWTEvents. Một trong hai lựa chọn thay thế có thể được chọn:

  1. MouseListener với WakeupOnBehaviorPost hoặc
  2. WakeupOnAWTEvent.

mẫu mã này có thể hữu ích.

Bắt đầu cập nhật thành phần Swing từ trong phương thức Behavior.processStimulus qua SwingUtilities.invokeLater sẽ không gây ra bất kỳ sự cố nào.

+0

Cảm ơn bạn đã gợi ý trên WakeupOnAWTEvent. Nhìn vào mã nguồn, tôi thực hiện điều tương tự riêng biệt; luôn luôn tốt đẹp để không bị trùng lặp chức năng API. – parasietje

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