2012-01-13 9 views
10

Sto combinando insieme Swing e Java3D. Le manipolazioni dei componenti swing devono essere eseguite utilizzando il thread Event Dispatcher, mentre le manipolazioni dei componenti Java3D devono essere eseguite in BehaviourSchedulerThread.Combina Java Swing e Java3D: problemi di prestazioni con la concorrenza

Java3D esegue il rendering della scena e quindi esegue tutto il comportamento associato alla scena.

Ho un MouseListener abilitato su Canvas3D. Gli eventi vengono registrati nella coda eventi AWT. Quindi voglio modificare l'ambiente Java3D in base a questi eventi, quindi utilizzo un comportamento speciale in cui posso pubblicare i Runnable. Ciò assicura che i Runnable vengano eseguiti durante il ciclo di comportamento di Java3D (e non modificano alcunché durante il ciclo di rendering).

Supponiamo che alcune operazioni nel comportamento vogliano modificare il modello Swing. Devo quindi pubblicare un nuovo Runnable per l'EDT.

È questo il modo corretto per farlo?

Utilizzando questa tecnica, ho riscontrato molti problemi su un ascoltatore di mouse. Aggiorno un punto nel mio modello Java3D nel comportamento e aggiorno la GUI di swing contemporaneamente.

Aggiornamento: il problema può essere più chiaramente definita come segue:

Ho un JButton "spin cubo" che ha un ActionListener. Una volta che l'ActionListener è stato attivato, spinge AWTEvent in un comportamento Java3D. Una volta che il comportamento si attiva, modifica il grafico Scene e quindi modifica l'actionListener di JButton e il testo diventa "Interrompi rotazione".

  1. Fare clic due volte sul pulsante J.
  2. Il primo AWTEvent viene inviato a SpinActionListener. Il cubo inizia a ruotare e l'actionListener JButton viene modificato in StopSpinningActionListener.
  3. Il secondo AWTEvent viene inviato a StopSpinningActionListener. Il cubo smette di ruotare e JButton actionListener viene modificato in SpinActionListener.

Cosa succede in realtà è la seguente:

  1. Fare clic su un JButton due volte. Entrambi i modelli AWTEvent s vengono spediti allo SpinActionListener. Questo crea un Runnable da eseguire all'interno del comportamento J3D.
  2. Il primo AWTEvent avvia un timer per far girare il cubo. Quindi invia un Runnable all'EDT per modificare il pulsante.
  3. Il secondo AWTEvent avvia un timer per far girare il cubo. Il cubo ora girerà due volte più velocemente. Quindi invia un Runnable all'EDT per modificare il pulsante.

Ovviamente, non dovrei dipendere dall'elaborazione sequenziale di AWTEvent. Non vedo l'ora di EDT per il comportamento, perché qualsiasi SwingUtilities.invokeAndWait() causerà quindi un deadlock.

+1

come noto e provato per 3D_API basato su OpenGL (i suoi cloni) è richiesto l'utilizzo di AWT Container, attentamente con http://java.sun.com/products/jfc/tsc/articles/mixing/ inserito in un contenitore (significato JPanel non JFrame, JDialog o JWindow), – mKorbel

risposta

4

Quale WakeupCriterion viene utilizzato per riattivare l'oggetto Comportamento speciale?

codice sorgente di Java 3D include le classi di utilità

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

che ascolta la Canvas3D di AWTEvents. Una delle due alternative possono essere scelti:

  1. MouseListener con WakeupOnBehaviorPost o
  2. WakeupOnAWTEvent.

Questo esempio di codice potrebbe essere utile.

L'avvio di un aggiornamento del componente Swing dall'interno del metodo Behavior.processStimulus tramite SwingUtilities.invokeLater non dovrebbe causare alcun problema.

+0

Grazie per il suggerimento su WakeupOnAWTEvent. Guardando il codice sorgente, ho implementato la stessa cosa separatamente; sempre bello non duplicare la funzionalità API. – parasietje