Javafx component won't show in JFrame for a seond time after dispose - swing

My java project has 2 JFrame. Let's call it A and B. Frame A has a button that when click will show Frame B.
In a button's event listener is
SwingUtilities.invokeLater(new Runnable () {
public void run() {
B b = new B();
}
});
In Frame B, there is a JFXPanel which show PieChart.
The problem is when I closed it and reopen by clicking a button in Frame A, Frame B is shown but the Pie Chart won't show. (Frame B is DISPOSE_ON_CLOSED as DefaultCloseOperation)
Why is that and how to fix it?

Related

Set object's `visible` to `true` when a `tap` event is performed then set it back to `false`

I have an object as MovieClip and I have a button as Button on my flash timeline.
When the button is tapped, I want to set the object.visible to true then when the button is not tapped, I want to set it back to false.
How can I do that?
I have tried this code, but it won't works as I want. I only can show the object but cannot hide it back.
button1.addEventListener(TouchEvent.TOUCH_TAP, touchTap);
function touchTap(e:TouchEvent): void {
mcObj.visible = true;
stage.addEventListener(TouchEvent.TOUCH_END, touchEnd);
}
function touchEnd(e:TouchEvent): void {
mcObj.visible = false;
stage.removeEventListener(TouchEvent.TOUCH_END, touchEnd);
}
I think this code could work.
button1.addEventListener(TouchEvent.TOUCH_BEGIN, touchTap);
function touchTap(e:TouchEvent): void {
mcObj.visible = true;
button1.addEventListener(TouchEvent.TOUCH_END, touchEnd);
}
function touchEnd(e:TouchEvent): void {
mcObj.visible = false;
button1.removeEventListener(TouchEvent.TOUCH_END, touchEnd);
}
I changed
1: TouchEvent.TOUCH_TAP to TouchEvent.TOUCH_BEGIN
2: stage.addEventListener to button1.addEventListener
Before saying anything about your problem, let's take a look on the definitions of the TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_END and TouchEvent.TOUCH_TAP events :
The TouchEvent.TOUCH_BEGIN is :
Dispatched when the user first contacts a touch-enabled device ...
The TouchEvent.TOUCH_END is :
Dispatched when the user removes contact with a touch-enabled device ...
The TouchEvent.TOUCH_TAP is :
Dispatched when the user lifts the point of contact over the same InteractiveObject instance on which the contact was initiated on a touch-enabled device ...
And with some tests, we can see that the TouchEvent.TOUCH_END event is, in almost cases, fired before the TouchEvent.TOUCH_TAP one (by 1 or 2 milliseconds), so we can understand the we are able to detect if the user has already removed contact with the device (TouchEvent.TOUCH_END is fired) then if that was on the same InteractiveObject object on which the contact was initiated (TouchEvent.TOUCH_TAP is fired).
And that's why your code is not working.
Now, let's see your problem : you want to show a MovieClip just when your user tap a button and hide it when he releases that button but only for a very short time (the time of a tap ~= 300 milliseconds).
In this case, I recommend you to use a TouchEvent.TOUCH_BEGIN event listener with a timeout to hide that object even if your user didn't release the button.
For that, take this example :
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
btn.addEventListener(TouchEvent.TOUCH_BEGIN, on_touchBegin);
function on_touchBegin(e:TouchEvent): void
{
obj.visible = true;
hide_obj();
}
function hide_obj(): void
{
// you can use a Timer object instead of setTimeout()
var timeout:int = setTimeout(function(){
clearTimeout(timeout);
obj.visible = false;
}, 300);
}
Hope that can help.

Missing Event type MouseUp

In the following scenario a Event from type MouseUp is missing.
The base to reproduce is this code (using rap 3.0)
#Override
protected void createContents(Composite parent) {
GridLayout gl = new GridLayout(1, false);
parent.setLayout(gl);
GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false);
Composite above = new Composite(parent, SWT.BORDER);
above.setLayout(gl);
above.setLayoutData(gd);
Button buttonAbove = new Button(above, SWT.TOGGLE);
buttonAbove.setText("above");
Button button = new Button(parent, SWT.TOGGLE);
button.setText("start");
addListener(button);
Composite bottom = new Composite(parent, SWT.BORDER);
bottom.setLayout(gl);
bottom.setLayoutData(gd);
Button buttonBottom = new Button(bottom, SWT.TOGGLE);
buttonBottom.setText("bottom");
}
private void addListener(Button button) {
Listener listener = new Listener() {
#Override
public void handleEvent(Event event) {
switch (event.type) {
case SWT.MouseDown:
System.out.println("MouseDown");
break;
case SWT.MouseUp:
System.out.println("MouseUp");
break;
}
}
};
button.addListener(SWT.MouseDown, listener);
button.addListener(SWT.MouseUp, listener);
}
go with the cursor over the button start
press the mouse button and keep it pressed
drag the cursor to the right, over the button bottom or to the composite buttom and release the MouseButton --> the Event from type SWT.MouseUp is fired
go with the cursor over the button start again
press the mouse button and keep it pressed
drag the cursor over the button above or over the composite above and release the mouse button --> the Event is not fired
I found this problem in a more complex way while doing drag'n'drop of a Button and this seem to be the root of the problem.
In a SWT Application a MouseUp Event is always thrown.
Is this a bug in RAP?

Buttons within Movieclip AS3 not working

I'm relatively new to flash and as3. Basically I'm trying to load a movieclip to the stage and then click a button within that movieclip to remove the child again from the stage. I have the following movieclip:
var myResultBox:ResultBox = new ResultBox();
addChild(myResultBox);
I have a button placed within the movieclip called closeButton1. I am trying to click the close button which in turn removes the movieclip.
the code within the MovieClip is -
//Event Listener for Close button within my results box
closeButton1.addEventListener(MouseEvent.CLICK, closeBMI);
function closeBMI(evt:MouseEvent):void
{
removeChild(myResultBox);
}
Following error
code: 1120: Access of undefined property closeButton1.
Any help would be most appreciated
Below is a simple program which i think has the functionality of what you are asking for. As far as I understand, you have button A on the stage. When you click button A, movie clip B is added to the stage. Movie clip B has button B in it. When you click button B, Movie clip B and button B are removed.
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
// This creates a movie clip that contains a button.
// This button will remove the movie clip that contains
// it when it is clicked.
var MovieClipB = new MovieClip();
MovieClipB.graphics.lineStyle(1,0);
MovieClipB.graphics.beginFill(0x0000FF,1);
MovieClipB.graphics.drawRect(0,0,50,50);
var ButtonB:MovieClip = new MovieClip();
ButtonB.buttonMode = true;
ButtonB.graphics.lineStyle(1,0);
ButtonB.graphics.beginFill(0xFFFFFF,1)
ButtonB.graphics.drawCircle(0,0,10);
ButtonB.x = ButtonB.y = 25;
MovieClipB.addChild(ButtonB);
ButtonB.addEventListener(MouseEvent.CLICK, removeButtonClickHandler, false, 0, true);
function removeButtonClickHandler(event:MouseEvent):void
{
var button = MovieClip(event.currentTarget);
var container = button.parent;
container.parent.removeChild(container);
}
// This creates a button that starts on the stage.
// When clicked, it adds the movie clip defined above to the stage
var ButtonA:MovieClip = new MovieClip();
ButtonA.buttonMode = true;
ButtonA.graphics.lineStyle(1,0);
ButtonA.graphics.beginFill(0xFF0000,1)
ButtonA.graphics.drawRect(0,0,50,50);
addChild(ButtonA);
ButtonA.x = ButtonA.y = 20;
ButtonA.addEventListener(MouseEvent.CLICK, addButtonClickHandler, false, 0, true);
function addButtonClickHandler(event:MouseEvent) : void
{
addChild(MovieClipB);
MovieClipB.x = 200;
MovieClipB.y = 20;
}
Within the button? But you can't reference button in such way. You should put your code within movieclip that holds button, where you add result addChild(myResultBox); So your event handler will be able reference myResultBox
For code within a button:
this.addEventListener(MouseEvent.CLICK, closeBMI);
function closeBMI(evt:MouseEvent):void
{
//removeChild(myResultBox);
//Sadly, you don't have reference on myResultBox within a button...
}

AS3 Concept similar to Event-Bubbling, in non-display-objects?

Events in Flash/AS3 are very much linked to the display list. There is the capture, target, and bubbling phase, which is great when it comes to objects visible on the stage.
But is there a similar concept for non display objects, outside of the display list?
If we have objects A, B and C, where C was created in object B, and B was created in object A, and none of them are display objects: How can A listen for things happening in C?
You can solve your problem using at least two strategies:
1) Redispatching of events. Say C dispatches some event. In B we subscribe this event and redispatch it:
var c:C = new C();
c.addEventListener("myEvent", myEventHandler);
private function myEventHandler (event:Event):void
{
dispatchEvent(event);
}
Remember you should implement clone() properly for your custom event class in this case.
You also can translate event from C to some other event in B and dispatch it.
2) Pass C to A. You can do it using interface flash.events.IEventDispatcher.
Something like the following:
In B:
private var _c:IEventDispatcher;
public function get innerInstance():IEventDispatcher
{
return _c;
}
public function B()
{
_c = new C();
}
In A:
var b:B = new B();
b.innerInstance.addEventListener("myEvent", myEventHandler);

MouseUpEvent stops working while Dragging MovieClip

There is a mouseUpEvent listener attached to the stage in the main class, while dragging the movieClip the mouseUpEvent doesnot trigger the handler and the movieClip gets sticks to the mouse. While the item is being dragged and the mouse is moved away from the movieClip i.e somewhere not on the item but on the stage the mouseUp is detected.
Edit: Here is the scenario I am using a static (Singleton) class as a movieClip as a "DragManager". Whenever a movieClip has to be dragged it is passed to the DragManager and is added as a child, when a mouseUp from stage is detected another static function of dragManager is called to stop the drag and put the movieClip on the appropriate layer. Here is the static function in the DragManager which is called on MouseDown from variouslayers.
public static function startDragMethod(item:Item):void
{
instance.addChild(item); //This is the instance of the DragManager
var boundArea:Rectangle = new Rectangle(0,0,610,760);
item.startDrag(false,boundArea);
}
In the constructor of the main class I add the eventHandler for the MouseUpEvent
this.addEventListener(MouseEvent.MOUSE_UP,stageMouseUpHandler);
The MouseUpHandler in the main class
private function stageMouseUpHandler(event:MouseEvent):void
{
DragManager.itemMouseUpHandler(event);
}
If there is something wrong with technique please guide me, my goal is to implement drag drop between various layers and with as less coupling as possible.
Well there are many ways to get the task done. Put some condition at your static listener function or when the object is dragged.
like
public static function startDragMethod(item:Item):void
{
instance.addChild(item); //This is the instance of the DragManager
var boundArea:Rectangle = new Rectangle(0,0,610,760);
item.startDrag(false,boundArea);
check = true;
}
private function stageMouseUpHandler(event:MouseEvent):void
{
if(check==true)
{
DragManager.itemMouseUpHandler(event);
check = false;
}
}