JavaFX: How can I migrate JComponent? - swing

I'm migrating a swing application to JavaFX. There is a lot of Code, that abstracts from JComponent.
public abstract class ComponentLayoutHelper<TComponent extends Componend>{...
componend.setBorder()
...}
Properties like the visibility, border and opaque is set to a Component first and afterwards the properties are extended for specific Components like Labels etc.
public class LabelLayoutHelper extends ComponendLayoutHelper<JLabel>{...
label.setText();
...}
In this post:
Alternative for JComponent in JavaFX they talked about Node as an equivalent to JComponent. But node doesnt have properties like border or opaque. Does someone have an idea how to migrate JComponent?

Related

Polymer Dart Strong Mode and Mixins is forcing weird code designs

We started to use Dart's Strong mode with our polymer dart code and honestly it looks terrible. It looks so terrible that I need a second opinion on the matter. It cant be this ugly looking, it honestly cant.
So We were creating a bunch of PolymerDart views using some mix ins for generic code. This generic code is reused everywhere so hence why we made it a mixin.
Our old design:
abstract class MyModel{ ... }
class SubModel extends MyModel with JsProxy{ ... }
#behavior
abstract class MyBehavior implements PolymerBase {
#Property(notify:true)
MyModel model = null;
// ....
}
#PolymerRegister("my-component")
class MyViewModel extends PolymerElement with MyBehavior {
#Property(notify:true)
SubModel model = null;
// ...
}
The purpose was to have a generic model to represent information and we leverage it in the behavior. Since SubModel extends it, we can slot anywhere normally and the behavior would work. My colleague says this is a huge NO and I am confused as to why. He said it a Polymer Issue, so when we leave Polymer it will be able to be done sort of.
He then pushed through the code base a refactor so it works.
#PolymerRegister("my-component")
class MyViewModel extends PolymerElement with MyBehavior {
#Property(notify:true)
MyModel model = null; // <-- changed to parent type from Behavior
//example reference
void test(){
int id = (model as SubModel).id; // <-- using AS to explain what it really is.
}
}
Now he put this EVERYWHERE, updated all references of model.id with (model as SubModel).id. I think this is ugly and just plain wrong. (Granted I get that feeling with everything PolymerDart).
Is this really how this kind of thing is done when dealing with Mixins? Since The mixin already has that definition, we shouldn't need it in the MyViewModel code either.
Can someone explain this to me as to why this is the right thing according to strong mode? Why must this change occur? While I trust in my colleague, something does seem off and I would like a deeper understanding. I believe, that he is correct that maybe it is because entirely due to Polymer Dart, but maybe there is a way to circumventing all property renames, and using (.. as Whatever) everywhere.
analysis_options.yaml:
analyzer:
strong-mode: true
Edit: The reasoning was that since the Model is defined as a property in the behavior, it is non-mutable. We cant override the type in the MyViewModel class. Since SubModel extends MyModel, It should be allowed to exist.

In AS3, how do I run code when a when the movie starts?

I'm making a level editor for my game, and would like to be able to access a list of all the classes included in my game. I have a static function in my Main class:
public static function register(c:Class, category:String):void {
if (classRegister[category] == null) {
classRegister[category] = new Array();
}
classRegister[category].push(c);
}
Then, in each class I want registered, I put a static initializer:
{
Main.register(prototype.constructor, "motion");
}
However, the static initializers only get called when the class first gets used. Is there a way for a class to force itself to be used right when the game starts? I'm aware that I could explicitly list all the registered classes in the Main file, but that's suboptimal in that the Main file would have to be edited whenever a new class is added that wants registration.
Thanks,
Varga
List all the class definition in the ApplicationDomain, and filter them based on a naming convention or a type (an interface?).
To achieve this, you can use ApplicationDomain.getQualifiedDefinitionNames() (docs), but only if you target FlashPlayer 11.3+.
As a side note, you MUST reference this class somewhere, as a class field so the compiler knows it must include this class in the SWF. You can also put the classes you want to reference inside a SWC library and use -compiler.include-libraries as compiler setting (in that case I wonder if your static initializers gets called?).

Is it possible to access a class outside package from other package?

I have a class like this
package test{
class Test{}
}
class TestInnerClass{}
I can access the TestInnerClass from Test class but I need to access the TestInnerClass(as class, not its instance) from other class as well. And I don't really want to make TestInnerClass an independent class as all it contains are a few variables.
Is there any way to access the class from outside Test class?
[edit]
More specifically, I need the access for the following code to work.
registerClassAlias("TestInnerClass",TestInnerClass);
If you have a class that would not otherwise be accessed except internally by a public class you may define it as internal.
Internal classes are visible to references inside the current package.
In your example, TestInnerClass is only visible to Test.
Otherwise, to access the class or register class alias it must be defined public in its own .as file.
Packages help to order and classify code in hierarchy. Often, I'll keep Value Object or Data Transfer Objects within their own package, such as:
com.jasonsturges.model.vo
This helps to group smaller model classes together.
If you wanted to make a class visible outside of it's containing package your class would be defined as so:
// SampleCode.as file
package samples{
public class SampleCode {}
}
// CodeFormatter.as file
package samples{
class CodeFormatter {}
}
The SampleCode class is visible whilst the CodeFormatter class is not.
Hope I've answered your question

Is it possible to change an inherited access modifier in ActionScript 3?

I'm currently working on a project where I have a ton of classes inheriting from other classes which inherit from other classes and so on. It's probably more complex than it should be, but I am a sucker for abstraction.
Anyway, at times I need to change a getter/setter from being public to private. I suppose it's not really a need, but a desire to cut off things that are preset in child classes, but still need to be publicly accessible in the parent classes.
So an example would be:
Class Base {
public function set label( value:String ):void{};
}
Class A extends Base {}
Class B extends A {
public function B() {
super();
this.label = "stuff";
}
override public function set label( value:String ):void {
//this setter should not be publicly available since the label should not be possible to change in this class
}
}
Currently, I am doing one of two things in these cases:
override the setter to do nothing or set it to the default value so that it can still update/render/whatever
throw an error saying it is unavailable in that class
I've done some searching and everything seems to point to this being impossible, but I've never found it explicitly stated that it is impossible. So is it possible to change the access modifier on an inherited property/function?
It is not possible, and it really should not be, because it leads to confusing and unpredictable class hierarchies. For starters, if you did something like that, you would break the Liskov Substitution Principle: A super class should at all times be replaceable by its derived classes. Changing the API would clearly prevent that - and thus possibly lead to runtime errors and/or inexplicable glitches, if another programmer accidentally exchanged types.
If the classes you are modeling have different behavior in such a way that would make you "hide" an otherwise public API method, you should probably not use inheritance for this - or perhaps in a different way. From what you are describing, I would guess that in a larger part of your hierarchy, you should probably be using composition instead of inheritance, anyway.
It is not possible for the very reason in the comments by Marty Wallace. But it's not an uncommon thing to do.
However in the alternative you used, The property owner is the base class & hence it should always know of anything that the derived class does with it's own properties.
Instead of your hack I would thus prefer something like this :
public class Base {
protected var _isLabelUsable:Boolean = true;
public function set label( value:String ):void {
if (!_isLabelUsable)
throw new Error("Access of undefined property label.");
// Set Label here
}
}
public class A extends Base {
}
public class B extends A {
public function B() {
super();
_isLabelUsable = false;
}
}
These are all valid points, but...
There are cases where they are all void.
Given a base class that comes from an external source. Like, say, mx:Panel.
It has the property 'titleIcon:Class'
The derived class inherits all properties and functions. But people using it shall never set the titleIcon directly, because part of the derived class' functionality depends on the availability of an icon name being known. It provides a property iconName:String. Setting it will also set the titleIcon.
Now how to prevent people from still setting the icon directly? The UI is offering the old property for AS3 and MXML, and the compiler will (of course) not complain.
If titleIcon is a setter/getter pair (in this case, it is), and not final, then the derived class can override the setter and throw an error, while the iconName setter will assign the icon class to super.titleIcon.
However, this is clumsy and will not work for final functions or variables.
If there were a way to at least tell the UI to not offer the property anymore or show a warning...

Document class silently fails

I have this weird issue while compiling my .fla file : it won't use the Document class. Here is the document class. (note that the parent class EditorPlugin extends Sprite).
package com.myproject.plugins.editor {
import flash.display.MovieClip;
import com.myproject.editor.EditorPlugin;
import com.myproject.editor.tools.EpisodeEditorTool;
import com.myproject.editor.tools.NewTabTool;
import com.myproject.editor.tools.ToolManager;
public class EpisodeEditorPlugin extends EditorPlugin{
public function EpisodeEditorPlugin(){
trace("creating", this);
AddAuth(ToolManager.EDIT_EPISODE_AUTH, ToolManager.EDIT_EPISODE_AUTH, EpisodeEditorTool, ToolManager.EDIT_EPISODE_LABEL);
}
}
}
The weird part is that in the line below, if I use NewTabTool instead of EpisodeEditorTool, the code works just fine, but with EpisodeEditorTool, the Class is not instanciated. There are no warnings or compiling errors, but i don't get the trace. I loaded the resulting .swf, it is not of type EpisodeEditorPlugin, but rather a simple MovieClip (via getQualifiedClassName() and is EpisodeEditorPlugin).
The EpisodeEditorTool and NewTabTool are quite similar even though of different use, but very huge, here are their declarations :
public class EpisodeEditorTool extends JPanel implements ITool{
and
public class NewTabTool extends JPanel implements ITool{
I should add that both class contain no error (at least according to Flash) and have been compiled in other .flas before. the only problem I can see is that EpisodeEditorTool is even more huge(r?) than other ITools.
Does anyone have any idea of how a document class could fail to be applied? And fail silently at that?
Thanks!
The only thing I can really think of is that you're not specifying the name of the Document class correctly inside the Flash IDE. Inside the Properties panel there's a box where you enter the name of your Document class, which you must presumably have used if the Document class works when you rename the class to NewTabTool. I guess you put NewTabTool into that box, then changed the actual class' name, and forgot to change the reference in the Properties panel. I've forgotten that little bit when changing the name of my Document class before, I hope your solution is as simple as that!
debu