[SWINGX-1336] Flickering in JXPanel with alpha < 1 Created: 09/Aug/10  Updated: 14/Nov/12  Resolved: 14/Nov/12

Status: Resolved
Project: swingx
Component/s: Misc Component
Affects Version/s: 1.6.1
Fix Version/s: 1.6.5

Type: Bug Priority: Major
Reporter: justthemath Assignee: Karl Schaefer
Resolution: Incomplete Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issue Links:
Dependency
depends on SWINGX-1366 Move InputEventDispatcher from demos ... Open
blocks SWINGX-1518 JXPanel: umbrella issue for paint pro... Closed
Duplicate
is duplicated by SWINGX-1515 JXPanel: painting artefacts in overla... Resolved
Issuezilla Id: 1,336

 Description   

When resizing the JFrame when using the following code, I have found the results to
be system dependent. On my Windows 7 – using Aero and just plain Windows7 – I get
lots and lots of flicker. If I do not let go of the frame and just continue resizing,
things get much worse and the flickering changes to completely blank areas. Sometimes
the buttons turn completely black before repainting. After resizing, everything is
displayed correctly. On the XP Professional system that I have access to, there is no
repaint problem. On my XP laptop, I get an "animated" border when I resize the
JFrame, but none of the flicker.

As another data point. A couple of times the transparency effect in Aero has been
turned off while I have been "violently" resizing an application involving a JXPanel.

Thanks in advance

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import org.jdesktop.swingx.JXPanel;

public class JFrameWithJXPanelTest {
private int iScreen = 55;
private int iLocation = 10;
JLayeredPane layerPane = new FilledJLayeredPane();

JFrame frame = new JFrame();
Container contentPane = frame.getContentPane();

public JFrameWithJXPanelTest() {

final JXPanel jxp = new JXPanel();
jxp.setLayout(new GridLayout());
JLabel j2 = new JLabel(" I'm a JXPanel ");
j2.setFont(new Font("Bookman Old Style", 3, 35));
j2.setBackground(Color.YELLOW);
j2.setOpaque(true);
jxp.add(j2);
jxp.setAlpha(0.3f);
jxp.setBorder(javax.swing.BorderFactory.createLineBorder(Color.BLACK,
40));

Timer fadeTimer = new Timer(45, new ActionListener() {
public void actionPerformed(ActionEvent arg0)

{ jxp.setAlpha(1.0f); }


});
fadeTimer.setInitialDelay(5000);
fadeTimer.setRepeats(false);
fadeTimer.start();

contentPane.add(jxp, BorderLayout.CENTER);

JPanel northButtonPanel = new JPanel();
northButtonPanel.setLayout(new GridLayout(2, 2));
northButtonPanel.add(new JButton(" I do nothing"));
northButtonPanel.add(new JButton(" I do nothing"));
northButtonPanel.add(new JButton(" I do nothing"));
northButtonPanel.add(new JButton(" I do nothing"));
// northButtonPanel.setBackground(Color.DARK_GRAY);
contentPane.add(northButtonPanel, BorderLayout.NORTH);
JPanel southButtonPanel = new JPanel();
southButtonPanel.setLayout(new GridLayout(2, 2));
southButtonPanel.add(new JButton(" I do nothing"));
southButtonPanel.add(new JButton(" I do nothing"));
southButtonPanel.add(new JButton(" I do nothing"));
southButtonPanel.add(new JButton(" I do nothing"));
// northButtonPanel.setBackground(Color.DARK_GRAY);
contentPane.add(southButtonPanel, BorderLayout.SOUTH);
JPanel eastButtonPanel = new JPanel();
eastButtonPanel.setLayout(new GridLayout(2, 2));
eastButtonPanel.add(new JButton(" I do nothing"));
eastButtonPanel.add(new JButton(" I do nothing"));
eastButtonPanel.add(new JButton(" I do nothing"));
eastButtonPanel.add(new JButton(" I do nothing"));

contentPane.add(eastButtonPanel, BorderLayout.EAST);

/*

  • Below is the code to intialize and show the JFrame.
    */
    boolean packFrame = false;
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = frame.getSize();
    frameSize.height = (int) (iScreen * screenSize.height / 100);
    frameSize.width = (int) (iScreen * screenSize.width / 100);
    frame.setSize(frameSize);
    frame.setLocation((screenSize.width - frameSize.width) / iLocation,
    (screenSize.height - frameSize.height) / iLocation);
    if (packFrame) { frame.pack(); packFrame = true; }

    else

    { frame.validate(); }


    frame.setVisible(true);
    }

/**

  • @param args
    */
    public static void main(String[] args) {
    try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }

    catch (Exception e)

    { e.printStackTrace(); }


    javax.swing.SwingUtilities.invokeLater(new Runnable()

    Unknown macro: { public void run() { new JFrameWithJXPanelTest(); } }

    );
    }

private class FilledJLayeredPane extends JLayeredPane {
private static final long serialVersionUID = 1L;
/**

  • Layout each of the components in this JLayeredPane so that they all
  • fill the entire extents of the layered pane – from (0,0) to
  • (getWidth(), getHeight())
  • from R Camick at CodeRanch
    */
    @Override
    public void doLayout() {
    super.doLayout();
    // Synchronizing on getTreeLock, because I see other layouts doing
    // that.
    // see BorderLayout::layoutContainer(Container)
    synchronized (getTreeLock()) {
    int w = getWidth();
    int h = getHeight();
    for (Component c : getComponents())
    Unknown macro: { if (getLayer(c) == JLayeredPane.DEFAULT_LAYER) { c.setBounds(0, 0, w , h ); c.doLayout(); } if (getLayer(c) == JLayeredPane.PALETTE_LAYER) { c.setBounds(0, 0, w + 2, h + 2); c.doLayout(); } }


    }
    }
    }
    }



 Comments   
Comment by Karl Schaefer [ 27/Sep/10 ]

Issue 1336: Fixed some painting issues with JXPanel: was not properly using the
alpha to paint and was not walking the tree to correctly repaint parents.
Still flickering on resize.

src/main/java/org/jdesktop/swingx/JXPanel.java
src/main/java/org/jdesktop/swingx/RepaintManagerX.java
src/test/java/org/jdesktop/swingx/JXPanelVisualCheck.java

Committed revision 3789.

Comment by Karl Schaefer [ 30/Mar/11 ]

Until Java 7, which will have a method for supporting painting roots, the only way to solve this problem is with the InputEventDispatcher code. Even if we don't place the code for public consumption we could use it internally. Any RepaintManager tricks will fail. As soon as the RepaintManager is set, even if the new manager delegates to the original, the painting will never be optimal (core bug, cannot work around).

We need to either decide to do SWINGX-1366 or not. If not, are we willing to take the hit on a private implementation? If not, this bug cannot be fixed.

Comment by Karl Schaefer [ 13/Aug/12 ]

SWINGX-1336: Update to allow JXPanel to use JAva & isPaintingOrigin method.

swingx-core/src/main/java/org/jdesktop/swingx/JXPanel.java

Committed revision 4234.

Comment by Karl Schaefer [ 14/Nov/12 ]

This fix only works on Java 7+, but that is the only Java versions that we can fix this issue on.

Generated at Sat Jul 04 22:08:51 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.