Multi-line tooltips in Java?

前端 未结 10 1606
故里飘歌
故里飘歌 2020-12-02 12:31

I\'m trying to display tooltips in Java which may or may not be paragraph-length. How can I word-wrap long tooltips?

10条回答
  •  悲哀的现实
    2020-12-02 13:13

    Here is a version which I have used before, it works well if you are loading your tool tips from ResourceBundles:

    import javax.swing.JComponent;
    import javax.swing.JToolTip;
    import javax.swing.LookAndFeel;
    import javax.swing.UIManager;
    import javax.swing.plaf.ComponentUI;
    import javax.swing.plaf.ToolTipUI;
    import java.awt.Dimension;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.util.regex.Pattern;
    
    /**
     * A tooltip that wraps multi-line text.
     */
    public final class MultiLineToolTipUI extends ToolTipUI {
    
        private static final int INSET = 2;
    
        private static final Pattern LINE_SPLITTER = Pattern.compile("$", Pattern.MULTILINE);
    
        private static final MultiLineToolTipUI SHARED_INSTANCE = new MultiLineToolTipUI();
    
        /**
         * Install the multi-line tooltip into the UI manager.
         */
        public static void installUI() {
            String toolTipUI = MultiLineToolTipUI.class.getName();
            UIManager.put("ToolTipUI", toolTipUI);
            UIManager.put(toolTipUI, MultiLineToolTipUI.class);
        }
    
        @SuppressWarnings("UnusedDeclaration")
        public static ComponentUI createUI(JComponent c) {
            return SHARED_INSTANCE;
        }
    
        private MultiLineToolTipUI() {}
    
        @Override
        public Dimension getMaximumSize(JComponent c) {
            return getPreferredSize(c);
        }
    
        @Override
        public Dimension getMinimumSize(JComponent c) {
            return getPreferredSize(c);
        }
    
        @Override
        public Dimension getPreferredSize(JComponent c) {
            String[] lines = LINE_SPLITTER.split(((JToolTip) c).getTipText());
            if (lines.length == 0) {
                return new Dimension(2 * INSET, 2 * INSET);
            }
            FontMetrics metrics = c.getFontMetrics(c.getFont());
            Graphics g = c.getGraphics();
            int w = 0;
            for (String line : lines) {
                w = Math.max(w, (int) metrics.getStringBounds(line, g).getWidth());
            }
            int h = lines.length * metrics.getHeight();
            return new Dimension(w + 2 * INSET, h + 2 * INSET);
        }
    
        @Override
        public void installUI(JComponent c) {
            LookAndFeel.installColorsAndFont(c, "ToolTip.background", "ToolTip.foreground", "ToolTip.font");
            LookAndFeel.installBorder(c, "ToolTip.border");
        }
    
        @Override
        public void paint(Graphics g, JComponent c) {
            int w = c.getWidth(), h = c.getHeight();
            g.setColor(c.getBackground());
            g.fillRect(0, 0, w, h);
            g.setColor(c.getForeground());
            g.drawRect(0, 0, w, h);
            String[] lines = LINE_SPLITTER.split(((JToolTip) c).getTipText());
            if (lines.length != 0) {
                FontMetrics metrics = c.getFontMetrics(c.getFont());
                int height = metrics.getHeight();
                int y = INSET + metrics.getAscent();
                for (String line : lines) {
                    g.drawString(line, INSET, y);
                    y += height;
                }
            }
        }
    
        @Override
        public void uninstallUI(JComponent c) {
            LookAndFeel.uninstallBorder(c);
        }
    
    }
    

    And you would use it by calling this method, before your UI is created:

    MultiLineToolTipUI.installUI();
    

    Then in your properties files just insert newlines to wrap your tool tips as desired.

提交回复
热议问题