Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Look-and-feel-decorated JFrames do not render properly #47

Closed
Chrriis opened this issue Jan 15, 2020 · 24 comments · Fixed by #108
Closed

Look-and-feel-decorated JFrames do not render properly #47

Chrriis opened this issue Jan 15, 2020 · 24 comments · Fixed by #108
Labels
enhancement New feature or request
Milestone

Comments

@Chrriis
Copy link
Contributor

Chrriis commented Jan 15, 2020

(split from issue #39)

Modern applications that use flat widgets may want their frame decorations also to be flat.

Here is a test case of the current situation:

	public static void main(String[] args) throws Exception {
		UIManager.setLookAndFeel(new FlatLightLaf());
		JFrame frame = new JFrame("JFrame");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setUndecorated(true);
		frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
		JDesktopPane desktopPane = new JDesktopPane();
		JInternalFrame internalFrame1 = new JInternalFrame("JInternalFrame1", true, true, true, true);
		internalFrame1.setLocation(50, 30);
		internalFrame1.setSize(300, 200);
		desktopPane.add(internalFrame1);
		JInternalFrame internalFrame2 = new JInternalFrame("JInternalFrame2", true, true, true, true);
		internalFrame2.setLocation(60, 40);
		internalFrame2.setSize(300, 200);
		desktopPane.add(internalFrame2);
		frame.getContentPane().add(desktopPane);
		frame.setSize(400, 300);
		frame.setVisible(true);
		internalFrame1.setVisible(true);
		internalFrame2.setVisible(true);
		internalFrame2.setIcon(true);
	}

... and here is the result:
FrameDecorations

@DevCharly said:
Window decoration style looks similar to internal frames, but it seems that the implementation has nothing to do with internal frames. It is implemented in javax.swing.plaf.metal.MetalRootPaneUIand javax.swing.plaf.metal.MetalTitlePane.

@DevCharly DevCharly added the enhancement New feature or request label Jan 15, 2020
DevCharly added a commit that referenced this issue Feb 18, 2020
(preparation for replacing "base" Metal LaF with BasicLookAndFeel)
@Poivin
Copy link

Poivin commented Mar 19, 2020

I agree, it would be very interesting to have a "flatLAF" decoration on Jframes and Jdialogs in order to give the possibility to completely open the title bars implementation through UIs for customisation and through Overriding for specific features. @DevCharly Is it in FlatLAF roadMap ? Thanks for all your work!

@Chrriis
Copy link
Contributor Author

Chrriis commented May 5, 2020

I thought having a L&F decorated frame was secondary, but in fact the default title bar totally ruins the dark mode experience. Here is a screenshot of a sample app:
Dark App

On a real app which fills the full screen, I keep seeing the light title bar because it stands out compared to the rest in dark.

It is a pity that the work done for internal frame cannot be reused easily because I believe it would do the job.

@DevCharly
Copy link
Collaborator

It is a pity that the work done for internal frame cannot be reused easily because I believe it would do the job.

Yes, but only on Windows. Would look bad on macOS and Linux.

@Chrriis
Copy link
Contributor Author

Chrriis commented May 7, 2020

Would look bad on macOS and Linux.

Why? Are you implying that internal frames feel already out of place on Linux and MacOS having this "window-esque" look?

For me, an application can opt to use the native title bars or provide its own. If a specific look and feel is picked, an application should have the right to get the frame title bars matching this look and feel.

Checking behavior of various applications on Windows:
AppsCustomTitlebars

Are you saying that on Linux and MacOS no application has custom titlebars?

@smileatom
Copy link

smileatom commented May 7, 2020

I think whats hes saying is that window decorations are controlled by the OS. All of the above examples you provided are customizations of the WinOS "Window Decorations", they ARE OS native decorations which are beyond the scope of Swing as they are merely containers.

Just like you can't without some work on linux or MacOS provide fancy native looking extensions of the native window decorations, this is application specific behavior based on intimate knowledge of the OS window decor.

I personally see no need for a cross platform L&F to provide that function. But to each his own.

As a simple example if you tried to use an OS native tool like Visual Basic to reproduce these you would have to "do it yourself".

Implement Chrome browser tabs yourself. It takes work in any language on any platform. The OS doesnt provide that. Nor does the L&F.

@Chrriis
Copy link
Contributor Author

Chrriis commented May 7, 2020

@smileatom there is no need to customize native OS decorations! Swing supports hiding the native decorations and asking the look and feel to paint its own using pure Swing code, provided the look and feel implemented it (like internal frames do).

This is controlled using:

frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

@smileatom
Copy link

smileatom commented May 7, 2020

@smileatom there is no need to customize native OS decorations! Swing supports hiding the native decorations and asking the look and feel to paint its own using pure Swing code, provided the look and feel implemented it (like internal frames do).

This is controlled using:

frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

Yes and by turning off those decorations you are in an "owner drawn" problem, which has nothing to do with Swing L&Fs of any sort. If you want to draw your own, write a L&F supporting it.

Again, just try to implement Chrome tabs that look like they do on any platform. I have. These examples that blend into window decorations is not the role of any java L&F.

@Chrriis
Copy link
Contributor Author

Chrriis commented May 7, 2020

@smileatom I am not sure I understand. You are saying that to have the title bar follow the look and feel I have to write my own look and feel? Well, same argument goes for internal frames then because they have frame decorations too.

In any case, as per Swing API: https://docs.oracle.com/javase/9/docs/api/javax/swing/JRootPane.html#setWindowDecorationStyle-int-

"Sets the type of Window decorations (such as borders, widgets for closing a Window, title ...) the JRootPane should provide."
This page also says: "This is only a hint, and some look and feels may not support this.", but a professional looking look and feel ought to support it 😃

@smileatom
Copy link

Im sorry Chris, but your thinking wishfully. Replacing OS native window decorations is a mega-fail and a waste of time.

@smileatom
Copy link

If you want a custom windows App, draw it yourself.

@Chrriis
Copy link
Contributor Author

Chrriis commented May 7, 2020

Substance look and feels seem to do it looking at the screenshots (scroll down the page):
https://github.com/kirill-grouchnikov/radiance

@smileatom
Copy link

I have done it myself. Your missing the point dude. Does frame.setUndecorated() belong to a class of L&F in Java? No it doesnt. It belongs to UserLand Swing. Check the package.
You want custom decorations, menus and shadows god knows what else, I could spend my whole life on that. Its not what a L&F does.

Im not the owner of this project, so if @DevCharly wants to engage in this nonsense its up to him. And Im not being rude, this is simply not the scope of java L&F, if you like Substance so much USE IT!.

And every time MS or Apple, or any of 10 flavors of linux changes its windows decorations or a new app does some native thing abusing title bars, you'll file a bug on this project because you, YOU dont understand the scope.

@smileatom
Copy link

Maybe youd like a little "iMovie"?
Screen Shot 2020-05-07 at 4 36 13 AM

Or a little black title bar?

Screen Shot 2020-05-07 at 4 33 10 AM

or a little classic mac?

Screen Shot 2020-05-07 at 4 34 55 AM

or a little iOS feel?

Screen Shot 2020-05-07 at 4 33 32 AM

All these can be easily had by drawing your own decorations on any platform.
Ill let you have any one of these for the deep discount of 10K each,

@smileatom
Copy link

All written in Java using no L&F and no window decorations. Its EASY!

@smileatom
Copy link

I believe what this project is about is creating a cross platform look and feel. Thats what I believe.

@Chrriis
Copy link
Contributor Author

Chrriis commented May 7, 2020

@smileatom you are missing the point: the application developer should have the ability to opt for the system title bar (default) or the look-and-feel provided title bar (that is a similar bar than the internal frames, in accordance to the theme that is currently loaded). That is what the Swing APIs provide, and professional look and feel actually implement it. Of course, if I wanted a custom title bar I would implement it, but this is not what we are talking about here.

@smileatom
Copy link

It actually is the actual point. Once you set frame to undecorated, you are assuming responsibility for not just drawing the title bar but much more than that. Java L&F can do that but it's beyond the design scope. A "cross platform" look and feel, should actually work beyond whatever the OS decorations pre-ordain and look acceptable. But even a great cross platform L&F cannot build custom applications that paint on the OS decorations. And thats what you are asking for.

A good L&F should not deal with OS decorations and functionality its beyond the scope of an L&F.
After all if the OS was so important you could use any number of platform specific tools to do that.

@smileatom
Copy link

This was actually a big, no huge bone of contention when Swing was invented by SUN. There were two camps, one said, Swing L&F should own everything, and the other camp said it should still use native window decorations. The big reason was OSes change window decorations all the time and they control window sizing and window controls that tie into OS task managers.

Building a cross platform thing means you are in a container. And being in a container means certain things are off limits. If you really went that direction your app would fail in so many horrible ways and you would end up rewriting everything every time an OS released a new version.

Building a nice cross platform GUI (which java hasnt had in years) that looks good and works on 3 platforms is a great thing. It doesnt need to go back in time and revisit these arguments about keeping up with the joneses. Look at intellij. Many programmers dont even know its written in Java or care.

Its not violating any sacred boundaries of UX in developer IDEs, we all love it. If Swing merely did that we would all be happy.

But if you really want to do your own thing, setUndecorated() and rock on, the rest of the OS specific problems you run into will be on you. It has nothing to do with an L&F implementation.

@smileatom
Copy link

smileatom commented May 7, 2020

Just to give you an idea of how bad that would be, "owner drawing" the container. In the above screen shots that appear as OSX would. The stoplights have changed many times since the 6 years ago I wrote that, how would I support just the stoplights, wrong color now, different distance in the window, that have changed 20 times since 2014? The title bar text is sometimes flush to top, sometimes vertically centered depending on how apple thought that day. Hmm, my UI would look dumb. And I put all that work into it. Waste o time. Also wheres the "fullscreen button"? What versions of OSX even support that? Dont we all have better things to think about?

@DevCharly
Copy link
Collaborator

**Chrriis wrote:

Are you implying that internal frames feel already out of place on Linux and MacOS having this "window-esque" look?

No, internal frames are within the application window. There you can do what you want and users (probably) accept it 😉

Having a Windows 10 style application window on Mac is a different story. The three (min,max,close) buttons are on different sides, have different order and a complete different look. Don't think that Mac users would like that...

Anyway, I currently see (at least) two main reasons to implement custom window decorations for Windows 10 (and Linux?):

  1. to have a dark title area
  2. move the menu bar into the title area

This is what IntelliJ IDEA does on Windows:

image

They paint the whole title area with Swing components, but on the other hand the Windows 10 snapping works the same way as in native applications. Don't yet know how they do this. Have to debug IDEA...

On macOS this is probably not necessary because:

  1. macOS makes the title area of Java apps dark if dark appearance is chosen in system preferences (on Mojave)
  2. menu bar is on top of screen on macOS

When using JetBrains Java Runtime, it is even possible to force dark (or light) window title by setting a client property on the root pane (on Mojave):

rootPane.putClientProperty("jetbrains.awt.windowDarkAppearance",true);
or
rootPane.putClientProperty("jetbrains.awt.windowLightAppearance",true);

This is what IntelliJ IDEA uses on macOS.

@smileatom whether such custom window decorations should be implemented in core FlatLaf or elsewhere is a different story. But I think it would be good to have something easy to use under the Flatlaf "umbrella". Maybe in a subproject. At least for Windows 10. There is demand for dark frame titles on Windows. I have been asked several times for this feature.

@Chrriis
Copy link
Contributor Author

Chrriis commented May 10, 2020

Maybe I misunderstand, but you say that macOS is different than Windows about the dartk/light. Well in Windows, the title bar behaves the same. You could end up with a light bar on a dark theme and vice versa on both OS.

In any case, I like a lot the idea of the menu bar and the title bar merged, but I don't know how hard that is to implement.
If you allow customizing the title bar and set window decorated to false, there needs to be at least a special border in place for the frame to be able to resize it. I guess this means that depending on a property like "titleBar.merged" = TRUE/FALSE, the rootpane would have or not a title bar, but would add the borders.

@smileatom
Copy link

smileatom commented May 11, 2020

If I remember correctly, if you set undecorated to false you also have to deal with title bar dragging and window sizing yourself. Just FYI in case you go in that direction. Also when you lose the window borders you will also lose any OS specific shading or drop shadows below the window and will have to draw them yourself. Focus will also have to be handled in the case of self drawn title bars if I remember correctly. Min max and hide buttons will need to be drawn with respect to their os and the behavior will need to be implemented per OS.

@Chrriis
Copy link
Contributor Author

Chrriis commented May 11, 2020

For completeness on merging title bars, here is what some angry users had to say:

DevCharly added a commit that referenced this issue May 27, 2020
#82)

TODO
- move window
- resize window
- window icon
- window border
DevCharly added a commit that referenced this issue May 28, 2020
DevCharly added a commit that referenced this issue May 29, 2020
DevCharly added a commit that referenced this issue May 29, 2020
DevCharly added a commit that referenced this issue May 31, 2020
DevCharly added a commit that referenced this issue May 31, 2020
JFormDesigner pushed a commit that referenced this issue Jun 6, 2020
@DevCharly DevCharly linked a pull request Jun 24, 2020 that will close this issue
@DevCharly DevCharly added this to the 0.37 milestone Jun 29, 2020
@DevCharly
Copy link
Collaborator

this is now released in FlatLaf 0.37

Unfortunately it was necessary to implement it in core JAR (instead of an additional JAR) to integrate it with FlatLaf.getSupportsWindowDecorations() and FlatRootPaneUI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants