mgarin / weblaf

WebLaF is a fully open-source Look & Feel and component library written in pure Java for cross-platform desktop Swing applications.
http://weblookandfeel.com
GNU General Public License v3.0
1.13k stars 234 forks source link

Issues with JToolTip shape on Linux systems #602

Closed mgarin closed 4 years ago

mgarin commented 4 years ago

Reported by @Sciss on gitter:

There is a tiny issue, I think since long time, with tooltip rendering in the wrong height, so that the text exceeds the top border. Might be related to them going into their own window when exceeding the parent window's bounds. Observed on Linux. Example (also the triangle has a slightly off position):

image

The code that can be used to reproduce the issue (on Linux systems):

import com.alee.laf.WebLookAndFeel;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import java.awt.EventQueue;

public class TooltipTest {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            WebLookAndFeel.install();
            final JFrame f = new JFrame("Test");

            final JMenuBar  mb      = new JMenuBar();
            final JMenu     mFile   = new JMenu("File");
            final JMenuItem mNew    = new JMenu("New");
            mFile.add(mNew);
            mb.add(mFile);
            f.setJMenuBar(mb);

            final JPanel p = new JPanel();
            p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
            p.add(Box.createHorizontalStrut(50));
            final JLabel lbNumUGens  = new JLabel("tool-tip");
            lbNumUGens.setToolTipText("UGens");
            p.add(lbNumUGens);
            p.add(Box.createHorizontalStrut(50));

            f.setResizable(false);
            f.getContentPane().add(p);
            f.pack();
            f.setVisible(true);
        });
    }
}

It can also be reproduced on Windows if SystemUtils system type output is manually changed to always say that it is a Linux system.

The problem is that JToolTip reuses popup that JPopupMenu uses (due to Swing PopupManager optimizations). So whenever a JPopupMenu is invoked it setups it's own shape on the window, that shape is preserved for the tooltips displayed later on, even thought it shouldn't be.

mgarin commented 4 years ago

The problem was in PopupMenuPainter that didn't properly uninstall custom JPopupMenu window shape when it is hidden (even though the code for cleaning up the shape is there). I already found the way to fix it and cleaned up surrounding code a bit, will be pushing a fix soon.

mgarin commented 4 years ago

I've added a fix for this issue. I tried to extensively test it across different systems and JDK versions to ensure that it doesn't break anything. I'll also do some more testing later this week under Mac OS X to maybe add some more changes to this part of the code.

Changes will be shortly available in v1.2.12 snapshot.