is it possible to create custom effects for JavaFX, based on a Pixle Shader? I found this article but what is Decora? I cannot find anything about it.
THX
Currently no - in the abstract base class Effect.java, there are abstract package-private methods like, copy(), sync(), update() etc.
The Decora project is discussed here: http://labonnesoupe.org/static/code/ . I asked about opening JSL, to make some kind of public API in the developer OpenJFX thread perhaps 6 months ago, and was told, "no, there are no plans to open this api to the public".
As you may be aware, OpenJFX are considering new committers, which works, I believe on the premise that you sign an Oracle contributor agreement, and are voted in by lazy consensus. Perhaps this will shunt this much needed area into life.
In my own 2D game, I use Guassian Blurs, and Blooms, to highlight spell strikes, and I believe Decora was used in developing these Effects. However, they are pitifully slow. Taking my FPS from around 250 down to around 30 on a 10 series NVidia card. I would love to see improvements here.
I emailed Chris Campbell (author of Labonnesoupe) asking about his work on JavaFX shaders, but he emailed me back to say it was over 8 years ago, and he's not up on the latest. A search of web reveals that all reference to Decora is now ancient.
Theoretically it is possible to create you custom effect in JavaFx however using way u probably won't like. Abstract class javafx.scene.effect.Effect has internal methods inside, that is right. But based on the fact that internal means "package private" we can do the following. In your project create a new package called "javafx.scene.effect" the same as Effect class is in, and inside this newly created package just create your custom effect class that extends javafx.scene.effect.Effect and that's it you have your custom JavaFx effect.
Custom Effect class example:
package javafx.scene.effect;
import com.sun.javafx.geom.BaseBounds;
import com.sun.javafx.geom.Rectangle;
import com.sun.javafx.geom.transform.BaseTransform;
import com.sun.javafx.scene.BoundsAccessor;
import com.sun.scenario.effect.FilterContext;
import com.sun.scenario.effect.ImageData;
import javafx.scene.Node;
public class MyEffect extends javafx.scene.effect.Effect
{
public MyEffect()
{
}
#Override
com.sun.scenario.effect.Effect impl_createImpl()
{
return new com.sun.scenario.effect.Effect()
{
#Override
public boolean reducesOpaquePixels()
{
// TODO Auto-generated method stub
return false;
}
#Override
public BaseBounds getBounds(BaseTransform transform, com.sun.scenario.effect.Effect defaultInput)
{
// TODO Auto-generated method stub
return null;
}
#Override
public AccelType getAccelType(FilterContext fctx)
{
// TODO Auto-generated method stub
return null;
}
#Override
public ImageData filter(FilterContext fctx, BaseTransform transform, Rectangle outputClip, Object renderHelper, com.sun.scenario.effect.Effect defaultInput)
{
// TODO Auto-generated method stub
return null;
}
};
}
#Override
void impl_update()
{
// TODO Auto-generated method stub
}
#Override
public BaseBounds impl_getBounds(BaseBounds bounds, BaseTransform tx, Node node, BoundsAccessor boundsAccessor)
{
// TODO Auto-generated method stub
return null;
}
#Override
boolean impl_checkChainContains(javafx.scene.effect.Effect e)
{
// TODO Auto-generated method stub
return false;
}
#Override
public javafx.scene.effect.Effect impl_copy()
{
// TODO Auto-generated method stub
return null;
}
}
However I have literally no idea what those inhered methods in from javafx.scene.effect.Effect supposed to do so you need to figure it out :)
Also, keep in mind that internal/private things are private for some reason (even though I also do not see that reason in this case)!
Aditional: What I currently know is that JavaFx Effects are only some sort of "masks" or "providers" for Effects from `com.sun.scenario.effect` and there are many com.sun.scenario.effect children classes that have no direct JavaFx version/implementation so you should be theoretically able to add these ones into JavaFx by your self using my solution! But again there is a question if this is a good idea because I think `com.sun.scenario.effect` is something that regular JavaFx programer supposed to not even know about. But I will let you to decide!
Use libgdx. Its free and Works on Web HTML 5 webgl ,ios,android,all desktop and with full shader support
Related
This question already has answers here:
How to make a Java class that implements one interface with two generic types?
(9 answers)
Closed 8 years ago.
I have the following interface, which I want to implement multiple times in my classes:
public interface EventListener<T extends Event>
{
public void onEvent(T event);
}
Now, I want to be able to implement this interface in the following way:
class Foo implements EventListener<LoginEvent>, EventListener<LogoutEvent>
{
#Override
public void onEvent(LoginEvent event)
{
}
#Override
public void onEvent(LogoutEvent event)
{
}
}
However, this gives me the error: Duplicate class com.foo.EventListener on the line:
class Foo implements EventListener<LoginEvent>, EventListener<LogoutEvent>
Is it possible to implement the interface twice with different generics? If not, what's the next closest thing I can do to achieve what I'm trying to do here?
Is it possible to implement the interface twice with different generics
Unfortunately no. The reason you can't implement the same interface twice is because of type erasure. The compiler will handle type parameters, and a runtime EventListener<X> is just a EventListener
If not, what's the next closest thing I can do to achieve what I'm trying to do here?
Type erasure can work in our favor. Once you know that EventListener<X> and EventListener<Y> are just raw EventListener at run-time, it is easier than you think to write an EventListener that can deal with different kinds of Events. Bellow is a solution that passes the IS-A test for EventListener and correctly handles both Login and Logout events by means of simple delegation:
#SuppressWarnings("rawtypes")
public class Foo implements EventListener {
// Map delegation, but could be anything really
private final Map<Class<? extends Event>, EventListener> listeners;
// Concrete Listener for Login - could be anonymous
private class LoginListener implements EventListener<LoginEvent> {
public void onEvent(LoginEvent event) {
System.out.println("Login");
}
}
// Concrete Listener for Logout - could be anonymous
private class LogoutListener implements EventListener<LogoutEvent> {
public void onEvent(LogoutEvent event) {
System.out.println("Logout");
}
}
public Foo() {
#SuppressWarnings("rawtypes")
Map<Class<? extends Event>, EventListener> temp = new HashMap<>();
// LoginEvents will be routed to LoginListener
temp.put(LoginEvent.class, new LoginListener());
// LogoutEvents will be routed to LoginListener
temp.put(LogoutEvent.class, new LogoutListener());
listeners = Collections.unmodifiableMap(temp);
}
#SuppressWarnings("unchecked")
#Override
public void onEvent(Event event) {
// Maps make it easy to delegate, but again, this could be anything
if (listeners.containsKey(event.getClass())) {
listeners.get(event.getClass()).onEvent(event);
} else {
/* Screams if a unsupported event gets passed
* Comment this line if you want to ignore
* unsupported events
*/
throw new IllegalArgumentException("Event not supported");
}
}
public static void main(String[] args) {
Foo foo = new Foo();
System.out.println(foo instanceof EventListener); // true
foo.onEvent(new LoginEvent()); // Login
foo.onEvent(new LogoutEvent()); // Logout
}
}
The suppress warnings are there because we are "abusing" type erasure and delegating to two different event listeners based on the event concrete type. I have chosen to do it using a HashMap and the run-time Event class, but there are a lot of other possible implementations. You could use anonymous inner classes like #user949300 suggested, you could include a getEventType discriminator on the Event class to know what do to with each event and so on.
By using this code for all effects you are creating a single EventListener able to handle two kinds of events. The workaround is 100% self-contained (no need to expose the internal EventListeners).
Finally, there is one last issue that may bother you. At compile time Foo type is actually EventListener. Now, API methods out of your control may be expecting parametrized EventListeners:
public void addLoginListener(EventListener<LoginEvent> event) { // ...
// OR
public void addLogoutListener(EventListener<LogoutEvent> event) { // ...
Again, at run-time both of those methods deal with raw EventListeners. So by having Foo implement a raw interface the compiler will be happy to let you get away with just a type safety warning (which you can disregard with #SuppressWarnings("unchecked")):
eventSource.addLoginListener(foo); // works
While all of this may seem daunting, just repeat to yourself "The compiler is trying to trick me (or save me); there is no spoon <T>. Once you scratch your head for a couple of months trying to make legacy code written before Java 1.5 work with modern code full of type parameters, type erasure becomes second nature to you.
You need to use inner or anonymous classes. For instance:
class Foo {
public EventListener<X> asXListener() {
return new EventListener<X>() {
// code here can refer to Foo
};
}
public EventListener<Y> asYListener() {
return new EventListener<Y>() {
// code here can refer to Foo
};
}
}
This is not possible.
But for that you could create two different classes that implement EventListener interface with two different arguments.
public class Login implements EventListener<LoginEvent> {
public void onEvent(LoginEvent event) {
// TODO Auto-generated method stub
}
}
public class Logout implements EventListener<LogoutEvent> {
public void onEvent(LogoutEvent event) {
// TODO Auto-generated method stub
}
}
New to WebFlux, reactive, and handlers.
I am able to get a Mono<> from a ServerRequest and process the contained POJO to add a new tuple to a database. But, it seems like there should be a "better" or "more accepted" way to write this code.
Any help/input with the code in AccountRequestHandler would be appreciated, especially with explanations of the rationale behind the recommend change(s).
Router implementation (stripped down to only "POST")...
#Configuration
public class AccountRequestRouter {
#Bean
public RouterFunction<ServerResponse> route(AccountRequestHandler requestHandler) {
return nest(path("/v2"),
nest(accept(APPLICATION_JSON),
.andRoute(RequestPredicates.POST("/accounts"), requestHandler::addAccount)
));
}
}
Handler implementation...
The code where I'm actually doing the add, and then separately creating a ServerResponse, is what I'm focused on. It seems "clunky", especially since AccountService.addAccount() returns a Mono on completion.
#Component
public class AccountRequestHandler {
#Autowired
private mil.navy.ccop.service.accounts.account.AccountService accountService;
public Mono<ServerResponse> addAccount(ServerRequest request) {
return request.bodyToMono(Account.class).flatMap(account -> {
accountService.addAccount(account);
return ServerResponse.ok().build();
})
.switchIfEmpty(ServerResponse.badRequest()
.contentType(APPLICATION_JSON)
.build(Mono.empty()));
}
}
AccountService implementation (again, stripped down)...
#Service
class AccountService {
#Autowired
private AccountRepository accounts;
public AccountService() {
}
public Mono<Void> addAccount(Account account) {
Account proxy;
// make sure that accountId is set to support auto-generation of synthetic key value
proxy = new Account(-1, account.getShortName(), account.getLongName(), account.getDescription());
accounts.save(proxy);
return Mono.empty();
}
}
Appreciating all the help in ramping up on this style of programming....
well first of all, you have 2 addAccount, that can be a bit confusing.
Second of all, what kind of "repository" are you writing too? if its an sql repo you need to properly wrap it in a Mono.fromCallable() otherwise it will block the Reactive thread pool and you can have really bad performance.
Yes there are other ways of doing things. A lot of people tend to do things in flatmap or map and sure it is completely possible to do things here, but for the semantics i'd say it is less good.
map and flatmap are usually used to perform some sort of computation on the inner value of the mono and then return the same or a new value and or type inside the mono.
i would rewrite this like such.
return void here:
public void addAccount(Account account) {
Account proxy;
// make sure that accountId is set to support auto-generation of synthetic key value
proxy = new Account(-1, account.getShortName(), account.getLongName(), account.getDescription());
accounts.save(proxy);
}
And here:
public Mono<ServerResponse> addAccount(ServerRequest request) {
return request.bodyToMono(Account.class)
.doOnSuccess(account -> {
accountService.addAccount(account);
}).then(ServerResponse.ok().build())
.switchIfEmpty(ServerResponse.badRequest()
.contentType(APPLICATION_JSON)
.build());
}
there are a number of different doOn methods that are ment to be used to consume and do "side effects" on things. Like doOnSuccess, doOnError, doOnCancel etc. etc.
you also have then and thenReturn which will just return whatever you put in them. Then returns whatever Mono you put in it. thenReturn wraps whatever value you put into it into a Mono and returns it.
I set up multiple custom controllers during the creation of an app and would need some help in organizing these controllers with setControllerFactory in JavaFX.
I'm fairly inexperienced with JavaFX but invested quite some time in creating a small app with Scenebuilder and JavaFX.
Background of the app
The app consists of:
- a map (implemented as an imageView)
- a sidebar with buttons and icons for drag and drop events.
- the map also has separate layers as the target for the drag and drop of different icon types.
As a prototype of my drag and drop event I used the instructions of Joel Graff (https://monograff76.wordpress.com/2015/02/17/developing-a-drag-and-drop-ui-in-javafx-part-i-skeleton-application/). He writes "in order for an object to be visible beyond a container’s edges, it must be a child of a parent or other ancestral container – it must belong to a higher level of the hierarchy. In the case of our drag-over icon, this means we had to add it as a child to the RootLayout’s top-level AnchorPane." and he uses dynamic roots for his project.
To teach myself how to use custom control with FXML I used Irina Fedortsova's tutorial https://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm.
And to learn how to set up multiple screens I used the video https://www.youtube.com/watch?v=5GsdaZWDcdY and associating code from https://github.com/acaicedo/JFX-MultiScreen.
After building my app the logic tier of my app got more and more entangled with the presentation tier, and I feel as if my code would benefit greatly from some refactoring.
My problem seems to be a lack in the understanding of the load and initialize process of controller classes. Since the drag icons and the RootLayout have to be loaded from the beginning, it is a mystery to me how I can load these classes in a way that I can call them again at a later time.
When I was looking for further solutions, I repeatedly came across the method setControllerFactory. Unfortunately I can't find a good explanation for how to use it properly and what it's specific purpose is.
The only tutorial I found was: https://riptutorial.com/javafx/example/8805/passing-parameters-to-fxml---using-a-controllerfactory, unfortunately it seems to be a bit insufficient for my purpose.
I feel as if I would benefit the most from a methode/class with which I could organize all my custom controllers, load and initialize them at the appropriate time and then later access them again (similar to the interface and superclass in the video for JFX-MultiScreen).
I repeatedly came across the method setControllerFactory. Unfortunately I can't find a good explanation for how to use it properly and what it's specific purpose is
By default, the FXMLLoader.load() method instantiates the controller named in the fxml document using the 0-arg constructor. The FXMLLoader.setControllerFactory method is used when you want your FXMLLoader object to instantiate controllers in a certain way, e.g. use a different controller constructor on specific arguments, call a method on the controller before it's returned, etc, as in
FXMLLoader loader = new FXMLLoader(...);
loader.setControllerFactory(c -> {
return new MyController("foo", "bar");
});
Now when you call loader.load() the controller will be created as above. However, calling the FXMLLoader.setController method on a preexisting controller may be easier.
I feel as if I would benefit the most from a methode/class with which I could organize all my custom controllers, load and initialize them at the appropriate time and then later access them again
When I first came across this problem, as you have, I tried and retried many approaches. What I finally settled on was turning my main application class into a singleton. The singleton pattern is great when you need to create one instance of a class which should be accessible throughout your program. I know there are many people who will take issue with that (in that it's essentially a global variable with added structure), but I've found that it reduced complexity significantly in that I no longer had to manage a somewhat artificial structure of object references going every which way.
The singleton lets controllers communicate with your main application class by calling, for example, MyApp.getSingleton(). Still in the main application class, you can then organize all of your views in a private HashMap and add public add(...), remove(...), and activate(...) methods which can add or remove views from the map or activate a view in the map (i.e. set the scene's root to your new view).
For an application with many views that may be placed in different packages, you can organize their locations with an enum:
public enum View {
LOGIN("login/Login.fxml"),
NEW_USER("register/NewUser.fxml"),
USER_HOME("user/UserHome.fxml"),
ADMIN_HOME("admin/AdminHome.fxml");
public final String location;
View(String location) {
this.location = "/views/" + location;
}
}
Below is an example of the main application class:
public final class MyApp extends Application {
// Singleton
private static MyApp singleton;
public MyApp() { singleton = this; }
public static MyApp getSingleton() { return singleton; }
// Main window
private Stage stage;
private Map<View, Parent> parents = new HashMap<>();
#Override
public void start(Stage primaryStage) {
stage = primaryStage;
stage.setTitle("My App");
add(View.LOGIN);
stage.setScene(new Scene(parents.get(View.LOGIN)));
stage.show();
}
public void add(View view) {
var loader = new FXMLLoader(getClass().getResource(view.location));
try {
Parent root = loader.load();
parents.put(view, root);
} catch (IOException e) { /* Do something */ }
}
public void remove(View view) {
parents.remove(view);
}
public void activate(View view) {
stage.getScene().setRoot(parents.get(view));
}
public void removeAllAndActivate(View view) {
parents.clear();
add(view);
activate(view);
}
}
If you have application-wide resources you can put them in the app class and add getters/setters so your controllers can access them. Here is an example controller class:
public final class Login implements Initializable {
MyApp app = MyApp.getSingleton();
// Some #FXML variables here..
#FXML private void login() {
// Authenticate..
app.removeAllAndActivate(View.USER_HOME);
}
#FXML private void createAccount() {
app.add(View.NEW_USER);
app.activate(View.NEW_USER);
}
#Override
public void initialize(URL url, ResourceBundle rb) {}
}
I have the following AppDelegate which takes quite some time to load:
Syncfusion.ListView.XForms.iOS.SfListViewRenderer.Init();
new Syncfusion.SfNumericUpDown.XForms.iOS.SfNumericUpDownRenderer();
Syncfusion.SfCarousel.XForms.iOS.SfCarouselRenderer.Init();
Syncfusion.XForms.iOS.Buttons.SfSegmentedControlRenderer.Init();
Syncfusion.XForms.iOS.Buttons.SfCheckBoxRenderer.Init();
new Syncfusion.XForms.iOS.ComboBox.SfComboBoxRenderer();
//Syncfusion.XForms.iOS.TabView.SfTabViewRenderer.Init();
new Syncfusion.SfRotator.XForms.iOS.SfRotatorRenderer();
new Syncfusion.SfRating.XForms.iOS.SfRatingRenderer();
new Syncfusion.SfBusyIndicator.XForms.iOS.SfBusyIndicatorRenderer();
What options should I consider when I know some of these components aren't needed for the main screen, but for subscreens?
I am using PRISM, and it appears that every tab is pre-loaded immediately before allowing display or interaction with the end user. What can I do to delay the pre-rendering that the Prism TabView does prior to showing the interface?
Should I use Lazy<T>? What is the right approach?
Should I move these components to another initialization section?
There are a number of ways you could ultimately achieve this, and it all depends on what your real goals are.
If your goal is to ensure that you get to a Xamarin.Forms Page as fast as possible so that you have some sort of activity indicator, that in essence says to the user, "it's ok I haven't frozen, we're just doing some stuff to get ready for you", then you might try creating a "SpashScreen" page where you do additional loading. The setup might look something like the following:
public partial class AppDelegate : FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App(new iOSInitializer()));
return base.FinishedLaunching(app, options);
}
}
}
public class iOSInitializer : IPlatformInitializer, IPlatformFinalizer
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterInstance<IPlatformFinalizer>(this);
}
public void Finalize()
{
new Syncfusion.SfNumericUpDown.XForms.iOS.SfNumericUpDownRenderer();
Syncfusion.SfCarousel.XForms.iOS.SfCarouselRenderer.Init();
Syncfusion.XForms.iOS.Buttons.SfSegmentedControlRenderer.Init();
Syncfusion.XForms.iOS.Buttons.SfCheckBoxRenderer.Init();
}
}
public class App : PrismApplication
{
protected override async void OnInitialized()
{
await NavigationService.NavigateAsync("SplashScreen");
}
}
public class SplashScreenViewModel : INavigationAware
{
private IPlatformFinalizer _platformFinalizer { get; }
private INavigationService _navigationService { get; }
public SplashScreenViewModel(INavigationService navigationService, IPlatformFinalizer platformFinalizer)
{
_navigationService = navigationService;
_platformFinalizer = platformFinalizer;
}
public async void OnNavigatedTo(INavigationParameters navigationParameters)
{
_platformFinalizer.Finalize();
await _navigationService.NavigateAsync("/MainPage");
}
}
If you're working with Modules you could take a similar approach though any Modules that would initialize at Startup would still be making that call to Init the renderers before you've set a Page to navigate to. That said, working with Modules does give you a number of benefits here as you only ever would have to initialize things that the app actually requires at that point.
All of that said I'd be surprised if you see much in the way of gain as these Init calls are typically empty methods only designed to prevent the Linker from linking them out... if you aren't linking or have a linker file you could simply instruct the Linker to leave your Syncfusion and other libraries alone.
i want to make a layout that be visible on mouse over and hide automatically on mouse out. i try this code but it not give me any result;
public class DemoLayout extends VerticalLayout implements MouseOverHandler,
MouseOutHandler,MouseUpHandler {
/**
*
*/
private static final long serialVersionUID = 7610044813670041530L;
public DemoLayout() {
super();
}
#Override
public void onMouseOver(MouseOverEvent event) {
// TODO Auto-generated method stub
System.out.println("Mouse over");
}
#Override
public void onMouseOut(MouseOutEvent event) {
// TODO Auto-generated method stub
System.out.println("Mouse out");
}
#Override
public void onMouseUp(MouseUpEvent event) {
// TODO Auto-generated method stub
System.out.println("Mouse up");
}
}
vaadin doesn't support layout mouse listener?
how can i implement this feature?
thank you
I may be wrong, but I don't know of such listeners for layouts up to Vaadin 7.4.3. The good news is that you have at least a few options:
the handlers you're implementing are from com.google.gwt.event.dom.client package which is bundled in the vaadin-client jar. You're, probably unintentionally, mixing client-side & server-side classes which is most likely not what you're after. However you can try to create your own widget and implement those handlers on the client side as suggested here and/or here
you may be able use the CSS :hover pseudo-class to some degree as discussed here
(perhaps the simplest) you could achieve a similar effect with a click. Take a look at the SliderPanel add-on to avoid re-inventing the wheel
You have two options:
Depending on your exact use case, you could probably just use CSS and the :hover pseudo class.
If :hover doesn't work then you could use the excellent Mouse Event Extension addon.