aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/plugin/desktoputil/ComponentUtils.java
blob: 62f23069a1a67cfe52dbc7e2086c18188bec99ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Copyright @ 2015 Atlassian Pty Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.java.sip.communicator.plugin.desktoputil;

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;

import javax.swing.*;

/**
 * Utility class for component related operations. For example: calculating size
 * of strings depending on the component, obtaining component index, updating
 * component tree UI, etc.
 *
 * @author Yana Stamcheva
 */
public class ComponentUtils
{
    /**
     * Returns the width in pixels of a text.
     *
     * @param c the component where the text is contained
     * @param text the text to measure
     * @return the width in pixels of a text.
     */
    public static int getStringWidth(Component c, String text)
    {
        return SwingUtilities.computeStringWidth(c
                .getFontMetrics(c.getFont()), text);
    }

    /**
     * Returns the size of the given text computed towards to the given
     * component.
     *
     * @param c the component where the text is contained
     * @param text the text to measure
     * @return the dimensions of the text
     */
    public static Dimension getStringSize(Component c, String text)
    {
        // get metrics from the graphics
        FontMetrics metrics = c.getFontMetrics(c.getFont());
        // get the height of a line of text in this font and render context
        int hgt = metrics.getHeight();
        // get the advance of my text in this font and render context
        int adv = metrics.stringWidth(text);
        // calculate the size of a box to hold the text with some padding.
        return new Dimension(adv+2, hgt+2);
    }

    /**
     * Returns the height of the given component.
     *
     * @param c the component where the text is contained
     * @return the height of the text
     */
    public static int getStringHeight(Component c)
    {
        // get metrics from the graphics
        FontMetrics metrics = c.getFontMetrics(c.getFont());
        // get the height of a line of text in this font and render context
        int hgt = metrics.getHeight();
        // calculate the height of a box to hold the text with some padding.
        return hgt+2;
    }

    /**
     * Returns the bounds of the given string.
     *
     * @param text the string to measure
     * @return the bounds of the given string
     */
    public static Rectangle2D getDefaultStringSize(String text)
    {
        Font font = UIManager.getFont("Label.font");
        FontRenderContext frc = new FontRenderContext(null, true, false);
        TextLayout layout = new TextLayout(text, font, frc);

        return layout.getBounds();
    }

    /**
     * A simple minded look and feel change: ask each node in the tree
     * to <code>updateUI()</code> -- that is, to initialize its UI property
     * with the current look and feel.
     *
     * @param c UI component.
     */
    public static void updateComponentTreeUI(Component c)
    {
        updateComponentTreeUI0(c);
        c.invalidate();
        c.validate();
        c.repaint();
    }

    /**
     * Returns the index of the given component in the given container.
     *
     * @param c the Component to look for
     * @param container the parent container, where this component is added
     * @return the index of the component in the container or -1 if no such
     * component is contained in the container
     */
    public static int getComponentIndex(Component c, Container container)
    {
        for (int i = 0, count = container.getComponentCount(); i < count; i++)
        {
            if (container.getComponent(i).equals(c))
                return i;
        }
        return -1;
    }

    /**
     * Repaints UI tree recursively.
     *
     * @param c UI component.
     */
    private static void updateComponentTreeUI0(Component c)
    {
        if (c instanceof JComponent)
        {
            JComponent jc = (JComponent) c;
            jc.invalidate();
            jc.validate();
            jc.repaint();
            JPopupMenu jpm =jc.getComponentPopupMenu();
            if(jpm != null && jpm.isVisible() && jpm.getInvoker() == jc)
            {
                updateComponentTreeUI(jpm);
            }
        }
        Component[] children = null;
        if (c instanceof JMenu)
        {
            children = ((JMenu)c).getMenuComponents();
        }
        else if (c instanceof java.awt.Container)
        {
            children = ((java.awt.Container)c).getComponents();
        }
        if (children != null)
        {
            for(int i = 0; i < children.length; i++)
                updateComponentTreeUI0(children[i]);
        }
    }
}