Simple Slide?

Status
Nicht offen für weitere Antworten.

Flashray

Mitglied
Hallo,

beschäftige mich seit kurzem mit Java 3D. Da wollte ich mal mein erstes kleines Java 3D Beispiel Programm schreiben, komme aber irgendwie nicht weiter.

Die Idee ist, in einem SimpleUniverse per Thread die primitiven Formen nacheinander anzuzeigen lassen. So das immer eine Form verschwindet und an deren Stelle die nächste angezeigt wird.

In Swing würde ich einfach mit remove() eine Komponente entfernen und die andere mit add() hinzufügen, anschließend mit updateUI() die Oberfläche aktualisieren.

Zuerst habe ich versucht nur das Kind auszutauschen, was nicht funktioniert hat. Mein zweiter Versuch war die Szene auszutauschen, dies hat leider auch nicht geklappt.

Optimal wäre es natürlich wenn nur das Kind ausgetauscht wird, und nicht die ganze Szene oder gar das ganze Universe.

Hätte jemand eine Idee was an dem unteren Code falsch ist? Es entsteht zwar kein Fehler, aber der Canvas ist vollständig schwarz, d.h. die Objekte sind nicht zu sehen. Auch würde mich interessieren, wie man das umsetzt, das einfach nur das jeweilige Kind gewechselt und die Szene aktualisiert wird.


Vg Flashray

Code:
package basic;

import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Iterator;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Node;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.vecmath.Color3f;

import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Text2D;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class GeometrySlide extends JPanel {

	private ArrayList<Node> geometries = new ArrayList<Node>();

	private BranchGroup scene;

	private SimpleUniverse simpleU;

	public GeometrySlide() {
		this.setLayout(new BorderLayout());

		Canvas3D canvas3D = new Canvas3D(SimpleUniverse
				.getPreferredConfiguration());

		this.add(canvas3D);

		simpleU = new SimpleUniverse(canvas3D);

		simpleU.getViewingPlatform().setNominalViewingTransform();

		scene = new BranchGroup();

		simpleU.addBranchGraph(scene);

		geometries.add(new Box());
		geometries.add(new ColorCube());
		geometries.add(new Cone());
		geometries.add(new Cylinder());
		geometries.add(new Sphere());
		geometries.add(new Text2D("Text2D", new Color3f(0f, 1f, 1f), "Arial",
				20, 4));

		new Thread() {
			public void run() {
				while (true) {
					for (Iterator<Node> iter = geometries.iterator(); iter
							.hasNext();) {
						scene = new BranchGroup();

						Node node = iter.next();
						node = node.cloneNode(true);

						System.out.println(node);

						scene.addChild(node);

						scene.compile();

						GeometrySlide.this.updateUI();

						try {
							Thread.sleep(3000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}.start();
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Geometry Slide");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new GeometrySlide());
		frame.setSize(320, 480);
		frame.setVisible(true);
	}
}
 

kaie

Bekanntes Mitglied
Hier ein stichwortartiger Lösungsvorschlag, sollte so (oder so ähnlich) funktionieren:

1. nicht jedesmal eine neue Szene-BranchGroup erzeugen, die alte kann weiterverwendet werden
2. nur einmal compile außerhalb der run-Methode aufrufen
3. der Szene die Fähigkeit zum Hinzufügen von Kindknoten geben:
Code:
scene.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
4. den Kindknoten erlauben, sich von der Szene zu lösen
Code:
node.setCapability(BranchGroup.ALLOW_DETACH);
5. alten Knoten entfernen
Code:
node.detach();
6. neuen Knoten hinzufügen
Code:
scene.addChild(node);
 

Flashray

Mitglied
Hallo Verjigorm & kaie,

habe versucht beide Tips und Hinweise zu verwerten. Klappt leider noch nicht so ganz. Die Fehlermeldung kann ich mir nicht erklären.


Vg Flashray


(Hinweis: Die Zeilennummern der Fehlermeldung sind hier (IDE=Forum) identisch.)

Code:
package basic;

import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Iterator;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Node;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.vecmath.Color3f;

import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Text2D;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class GeometrySlide extends JPanel {

	private ArrayList<Node> geometries = new ArrayList<Node>();

	private BranchGroup scene;

	private BranchGroup exchange;

	private SimpleUniverse simpleU;

	public GeometrySlide() {
		this.setLayout(new BorderLayout());

		Canvas3D canvas3D = new Canvas3D(SimpleUniverse
				.getPreferredConfiguration());

		this.add(canvas3D);

		simpleU = new SimpleUniverse(canvas3D);

		simpleU.getViewingPlatform().setNominalViewingTransform();

		scene = new BranchGroup();
		scene.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
		scene.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);

		exchange = new BranchGroup();
		exchange.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
		exchange.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
		exchange.setCapability(BranchGroup.ALLOW_DETACH);

		scene.addChild(exchange);

		simpleU.addBranchGraph(scene);

		geometries.add(new Box());
		geometries.add(new ColorCube());
		geometries.add(new Cone());
		geometries.add(new Cylinder());
		geometries.add(new Sphere());
		geometries.add(new Text2D("Text2D", new Color3f(0f, 1f, 1f), "Arial",
				20, 4));

		for (Node node : geometries) {
			node.setCapability(BranchGroup.ALLOW_DETACH);
		}

		exchange.addChild(geometries.get(5));

		scene.compile();

		new Thread() {
			public void run() {
				while (true) {
					for (Iterator<Node> iter = geometries.iterator(); iter
							.hasNext();) {

						Node node = iter.next();
						geometries.get(getLastNumber(geometries.indexOf(node)));

						System.out.println(node);

						exchange.detach();
						exchange.addChild(node);

						GeometrySlide.this.updateUI();

						try {
							Thread.sleep(3000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}.start();
	}

	public int getLastNumber(int i) {
		return i > 0 ? i - 1 : 5;
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Geometry Slide");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new GeometrySlide());
		frame.setSize(320, 480);
		frame.setVisible(true);
	}
}

Code:
Java 3D WARNING : reported GLX version = 1.2
    GLX version 1.3 or higher is required
    The reported version number may be incorrect.  There is a known
    ATI driver bug in glXQueryVersion that incorrectly reports the GLX
    version as 1.2 when it really is 1.3, so Java 3D will attempt to
    run anyway.
Exception in thread "main" javax.media.j3d.RestrictedAccessException: Group: only a BranchGroup node may be added
	at javax.media.j3d.Group.addChild(Group.java:265)
	at basic.GeometrySlide.<init>(GeometrySlide.java:69)
	at basic.GeometrySlide.main(GeometrySlide.java:107)
 

kaie

Bekanntes Mitglied
Probier's mal hiermit:

Code:
geometries.add(new Shape3D(new Box())); 
geometries.add(new Shape3D(new ColorCube())); 
geometries.add(new Shape3D(new Cone())); 
geometries.add(new Shape3D(new Cylinder())); 
geometries.add(new Shape3D(new Sphere())); 
geometries.add(new Shape3D(new Text2D("Text2D", new Color3f(0f, 1f, 1f), "Arial", 20, 4)));
 

Flashray

Mitglied
Hallo kaie,

Shape3D nimmt keinen dieser per Konstruktor auf, der Kompiler meldet für alle den Fehler:
The constructor Shape3D(Box) is undefined.
...


Vg Flashray
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben