Skip to main content

SGComponent with translation

5 replies [Last post]
asantiago
Offline
Joined: 2006-11-09
Points: 0

Hi all (and merry christmas)

I want to create a node to show Swing components. Logically I have extended the SGComponent, creating a new subclass, on which I create some JPanel and set as the content.

My problem is: I want every time the node is going to be rendered, the node itself calculates some values and translate itself.
As a first approach I have override the 'paint' method on which I calculate the new coordinates, apply it it through 'g.translate(x,y)' and then call the super.paint().
The problem with that is the node is rendered in the new coordinates but event doesn't respond. The events seems to take efect near the 0,0 coordinates.

As second try, I created some kind of SGFilter or SGTransform node which contains my SGComponent. The problem is a can't override the 'paint' method.

Anybody is in a similar situation? Any help or ideas will be appreciate.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
vvessan
Offline
Joined: 2007-10-13
Points: 0

Hello,

I have solved my problem by using older scenario library that can be downloaded from https://scenegraph.dev.java.net/ . Unfortunately there are some changes in API so it may not be compatible with other stuff you use, but works for me at least. But seems to be some regression issue.

vvessan
Offline
Joined: 2007-10-13
Points: 0

I have exactly the same problem. I have Translate->SGComponent->JButton in hierarchy and the button does not sometimes work as expected, but it is not deterministic, so I guess it is some concurrency issue. Sometime the button is clickable, sometime it is clickable only on top-left corner (so cose to 0,0 coords). My guess that it could be caused by the JButton size changes and the parent component is hot aware of the changes in the child JComponent.

Is there any way to let the parent component know or force it to revalidate or something? Haven't find any such method.

Thanks.

asantiago
Offline
Joined: 2006-11-09
Points: 0

Hi again.

I was playing with your previous code, which works fine, but not when I try to adapt to my code.

I have modified a bit your code to show my situation. What I want is every time my CustomSGComponent will be painted, previously calculate the appropiate position and translate it. All that every time and before it is rendered.

import com.sun.scenario.scenegraph.JSGPanel;
import com.sun.scenario.scenegraph.SGComponent;
import com.sun.scenario.scenegraph.SGTransform;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
*
* @author Antonio Santiago
*/
public class SwingTest extends JFrame
{

class CustomSGComponent extends SGComponent
{

private SGTransform.Translate translate;

public CustomSGComponent()
{
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(50, 50));
panel.setBackground(Color.BLACK);

this.setComponent(panel);
}

public void setTranslate(final SGTransform.Translate translate)
{
this.translate = translate;
}

@Override
public void paint(Graphics2D g)
{
System.out.println("Loc: " + translate.getTranslateX() + " - " + translate.getTranslateY());

translate.setTranslateX(translate.getTranslateX() + 1);
translate.setTranslateY(translate.getTranslateY() + 1);

super.paint(g);
}
}

// class CustomComponent extends JComponent
// {
//
// private SGTransform.Translate translate;
//
// CustomComponent(final SGTransform.Translate translate)
// {
// this.translate = translate;
// setPreferredSize(new Dimension(50, 50));
// addMouseListener(new MouseAdapter()
// {
//
// public void mouseClicked(MouseEvent e)
// {
// translate.setTranslateX(translate.getTranslateX() + 1);
// translate.setTranslateY(translate.getTranslateY() + 1);
// }
// });
// }
//
// protected void paintComponent(Graphics g)
// {
// g.setColor(Color.blue);
// g.fillRect(0, 0, getWidth(), getHeight());
// }
// }

public SwingTest()
{
JSGPanel panel = new JSGPanel();

// SGComponent component = new SGComponent();
CustomSGComponent component = new CustomSGComponent();
SGTransform.Translate trans = SGTransform.createTranslation(0, 0, component);
component.setTranslate(trans);
panel.setScene(trans);

// CustomComponent cc = new CustomComponent(trans);
// component.setComponent(cc);

getContentPane().setLayout(new BorderLayout());
getContentPane().add(panel);

setSize(500, 500);
setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}

public static void main(String[] args)
{
new SwingTest();
}
}

I don't know why my overriden 'paint' method is not called every time, and I don't know how to solve it.

Any ideas will be appreciated.
Thanks

Message was edited by: asantiago

mortennobel
Offline
Joined: 2004-11-03
Points: 0

If I understand your problem correct, you have created a Swing component that needs to be rendered at different locations (the the swing component needs to have control over where it is painted).

Hierarchically your application looks like this:
SGTranslate.Transform
-- SGComponent
---- CustomComponent
With that little twist that the CustomComponent needs to have a reference to the SGTranslate object (to change the position).

I have created a small sample application to demonstrate:
_____________________________________
import com.sun.scenario.scenegraph.SGTransform;
import com.sun.scenario.scenegraph.JSGPanel;
import com.sun.scenario.scenegraph.SGComponent;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class SwingTest extends JFrame {

class CustomComponent extends JComponent {
private SGTransform.Translate translate;

CustomComponent(final SGTransform.Translate translate) {
this.translate = translate;
setPreferredSize(new Dimension(50,50));
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
translate.setTranslateX(translate.getTranslateX()+1);
translate.setTranslateY(translate.getTranslateY()+1);
}
});
}

protected void paintComponent(Graphics g) {
g.setColor(Color.blue);
g.fillRect(0,0,getWidth(),getHeight());
}
}

public SwingTest() {
JSGPanel panel = new JSGPanel();

SGComponent component = new SGComponent();
SGTransform.Translate trans = SGTransform.createTranslation(0,0,component);
panel.setScene(trans);

CustomComponent cc = new CustomComponent(trans);
component.setComponent(cc);

getContentPane().setLayout(new BorderLayout());
getContentPane().add(panel);

setSize(500,500);
setVisible(true);
}

public static void main(String[] args) {
new SwingTest();
}
}
______________

Kind regards,
Morten

asantiago
Offline
Joined: 2006-11-09
Points: 0

Thanks a lot !!!

It can seem stupid but I didn't thought on that :) that is, send a reference to a parent node.