How to eliminate black lag area in Java Swing running on Windows

Viewed 223

There is a common issue on every Swing application I wrote: black area appears when resizing window, even for the simplest code below:

import javax.swing.*;

public class SampleWindow extends JFrame {

    public static void main(String[] args) {
        SampleWindow sampleWindow = new SampleWindow();
        sampleWindow.setTitle("Sample Window");

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(new JLabel(
                System.getProperty("os.name") + " Java " + System.getProperty("java.version")
        ), BorderLayout.CENTER);

        sampleWindow.setContentPane(contentPane);
        sampleWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        sampleWindow.setSize(400, 200);
        sampleWindow.setVisible(true);
    }
}

enter image description here

enter image description here

And let's see what JavaFX acts:

enter image description here

Is there any way to eliminate this?


I'm tring to add a component listener and print when event comes:

sampleWindow.addComponentListener(new ComponentAdapter() {
    @Override
    public void componentResized(ComponentEvent e) {
        System.out.println("Resizing event: " + System.currentTimeMillis());
    }
});

I got these output:

Resizing event: 1614328759426
Resizing event: 1614328759524    // huge delay
Resizing event: 1614328759525
Resizing event: 1614328759525
Resizing event: 1614328759525
Resizing event: 1614328759525
Resizing event: 1614328759525
Resizing event: 1614328759526
Resizing event: 1614328759526

It is obvious that there is a huge delay between first line and second line. I think trying to handle resizing event is no effort.


I've found even IntelliJ also has a similar issue, so alright I give up :(

enter image description here

1 Answers

I don't know how to do the animation, but I didn't experience the black area with this code.

Sample Window GUI

My takeaway is to always start your Swing application with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.

Here's the code I ran.

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SampleWindow implements Runnable {
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SampleWindow());
    }
    
    private String properties;
    
    public SampleWindow() {
        this.properties = System.getProperty("os.name") + " Java " + 
                System.getProperty("java.version");
    }

    @Override
    public void run() {
        JFrame sampleWindow = new JFrame();
        sampleWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        sampleWindow.setTitle("Sample Window");
        
        JLabel label = new JLabel(properties);
        label.setHorizontalAlignment(JLabel.CENTER);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(label, BorderLayout.CENTER);

        sampleWindow.add(contentPane, BorderLayout.CENTER);
        sampleWindow.setSize(400, 200);
        sampleWindow.setVisible(true);
    }
    
}
Related