It seems to me Java3D has a problem redrawing the scene sometimes when the Frame/JPanel/Canvas3D has been resized. I have a problem in my application using Java3D/JUNG3D where if the Frame/JPanel/Canvas3D's horizontal size is of certain size, the entire scene disappears. I was trying to simply the problem then found that a similar problem occurs in the following sample code: http://www.java3d.org/samples.html (The second to last example, "Text 3D Example") I will paste at the bottom for convenience.
Steps:
Install Java3D
Build this example using the 3 Java3D jars.
Run
Stretch the frame horizontally to 500 pixels or so then everything disappears. Shrink it back then it's there again. While things have disappeared, stretch vertically and things appear again.
It certainly seems to have something to do with the Frame/JPanel/Canvas3D aspect ratio and that of the content that it displays. My own problem is slightly different I'm guessing because I'm displaying scene of different aspect ratio and the underlying problem is the same. Can anyone tell me how I might be able to get around this bug/feature so that the scene never disappears when the window is resized?
Here are what I've tried so far with no success:
Catching the JPanel resize event then forcing the Canvas3D to redraw
Playing with double buffering settings
Many other things I can't recall right now - just came back from a vacation :)
Code :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
public class Titles {
public static void main(String[] args) {
Titles t = new Titles();
t.setUp();
}
public void setUp() {
JFrame jf = new JFrame("Welcome");
// kill the window on close
jf.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent winEvent) {
System.exit(0);
}
});
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, 1, 2, 2));
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
Canvas3D canvas3D = new Canvas3D(config);
canvas3D.setSize(360, 160);
SimpleUniverse universe = new SimpleUniverse(canvas3D);
BranchGroup group = new BranchGroup();
addObjects(group);
addLights(group);
universe.getViewingPlatform().setNominalViewingTransform();
universe.addBranchGraph(group);
panel.add(canvas3D);
jf.getContentPane().add(panel, BorderLayout.CENTER);
jf.pack();
jf.setVisible(true);
}
public void addLights(BranchGroup group) {
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
1000.0);
Color3f light1Color = new Color3f(1.0f, 1.0f, 1.0f);
Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light1 = new DirectionalLight(light1Color,
light1Direction);
light1.setInfluencingBounds(bounds);
group.addChild(light1);
// Set up the ambient light
Color3f ambientColor = new Color3f(.1f, .1f, .1f);
AmbientLight ambientLightNode = new AmbientLight(ambientColor);
ambientLightNode.setInfluencingBounds(bounds);
group.addChild(ambientLightNode);
}
private void addObjects(BranchGroup group) {
Font3D f3d = new Font3D(new Font("TestFont", Font.PLAIN, 2),
new FontExtrusion());
Text3D text = new Text3D(f3d, new String("Java3D.org"), new Point3f(-3.5f,
-.5f, -4.5f));
text.setString("Java3D.org");
Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
Color3f blue = new Color3f(.2f, 0.2f, 0.6f);
Appearance a = new Appearance();
Material m = new Material(blue, blue, blue, white, 80.0f);
m.setLightingEnable(true);
a.setMaterial(m);
Shape3D sh = new Shape3D();
sh.setGeometry(text);
sh.setAppearance(a);
TransformGroup tg = new TransformGroup();
Transform3D t3d = new Transform3D();
Transform3D tDown = new Transform3D();
Transform3D rot = new Transform3D();
Vector3f v3f = new Vector3f(-1.6f, -1.35f, -6.5f);
t3d.setTranslation(v3f);
rot.rotX(Math.PI / 5);
t3d.mul(rot);
v3f = new Vector3f(0, -1.4f, 0f);
tDown.setTranslation(v3f);
t3d.mul(tDown);
tg.setTransform(t3d);
tg.addChild(sh);
group.addChild(tg);
}
}
Try setting up a Buffer,Tutorial here. http://www.youtube.com/watch?v=vzfnUSLKUDs&list=ECA331A6709F40B79D
It's been 5 years but try this solution.
I tried it and it worked with lookAt() function.
Related
i would like to get a Separator, which changes his Size with the Size of the Mother-Component.
In my Example, i have a JavaFX Popup and there i add a VBox. To this VBox i add a HBox. And this HBox has a Label, a Speparator and a Button.
Now i would like to have that the Button is on the Right End and the Label is on the Left End of the HBox. I think i have to use a Separator between these components to get the Space.
How can i handle it...
I made something like this, but it does not work.
// Box for the Headline
HBox headLine = new HBox();
headLine.setPadding(new Insets(5, 5, 5, 5));
// Label with the HeadLine Description in
final Label heading = new Label(headLineText);
heading.getStyleClass().addAll("popup-label-name");
// Close Button
close = new Button("X");
close.setVisible(false);
closeButtonHandler();
// Creates an invisble Separator1
Separator sep = new Separator(Orientation.HORIZONTAL);
sep.setVisible(false);
sep.widthProperty().add(m_container.widthProperty().get());
close.getStyleClass().addAll("popup-button", "popup-button-color");
// Adds to the Headline the Data
headLine.getChildren().addAll(heading, sep, close);
The Variable m_container is the VBox! How can i handle it?
Thanks for your help :)
The simplest way (if not using a different container like AnchorPane) is to insert an invisible, but expandible 'space' object:
void testLabelSpace(HBox box) {
Text first = new Text("first");
Text second = new Text("second");
Node space = new HBox();
HBox.setHgrow(space, Priority.ALWAYS);
box.getChildren().addAll(first, space, second);
}
If I understand the question correctly, you just want blank space between the label and the button. Just tell the Label always to grow horizontally, and set its maximum width to allow it to grow to any size:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
public class HBoxExample extends Application {
#Override
public void start(Stage primaryStage) {
HBox hbox = new HBox();
Label label = new Label("Label");
Button button = new Button("Button");
HBox.setHgrow(label, Priority.ALWAYS);
label.setMaxWidth(Double.MAX_VALUE);
hbox.getChildren().addAll(label, button);
primaryStage.setScene(new Scene(hbox, 350, 75));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
How can I achieve proportional resize of whole SplitPane?
public class JfxSplitPaneTest extends Application {
#Override
public void start(Stage stage) throws Exception {
SplitPane split = new SplitPane();
StackPane child1 = new StackPane();
child1.setStyle("-fx-background-color: #0000AA;");
StackPane child2 = new StackPane();
child2.setStyle("-fx-background-color: #00AA00;");
StackPane child3 = new StackPane();
child3.setStyle("-fx-background-color: #AA0000;");
split.getItems().addAll(child1, child2, child3);
//split.setDividerPositions(0.1f, 0.6f, 0.9f)
stage.setScene(new Scene(split, 400, 300));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Start the program:
Set dividers how I like them:
Make window width really small (I continued and made it even smaller, no pic):
Resize back and observe that dividers are neither how I set them nor how they were when program started.
Doing this makes it closer to what I'd expect:
child1.setMinWidth(Region.USE_PREF_SIZE)
child1.setPrefWidth(100)
child2.setMinWidth(Region.USE_PREF_SIZE)
child2.setPrefWidth(200)
child3.setMinWidth(Region.USE_PREF_SIZE)
child3.setPrefWidth(300)
except that dividers are initally at wrong position (until I resize SplitPane, 1px is enough) and when shrinking window width, dividers are inside components.
How can I make this work please?
Try to set the divisors like AS3Boyan said
split.setDividerPositions(0.1f, 0.6f, 0.9f)
and add this:
How can I avoid a SplitPane to resize one of the panes when the window resizes?
Try to add Change Listener to stage.widthProperty() and stage.heightProperty(). And call this:
split.setDividerPositions(0.1f, 0.6f, 0.9f)
The rule of thumb is to use setDividerPositions with Platform.runLater when the resize event is triggered.
You probably want to start with a default ratio, let the user change that ratio, and maintain this ratio whatever it is when there's a resize event. Let's consider a 25/75 vertical FX splitPane in some stage:
splitPane.setDividerPositions(0.25f, 0.75f);
stage.heightProperty().addListener((obs, oldVal, newVal) -> {
double[] positions = splitPane.getDividerPositions(); // reccord the current ratio
Platform.runLater(() -> splitPane.setDividerPositions(positions)); // apply the now former ratio
});
I mean drawing somg simple shape like circle,rectangleFigure,and polylineConnectistrong.It seems that a LightweightSystem has to been constructed on a Canvas such as a Shell.And in a RCP application when I add an extension of an editor,the editor extends org.eclipse.ui.part.EditorPart by default.It has a method called createPartControl.This method has a parameter (Composite parent).
So I write the following code and it give me a Unhandled event loop exception
public void createPartControl(Composite parent) {
Shell shell = parent.getShell();
shell.open();
Display display = shell.getDisplay();
LightweightSystem lws = new LightweightSystem(shell);
IFigure panel = new Figure();
lws.setContents(panel);
RectangleFigure node1 = new RectangleFigure();
RectangleFigure node2 = new RectangleFigure();
node1.setBackgroundColor(ColorConstants.red);
node1.setBounds(new Rectangle(30, 30, 64, 36));
node2.setBackgroundColor(ColorConstants.blue);
node2.setBounds(new Rectangle(100, 100, 64, 36));
PolylineConnection conn = new PolylineConnection();
conn.setSourceAnchor(new ChopboxAnchor(node1));
conn.setTargetAnchor(new ChopboxAnchor(node2));
conn.setTargetDecoration(new PolygonDecoration());
Label label = new Label("Midpoint");
label.setOpaque(true);
label.setBackgroundColor(ColorConstants.buttonLightest);
label.setBorder(new LineBorder());
conn.add(label, new MidpointLocator(conn, 0));
panel.add(node1);
panel.add(node2);
panel.add(conn);
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ())
display.sleep ();
}
}
So how to solve this problem and how to draw these figures on the editor?
As you want to draw inside the editor, you don't need to create new Shell nor dispatch events from the event queue as you would do in a standalone SWT application; just create a Canvas and draw into it. This should help you:
public void createPartControl(Composite parent) {
Canvas canvas = new Canvas(parent, SWT.NONE);
LightweightSystem lws = new LightweightSystem(canvas);
IFigure panel = new Figure();
lws.setContents(panel);
[...]
panel.add(node1);
panel.add(node2);
panel.add(conn);
}
When I run this program, the panel with the 6 buttons appears as it should on the bottom of the screen, and the first 3 labels appear as they should and where they should, but the last label appears at about the center of the screen. Furthermore, when I click and drag on the bottom right corner of the window (resizing the window), the panel and the last label move so they stay in their relative positions with the size of the window but the first 3 labels stay in their designated positions. When I uncomment the line of code towards the bottom that adds a blank JLabel, all 4 labels are now in their correct spots and only the panel moves when I resize the window. Could someone please explain what is going on here? Thanks in advance!
import javax.swing.*;
import java.awt.*;
public class X extends JFrame{
private JPanel panel;
private JButton buttons[];
private JLabel labels[];
private Icon images[];
public X()
{
panel = new JPanel();
panel.setPreferredSize(new Dimension(470,110));
buttons = new JButton[6];
labels = new JLabel[4];
Dimension dim = new Dimension(75,100);
labels = new JLabel[4];
images = new Icon[6];
for(int i = 0; i<6;i++)
images[i] = new ImageIcon(getClass().getResource("image" + i + ".gif"));
int j = 5;
while( j >= 0 ){
Icon image = images[j];
buttons[j] = new JButton(image);
buttons[j].setPreferredSize(dim);
panel.add(buttons[j]);
j--;
}
add(panel, BorderLayout.SOUTH);
j = 3;
while( j>=0){
Icon image = new ImageIcon(getClass().getResource("image6.gif"));
labels[j] = new JLabel(image);
labels[j].setPreferredSize(dim);
if (j==3){
labels[j].setBounds(200,135,75,100);
}
else if (j==2){
labels[j].setBounds(313,70,75,100);
}
else if (j==1){
labels[j].setBounds(425,135,75,100);
}
else if (j==0){
labels[j].setBounds(313,200,75,100);
}
add(labels[j]);
j--;
}
// add(new JLabel());
}
public static void main(String[] args) {
X frame = new X();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700,500);
frame.setVisible(true);
}
}
1) You should read Javadocs for JPanel/JButton/JLabel and their default behaviours.
2) You should make sure that the code which you post compiles
3) You should make sure that the code AS you post it illustrates your problem
As it is your post does not meet requirements 2) and 3) and you probably did not read enough of 1)
I am new to SmartGWT and having this issue for long time and could not fix it.
The charts are not in the right position and not resized after I maximize / restore the window, the same issue exists when I drag the resize bar in the window. However after I drag the edge of the window, even just a little, the charts can be rendered correctly. (looks like there is a delay or something)
I want my charts can render correctly immediately the window is maximized / restored, or when I drag the resize bar. NOT trying to drag the edge of the window every time to correct it.
Please take a look at the below simple case: (I am using HighCharts for charting)
import org.moxieapps.gwt.highcharts.client.Chart;
import org.moxieapps.gwt.highcharts.client.Point;
import org.moxieapps.gwt.highcharts.client.Series;
import org.moxieapps.gwt.highcharts.client.ToolTip;
import org.moxieapps.gwt.highcharts.client.ToolTipData;
import org.moxieapps.gwt.highcharts.client.ToolTipFormatter;
import org.moxieapps.gwt.highcharts.client.labels.PieDataLabels;
import org.moxieapps.gwt.highcharts.client.plotOptions.PiePlotOptions;
import org.moxieapps.gwt.highcharts.client.plotOptions.PlotOptions;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
public class Test1 implements EntryPoint {
public void onModuleLoad() {
Window.enableScrolling(true);
Window.setMargin("0px");
HLayout mainLayout = new HLayout();
mainLayout.setWidth100();
mainLayout.setHeight100();
VLayout vl1 = new VLayout();
vl1.setWidth(250);
vl1.setHeight100();
vl1.setShowResizeBar(true);
VLayout vl2 = new VLayout();
vl2.setWidth100();
vl2.setHeight100();
HLayout top = new HLayout();
HLayout bottom = new HLayout();
VLayout topLeft = new VLayout();
VLayout topRight = new VLayout();
VLayout bottomLeft = new VLayout();
VLayout bottomRight = new VLayout();
topLeft.addMember(drawCharts());
topRight.addMember(drawCharts());
bottomLeft.addMember(drawCharts());
bottomRight.addMember(drawCharts());
top.setMembers(topLeft, topRight);
bottom.setMembers(bottomLeft, bottomRight);
vl2.setMembers(top, bottom);
mainLayout.setMembers(vl1, vl2);
RootPanel.get().add(mainLayout);
}
private Chart drawCharts() {
final Chart chart = new Chart()
.setType(Series.Type.PIE)
.setPlotBackgroundColor((String) null)
.setPlotBorderWidth(null)
.setPlotShadow(false)
.setOption("/chart/marginTop", 0)
.setOption("/chart/marginBottom", 10)
.setPiePlotOptions(
new PiePlotOptions()
.setAllowPointSelect(true)
.setCursor(PlotOptions.Cursor.POINTER)
.setPieDataLabels(
new PieDataLabels().setEnabled(false))
.setShowInLegend(true))
.setToolTip(new ToolTip().setFormatter(new ToolTipFormatter() {
public String format(ToolTipData toolTipData) {
return "<b>" + toolTipData.getPointName() + "</b>: "
+ toolTipData.getYAsDouble() + " %";
}
}));
chart.addSeries(chart
.createSeries()
.setName("Browser share")
.setPoints(
new Point[] {
new Point("Firefox", 45.0),
new Point("IE", 26.8),
new Point("Chrome", 12.8).setSliced(true)
.setSelected(true),
new Point("Safari", 8.5),
new Point("Opera", 6.2),
new Point("Others", 0.7) }));
return chart;
}
}
Do I need to add a resize handler to fix this problem?
Or it may be the problem of the charts layout? I divided the area into four parts (top_left, top_right, bottom_left, bottom_right) and put chart into each part.
Anyone knows how to fix this problem which troubles me a long time? Appreciated.
First of all, I believe your browser share is not very accurate (Lol).
Taking a quick look at your code, it seems that you're mixing GWT charts with SmartGWT, which is not fully supported.
You will have to add some manual handling of the resizes events here.
Take a look at this post :
http://forums.smartclient.com/showthread.php?t=8159#aContainer
and the brief explanation is right here :
http://forums.smartclient.com/showthread.php?t=8159#aMix