JFormDesigner / FlatLaf

FlatLaf - Swing Look and Feel (with Darcula/IntelliJ themes support)
https://www.formdev.com/flatlaf/
Apache License 2.0
3.18k stars 258 forks source link

Doesn't work with IBM (Eclipse OpenJ9) Java #851

Open MerlinUKRhapsody opened 2 weeks ago

MerlinUKRhapsody commented 2 weeks ago

Loving this project but if anyone has any ideas how to solve this I'd really appreciate it !

If i run my app from Eclipse it works but if I build my app as a JAR file (and that isnt executable - it gets loaded by another Windows application that supports 'plugins') - it doesnt work - the app works but the layout is all screwed up - for example:

This is what the app looks like when run from Eclipse:

image

This is the same app when launched from the Windows application that loads it as a plugin:

image

I tried extracting the dlls in case that was the issue - but it didnt help (RhapsodyPowerpackPlugin.jar is the app that the Windows application loads) - if there are other required libraries like (for example MigLayout) those work fine so its something specific to FlatLaf

image

This is the ANT Script that builds it:

DevCharly commented 2 weeks ago

Looks like a layout problem, not like a FlatLaf problem, because the look is equal in both screenshots...

What happens if you resize the window in the second screenshot? Do you have the same problem with other Laf? E.g. Metal or Windows Laf?

MerlinUKRhapsody commented 2 weeks ago

Yeah I tried resizing - it doesnt change anything It works fine with Nimbus / Metal:

image image
DevCharly commented 2 weeks ago

Are there any exceptions?

MerlinUKRhapsody commented 2 weeks ago

Sadly not no - I can connect to the windows app using a remote java application config and no exceptions are thrown - thats whats so frustrating !

remcopoelstra commented 2 weeks ago

Just a guess, but it might have something to do with the (native) window decorations, it looks like both the host application and the plugin are trying to manipulate the title-bar, the app-icon is also rotated compared to the other screenshots and the options menu is missing. Maybe you could give it a try without the window decorations.

MerlinUKRhapsody commented 2 weeks ago

The host application doesnt try to manipulate the plugin in any way. Weird about the icon being rotated - Metal / Nimbus didn't rotate it and FlatLaf has also stopped rotating it now. I removed the icon and the menu anyway just to test it but it had no effect. I also reduced the data set it works on to try and figure out of its a specific component that is causing it to choke

JTextFields seem to be an issue so i removed the formatting from them but it didn't stop the issue:

image
remcopoelstra commented 2 weeks ago

I think in your last screenshots FlatLaf is still probably trying to control the layout/style of the title bar (default behavior), i would try disabling the native window decorations of FlatLaf, I am not sure exactly whats the recommended way in the latest version, but you could try adding these lines immediately after your code where you set the FlatLaf look and feel:

System.setProperty(FlatSystemProperties.USE_WINDOW_DECORATIONS, "false");
JFrame.setDefaultLookAndFeelDecorated(false);
JDialog.setDefaultLookAndFeelDecorated(false);
remcopoelstra commented 2 weeks ago

And maybe also add:

System.setProperty(FlatSystemProperties.USE_NATIVE_LIBRARY, "false");
MerlinUKRhapsody commented 2 weeks ago

Well I do want the theme applied to the title bar - - but I applied your suggestion anyway to test:

image
remcopoelstra commented 2 weeks ago

Then I also have no idea whats going on.. But you can probably rule out now that it has to do with window decorations and turn them back on.

Maybe you can find some way of debugging your plugin, if you can add logging to your code, for example printing the bounds of your components after layout is performed, it might help you to pinpoint the exact location in your code where things start to go wrong compared to the other look and feels.

MerlinUKRhapsody commented 2 weeks ago

Well I zeroed in on it - I still havent figured out why this is an issue but ..

     SwingUtilities.invokeLater( () ->
     {
     buildGui();
     } );

This caused the issue (the first tjhing buildGui does is set the look and feel. Changing it to simply:

buildGui();

fixed it

remcopoelstra commented 2 weeks ago

If the host application is also eclipse based it might be interesting to search for info about mixing swt and swing (awt).

Your buildGui(); call should normally be done on the event dispatch thread like you did in your original code.

MerlinUKRhapsody commented 2 weeks ago

The original application is a C++ based app and this is the first time applying any kind of LAF has caused this issue. Thanks for all the replies so far guys !

MerlinUKRhapsody commented 1 week ago

I did some more testing on this and pared it right back to basics - coloring the windows app title bar - something that Nimbus cannot do and FlatLaf can. When run as a plugin - it fails to apply the color, as an external app it succeeds. This leads me to the conclusion that it is indeed the required natives causing the issue - but I'm struggling to work around it. I've opened a ticket with the makers of the C++ app but I've also tried: Putting the three windows based dlls into the folder as the JAR Copying them to the Windows folder Adding them to the built JAR itself using the Ant script that builds it Lastly I tried debugging the source code - I added breakpoints and was able to track the progress successfully when run as an external app. When run as a plugin it gets as far as UIManager.setLookAndFeel:

image

I can step into that:

image

But thats all - the next step takes me to comments - so its lost track of where we are in the code.

I added. breakpoints and it never gets as far as these:

image image
MerlinUKRhapsody commented 1 week ago

OK so sleep is overrated anyway ! I found that the application embedding the plugin uses IBM Java:

java version "17.0.7" 2023-04-18 IBM Semeru Runtime Certified Edition 17.0.7.0 (build 17.0.7+7) Eclipse OpenJ9 VM 17.0.7.0 (build openj9-0.38.0, JRE 17 Windows 11 amd64-64-Bit Compressed References 20230418_403 (JIT enabled, AOT enabled) OpenJ9 - d57d05932 OMR - 855813495 JCL - 7a1e0864e99 based on jdk-17.0.7+7)

Thats the core issue - if I switch to another Java like Oracle 22 then everything works as expected .. almost

The remaining issue is I still cant run it on the EDT This works:

image

But if I change it to this:

image

Then I get an UnsupportedLookAndFeelException:

image

I also tried creating and registering the themes before calling the routine that creates the GUI but got the same result:

image

The first thing 'Themes' does is register the themes and then apply the appropriate one:

image
DevCharly commented 3 days ago

I did some more testing on this and pared it right back to basics - coloring the windows app title bar - something that Nimbus cannot do and FlatLaf can. When run as a plugin - it fails to apply the color, as an external app it succeeds. This leads me to the conclusion that it is indeed the required natives causing the issue - but I'm struggling to work around it.

If FlatLaf fails to load a native library it outputs a log (using java.util.logging.Logger). You could check in the debugger whether loading is successful:

https://github.com/JFormDesigner/FlatLaf/blob/72a4c00e72a33aef3b4ea6b8f1986afaa266d2d9/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeLibrary.java#L109-L111

java version "17.0.7" 2023-04-18 IBM Semeru Runtime Certified Edition 17.0.7.0 (build 17.0.7+7) Eclipse OpenJ9 VM 17.0.7.0 (build openj9-0.38.0, JRE 17 Windows 11 amd64-64-Bit Compressed References 20230418_403 (JIT enabled, AOT enabled) OpenJ9 - d57d05932 OMR - 855813495 JCL - 7a1e0864e99 based on jdk-17.0.7+7)

Thats the core issue - if I switch to another Java like Oracle 22 then everything works as expected .. almost

Strange, tried FlatLaf Demo with OpenJ9 17 and it works without problems 😕

Then I get an UnsupportedLookAndFeelException:

image

Why are you using UIManager.createLookAndFeel()?

Better use FlatLightLaf.setup() or UIManager.setLookAndFeel( new FlatLightLaf() ).

I've no idea what's going wrong when running on EDT... Have you tried to setup L&F on current thread and then create UI on EDT?

MerlinUKRhapsody commented 3 days ago

Thanks for the comments ! Yes if I setup LAF on the current thread and then build the ui on the EDT i get the same result. I did get a logger error though:

image

UnitLogger.log

Even if I avoid using the EDT in my code i get weird results that i have to work around - for example this is a JOptionPane when run as an external java app:

image

The same thing when run as a plugin (with IBM Java so the theme doesnt get applied to the title bar) image The same thing with Oracle java - the theme is applied but the question is still missing: image

Of course these issues (another one includes the tooltips not appearing if FlatLaf is used) could be down to the fact that I'm not building the UI on the EDT because it all fails if I do. For this issue I have to temporarily apply Nimbus before asking the question and then re-apply FlatLaf afterwards. In these cases no exceptions are in the log.

I'm not using UIManager.setLookAndFeel by default - I'm using the recommended subclassing approach:

private static void applyRhapsody10Basic()
    {
        if ( isIBMJava )
        {
            try
            {
                Rhapsody10BasicIBM.setup();
                updateComponentTreeUI();
                useDarkIcons = true;
                useDarkTitleBarIcon = true;
            } catch ( Exception e )
            {
                applyNimbus();
            }
        }
        else
        {
            try
            {
                Rhapsody10Basic.setup();
                updateComponentTreeUI();
                useDarkIcons = true;
                useDarkTitleBarIcon = false;
            } catch ( Exception e )
            {
                applyNimbus();
            }
        }

    }
public class Rhapsody10Basic extends FlatLightLaf
{

    public static boolean setup()
    {
        return setup( new Rhapsody10Basic() );
    }

    @Override
    public String getName()
    {
        return "Rhapsody 10 Basic";
    }

}

I love FlatLaf - but I dont have the luxury of running it as an external java app or enforcing the version of java being used - these are plugins for IBM Rhapsody which ships its own Semeru java - while that can be changed by users - few will do it due to company policy restrictions etc.