Open IAmBaguette opened 2 months ago
This is also a problem with JComboBoxes withing JTables, not just MenuBars.
2 monitors, 144hz both, RTX 3050 GPU, Windows 11 Education 23H2
I'm seeing the same problem with a JComboBox in the FlatLaf demo app.
https://github.com/user-attachments/assets/85841646-1b54-45ce-ae21-915554a6ffe1
However, I am unable to replicate the issue with JComboBoxes within a JTable when using the demo app. @nevemlaci Are you able to reproduce the same issue using the demo app for the JComboBoxes within a JTable?
I'd love to but the demo app is impossible to navigate for me due to the repaint issues, 2 clicks and the whole thing just breaks down. I'm not sure where to look for a JTable + JComboBox in the demo app either, I've never used it.
Some of the users of our software which uses FlatLAF 3.5.1 are also reporting this issue
Had the same issue on windows after some update
System.setProperty("sun.java2d.noddraw", "true");
fixed this for me.
@nevemlaci
I'd love to but the demo app is impossible to navigate for me due to the repaint issues, 2 clicks and the whole thing just breaks down. I'm not sure where to look for a JTable + JComboBox in the demo app either, I've never used it.
The JTable is located under the Data components tab in the demo app.
Had the same issue on windows after some update
System.setProperty("sun.java2d.noddraw", "true");
fixed this for me.
I'm no longer seeing the issue with the demo app or the minimal reproduction project. It also addressed my problem of the menu not being integrated into the title bar using my initial solution. Thank you @norbert-gaulia!
Note, turning off DirectDraw disables hardware acceleration, which will reduce performance, especially in graphics-intensive applications. While this isn’t a problem for me at the moment, I suspect this may not be a solution for everyone.
@nevemlaci
I'd love to but the demo app is impossible to navigate for me due to the repaint issues, 2 clicks and the whole thing just breaks down. I'm not sure where to look for a JTable + JComboBox in the demo app either, I've never used it.
The JTable is located under the Data components tab in the demo app.
I'll take a look today.
@IAmBaguette thanks for the detailed report and the screencasts. Very useful 👍
Unfortunately I can not reproduce the issue on my systems...
What happens if you use the flag -Dflatlaf.useWindowDecorations=false
? (with DirectDraw enabled)
This flag disables the FlatLaf window decorations, but keeps the rounded popup border enabled.
Since you wrote that it first occurs with FlatLaf 3.1, I assume that it has something to do with the (native) rounded popup borders, which are the only change in native code in this version.
Does it work if you disable rounded popup borders with:
UIManager.put( "PopupMenu.borderCornerRadius", 0 );
UIManager.put( "ComboBox.borderCornerRadius", 0 );
UIManager.put( "ToolTip.borderCornerRadius", 0 );
UIManager.put( "Popup.borderCornerRadius", 0 );
@DevCharly Disabling the FlatLaf window decorations while DirectDraw is enabled results to the same issue with the Minimal reproduction project (MRP).
-Dflatlaf.useWindowDecorations=false -Dsun.java2d.noddraw=false
Disabling the rounded popup borders using the UIManager
did resolve the issue. Do you have any idea why the native rounded popup borders would cause this painting issue?
I also attempted to turn off hardware acceleration from my Windows display graphics settings to see if it would make a difference, but the option does not seem to be available with my AMD graphics card.
If there's anything else you'd like me to try, let me know.
I think that following lines, which are invoked before setting rounded popup border, could cause the problem:
addNotify()
creates the native window and also invokes some DirectDraw code.
I'll rework the code to avoid invocation of addNotify()
.
Hope this will solve the issue.
Could you please try latest 3.5.2-SNAPSHOT
: https://github.com/JFormDesigner/FlatLaf#snapshots
Hope this change fixes the problem...
No luck. Issue is still present.
It could be a general Swing issue with "heavy-weight" popup windows, which are used if the popup does not fit into the owner window. If the popup fits into the owner window, FlatLaf 3.0 (and most other L&Fs) use "light-weight" popups (simple Swing component). But FlatLaf 3.1 always uses "heavy-weight" popups on Windows 11 to show Windows rounded borders and drop shadows.
Here is an issue that reports same redraw issue for Windows L&F: https://github.com/kaikramer/keystore-explorer/issues/497
Here is a test case that uses Windows L&F and large menus. Could you try this out and report whether is shows same redraw issue?
import javax.swing.*;
public class HeavyWeightPopupsTest {
public static void main( String[] args ) {
try {
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
} catch( Exception ex ) {
ex.printStackTrace();
}
JFrame frame = new JFrame( "HeavyWeightPopupsTest" );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JMenu fileMenu = new JMenu( "File" );
JMenu editMenu = new JMenu( "Edit" );
for( int i = 1; i <= 20; i++ )
fileMenu.add( "Item " + 1 );
for( int i = 1; i <= 20; i++ )
editMenu.add( "Item " + 1 );
JMenuBar menuBar = new JMenuBar();
menuBar.add( fileMenu );
menuBar.add( editMenu );
frame.setJMenuBar( menuBar );
JTable table = new JTable( 100, 5 );
frame.getContentPane().add( new JScrollPane( table ) );
frame.setSize( 400, 300 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}
There doesn't appear to be any redraw issue on Windows 11.
https://github.com/user-attachments/assets/49bfef07-9c58-4c16-81c8-277a3657945d
There are no redraw issue with FlatLaf either. Tested with versions 3.5.1
and 3.5.2-SNAPSHOT
.
https://github.com/user-attachments/assets/9bdee9cc-8185-40df-966a-fe7824ecfff5
However, the issue reappears with FlatLaf when the JMenu
contains 6 or fewer menu items. Tested with versions 3.5.1
and 3.5.2-SNAPSHOT
. The system LAF remained unaffected.
https://github.com/user-attachments/assets/8d44a06f-fc17-4da2-82cf-d08469248aa5
I was able to reproduce the redraw issue using the system LAF with two JComboBox
components. The issue appears to heavily depend on the layout and constraints. I noticed that in some cases, if the layout was near the bottom of the window (causing the popup to open outside the window), the redraw issue would appear. However, this was not the case when using a GridLayout
, the redraw issue did not appear for either the system LAF or FlatLaf. When I tested the same layout with FlatLaf, the redraw issue did not appear, but it reappeared if the number of items within the combo box was 7 or fewer (with the exception of GridLayout
).
If you need more details about when the redraw issue appears with specific layouts, I will need to conduct a more thorough investigation to compile a comprehensive list.
Let me know what you would like me to do.
@IAmBaguette thanks for testing and confirming that this is can also happen in other L&Fs. So it is actually not a FlatLaf bug.
Not sure whether it makes sense to try layouts...
Found an undocumented Java system property that disables parts of DirectX.
Please try option -Dsun.java2d.d3d.onscreen=false
I was unable to reproduce the redraw issue with -Dsun.java2d.d3d.onscreen=false
in any of the apps: FlatLaf demo, MRP, or heavy-weight popups.
It does appear the issue originates from Java rather than FlatLaf. Both -Dsun.java2d.noddraw=false
and -Dsun.java2d.d3d.onscreen=false
appear to be viable solutions for users who are encountering the same redraw issue with Swing.
I’m not sure if you plan to continue pursuing this. The question is whether it’s worth the effort now that there are workarounds for this Java-related issue.
@DevCharly Thank you for your help, I really appreciate it!
Great that sun.java2d.d3d.onscreen=false
fixes the issue.
Compared to sun.java2d.d3d=false
(same as sun.java2d.noddraw=true
), sun.java2d.d3d.onscreen=false
has the advantage that only a part of Java's Direct3D usage is disabled. Component rendering (via class Graphics
) still uses Direct3D. So hope that performance does not change much...
BTW IntelliJ IDEA has disabled Direct3D (since 13 years). See <idea-install>/bin/idea.properties
. Also NetBeans has it disabled...
Too avoid/fix the redraw issue, I'm going to set sun.java2d.d3d.onscreen=false
in FlatLaf 3.5.2.
@IAmBaguette you mentioned in this comment https://github.com/JFormDesigner/FlatLaf/issues/887#issuecomment-2409099659 that the redraw issue appears only if the menu contains 6 or fewer menu items. There is some code in method sun.java2d.d3d.D3DScreenUpdateManager.canUseD3DOnScreen()
that checks whether (popup) window is smaller that 150x150 pixels and then uses different screen surfaces. GDI surface if smaller then 150x150, otherwise D3D surface. In your video the size of the popup is 83x140. So maybe the redraw problem is related to that 150x150 size check.
Could you please try following test case? (without using any -D...
flags!)
It has 3 menus that show (empty) popups of size 152x152, 151x151 and 150x150.
First click the 152x152 menu to show the popup, click it again to hide it.
Then try the same with the 151x151 and 150x150 menus.
If my theory is correct, then the redraw problem should start after the 150x150 popup is shown.
In this case it would be great if you could post a screencast.
I'd like to report the problem to Oracle and having a test case would be great.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class GhostingTest
{
public static void main( String[] args ) {
JFrame frame = new JFrame( "GhostingTest" );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
UIManager.put( "PopupMenu.border", BorderFactory.createEmptyBorder() );
// force heavy-weight popups
JPopupMenu.setDefaultLightWeightPopupEnabled( false );
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar( menuBar );
// showing this popups should not start ghosting
menuBar.add( createMenuOfSize( 152 ) );
menuBar.add( createMenuOfSize( 151 ) );
// showing this popup should start ghosting
menuBar.add( createMenuOfSize( 150 ) );
JTable table = new JTable( 100, 5 );
frame.getContentPane().add( new JScrollPane( table ) );
frame.setSize( 400, 300 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
private static JMenu createMenuOfSize( int size ) {
JPanel p = new JPanel();
p.setPreferredSize( new Dimension( size, size ) );
p.setBorder( new LineBorder( Color.red ) );
JMenu menu = new JMenu( size + " x " + size );
menu.add( p );
return menu;
}
}
@DevCharly I was able to reproduce the redraw issue inconsistently when following your exact instructions. To consistently trigger the redraw issue, I needed to repeat the action of showing and hiding the 150x150 menu exactly twice.
Here's an example where the redraw issue does not appear with a single action of showing and hiding.
https://github.com/user-attachments/assets/85ecc180-62e7-4f6f-a297-c458703b4457
Here's an example using the same sequence of actions in reverse order.
https://github.com/user-attachments/assets/fb28229d-272e-4f24-8e23-9d26f2ffda5c
Here's an example where the redraw issue appears with a single action of showing and hiding.
https://github.com/user-attachments/assets/2786e07b-05d7-4b03-926d-8969a8324622
Here’s an example where the redraw issue appears after repeating the action of showing and hiding exactly twice. Note that the outcome is the same regardless of whether the other menus were shown/hidden once or twice before the 150x150 menu. I decided to keep the actions consistent for all menus.
https://github.com/user-attachments/assets/fedf8d3b-503d-4f06-bade-eaac01ebdf62
Here's an example using is the same sequence of actions in reverse order. Note that after performing the action of showing and hiding exactly twice for the 152x152 menu, it “erases” the content pane. This behavior is inconsistent. In some tests, this occurred with both the 152x152 and 151x151 menus, while in others, it did not occur at all.
https://github.com/user-attachments/assets/17329984-203c-4f69-9c58-ac4b403e79e2
I've provided more screencasts than you asked to provide a more complete view of what's happening. I prefer to give you more information so that you can decide whether it is necessary for your report to Oracle.
@DevCharly Would you like me to close issue now that the issue is resolved?
Issue Description
I'm experiencing a repaint issue with FlatLaf 3.5.1 on Windows 11. My setup includes an AMD graphics card (RX 6700 XT) with three monitors (1920 x 1080, 120Hz). The issue occurs when using a
JFrame
with aJMenuBar
. Notably, the same project does not exhibit the issue on Windows 10 with an Intel integrated graphics card.Details:
https://github.com/user-attachments/assets/9c2bcdc7-94ac-4856-bcb1-090b2b971867
Observations:
flatlaf.uiScale
property to2x
appears to resolve the issue, but any smaller scale does not.-Dflatlaf.useNativeLibrary=false
flag resolves the issue but removes the menu bar and title bar integration, which I would like to keep.JFrame
window to another monitor forces a full repaint.Steps to reproduce
https://github.com/user-attachments/assets/b0ed217e-24fb-4a79-82fd-48a042c5da4a
Minimal reproduction project (MRP)
flatlaf-windows11.zip