JGoButton problem

I’ve created an extension, PLXButton, of JGoButton, currently all it does is extend JGoButton - no methods are overriden. All that the constructor of PLXButton does is call

super(new Rectangle(50,50), “PLX”);

My application has one JGoView and several documents and I use view.setDocument(…) to change whats displayed. All of this works fine. My JGoDocuments have various areas with nodes added to them and when I tell the view to swap documents everything works as expected. Howeverwhen I add my extension of JGoButton things go slightly wrong.

I have a class

SFPNode extends JGoIconicNode

and in the constructor of SFPNode I have
onOffBtn = new PLXButton();
this.addObjectAtHead(onOffBtn );

Once the application has run up I see the all the nodes and the PLXButtons,
when I toggle the document I see the new document (and its PLXButtons) displayed correctly - however when I toggle back to the first document the PLXButtons are not shown ('tho they were shown initially) - similarly if I then go back to the second document it too has ‘lost’ its PLXButtons (but all the other nodes are fine).

I’m using JGo 521, Jave 150

Any thoughts ?

Thanks

Mike

Well, that’s an interesting bug. Thanks for reporting it.

Basically the problem is that in JGoView.setDocument, it is correctly removing all of the JComponents from the view (or for SWT, Controls), but it is not clearing the reference from the JGoControl/JGoButton/PLXButton to its JComponent/Control.
Try modifying the implementation of JGoView.setDocument. Add the following line:
c.getMap().remove(this);
immediately after the call to repaint (or to redraw if you are using JGo for SWT).

Nice one Walter! Thanks.

Hi,

I made the changes as suggested and it works fine. However a new problem has occured - I suspect the two are related.

I add some sub-classes of JGoButton to my SFPNode and the node is added to a simple extension of JGoSubGraph called StandardSubGraph. All the extension does is customise simple things in the constructor (e.g. insets, border pen etc.)

Prior to adding extensions of JGoButtons to the StandardSubGraph I had no problems dragging the subgraph around the screen. However with extensions of JGoButton added I get the following error

java.lang.InstantiationException: com.xyratex.plx.jgo.StandardSubGraph
at java.lang.Class.newInstance0(Class.java:335)
at java.lang.Class.newInstance(Class.java:303)
at com.nwoods.jgo.JGoObject.copyObject(JGoObject.java:266)
at com.nwoods.jgo.JGoArea.copyObject(JGoArea.java:85)
at com.nwoods.jgo.JGoNode.copyObject(JGoNode.java:51)
at com.nwoods.jgo.JGoCopyMap.copy(JGoCopyMap.java:93)
at com.nwoods.jgo.JGoDocument.copyFromCollection(JGoDocument.java:1692)
at com.nwoods.jgo.JGoDocument.copyFromCollection(JGoDocument.java:1645)
at com.nwoods.jgo.JGoView.dragGestureRecognized(JGoView.java:6551)
at com.nwoods.jgo.JGoView.onDragGestureRecognized(JGoView.java:6526)
at com.nwoods.jgo.JGoView$JGoViewCanvas.dragGestureRecognized(JGoView.java:1983)
at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(DragGestureRecognizer.java:339)
at sun.awt.windows.WMouseDragGestureRecognizer.mouseDragged(WMouseDragGestureRecognizer.java:202)
at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:261)
at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:261)
at java.awt.Component.processMouseMotionEvent(Component.java:5536)
at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:3144)
at java.awt.Component.processEvent(Component.java:5257)
at java.awt.Container.processEvent(Container.java:1966)
at java.awt.Component.dispatchEventImpl(Component.java:3955)
at java.awt.Container.dispatchEventImpl(Container.java:2024)
at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3909)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
at java.awt.Container.dispatchEventImpl(Container.java:2010)
at java.awt.Window.dispatchEventImpl(Window.java:1774)
at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Does anything spring to mind?
Are there some methods in JGoButton that my extensions must override?

Thanks

Mike

The stack trace suggests that you don’t have a default (i.e. zero-argument) constructor. That’s needed by copyObject.

This is a requirement for all JGoObject subclasses, so it doesn't have anything to do with JGoButton in particular.

Thanks Walter, that’s sorted it out.

Could you tell me please what is the best (correct) way to modify the properties of the JButton owned by the JGoButton class? I want to do things like change the icon and the border. I’ve tried extending JGoButton and getting the button from createComponent and modifying the buttons properties before returning it but this causes the processor to max out when the view is made visible.

Thanks

Mike

I’ve just looked at my code in more detail (always a good idea!)…

public class PLXButton extends JGoButton
{

 public JComponent createComponent( JGoView view )

{
System.out.println( "createComponent " );
final JButton btn = ( JButton ) super.createComponent( view );
btn.setFocusable( false );
btn.setIcon( icon );
btn.setBorder( null );
btn.setOpaque( false );
return btn;
}

}

The line btn.setOpaque( false ); causes the CPU to max out when the view is visible. Certainly when I remove it the whole GUI behaves sensibly.

I’m not sure if I understand why this line causes problems. Any comments would be appreciated.

Thanks

Mike

Yes, overriding JGoControl.createComponent is the right thing to do. I can’t explain the behavior you are seeing. This works for me:

[code]public class TestButton extends JGoButton {
public TestButton() {
setSize(100, 50);
setLabel("hello");
}
public String getIconName() { return myIconName; }
public void setIconName(String s) { myIconName = s; } //??? does not update existing icons
private String myIconName = "";
public JComponent createComponent(JGoView view) {
JButton but = (JButton)super.createComponent(view);
ImageIcon icon = new ImageIcon(getIconName());
but.setIcon(icon);
return but;
}
}[/code]
You'll need to call setIconName during initialization of the TestButton;
I didn't bother implementing support for updating the icon for all the existing JButtons that the TestButton might be hosting.

(Cross posts)

Well, as my doctor says: if it hurts, don't do it.
I don't recall what you need to do to implement partially transparent JComponents. Certainly JGoView itself does not support that feature.