1 | /*
|
---|
2 | * 08/13/2009
|
---|
3 | *
|
---|
4 | * TipUtil.java - Utility methods for homemade tool tips.
|
---|
5 | *
|
---|
6 | * This library is distributed under a modified BSD license. See the included
|
---|
7 | * RSyntaxTextArea.License.txt file for details.
|
---|
8 | */
|
---|
9 | package org.fife.ui.rsyntaxtextarea.focusabletip;
|
---|
10 |
|
---|
11 | import java.awt.Color;
|
---|
12 | import java.awt.Font;
|
---|
13 | import java.awt.GraphicsConfiguration;
|
---|
14 | import java.awt.GraphicsDevice;
|
---|
15 | import java.awt.GraphicsEnvironment;
|
---|
16 | import java.awt.Rectangle;
|
---|
17 | import java.awt.SystemColor;
|
---|
18 | import javax.swing.BorderFactory;
|
---|
19 | import javax.swing.JEditorPane;
|
---|
20 | import javax.swing.UIManager;
|
---|
21 | import javax.swing.border.Border;
|
---|
22 | import javax.swing.plaf.ColorUIResource;
|
---|
23 | import javax.swing.text.html.HTMLDocument;
|
---|
24 |
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * Static utility methods for focusable tips.
|
---|
28 | *
|
---|
29 | * @author Robert Futrell
|
---|
30 | * @version 1.0
|
---|
31 | */
|
---|
32 | public class TipUtil {
|
---|
33 |
|
---|
34 |
|
---|
35 | private TipUtil() {
|
---|
36 | }
|
---|
37 |
|
---|
38 |
|
---|
39 | /**
|
---|
40 | * Returns a hex string for the specified color, suitable for HTML.
|
---|
41 | *
|
---|
42 | * @param c The color.
|
---|
43 | * @return The string representation, in the form "<code>#rrggbb</code>",
|
---|
44 | * or <code>null</code> if <code>c</code> is <code>null</code>.
|
---|
45 | */
|
---|
46 | private static final String getHexString(Color c) {
|
---|
47 |
|
---|
48 | if (c==null) {
|
---|
49 | return null;
|
---|
50 | }
|
---|
51 |
|
---|
52 | StringBuffer sb = new StringBuffer("#");
|
---|
53 | int r = c.getRed();
|
---|
54 | if (r<16) {
|
---|
55 | sb.append('0');
|
---|
56 | }
|
---|
57 | sb.append(Integer.toHexString(r));
|
---|
58 | int g = c.getGreen();
|
---|
59 | if (g<16) {
|
---|
60 | sb.append('0');
|
---|
61 | }
|
---|
62 | sb.append(Integer.toHexString(g));
|
---|
63 | int b = c.getBlue();
|
---|
64 | if (b<16) {
|
---|
65 | sb.append('0');
|
---|
66 | }
|
---|
67 | sb.append(Integer.toHexString(b));
|
---|
68 |
|
---|
69 | return sb.toString();
|
---|
70 |
|
---|
71 | }
|
---|
72 |
|
---|
73 |
|
---|
74 | /**
|
---|
75 | * Returns the screen coordinates for the monitor that contains the
|
---|
76 | * specified point. This is useful for setups with multiple monitors,
|
---|
77 | * to ensure that popup windows are positioned properly.
|
---|
78 | *
|
---|
79 | * @param x The x-coordinate, in screen coordinates.
|
---|
80 | * @param y The y-coordinate, in screen coordinates.
|
---|
81 | * @return The bounds of the monitor that contains the specified point.
|
---|
82 | */
|
---|
83 | public static Rectangle getScreenBoundsForPoint(int x, int y) {
|
---|
84 | GraphicsEnvironment env = GraphicsEnvironment.
|
---|
85 | getLocalGraphicsEnvironment();
|
---|
86 | GraphicsDevice[] devices = env.getScreenDevices();
|
---|
87 | for (int i=0; i<devices.length; i++) {
|
---|
88 | GraphicsConfiguration[] configs = devices[i].getConfigurations();
|
---|
89 | for (int j=0; j<configs.length; j++) {
|
---|
90 | Rectangle gcBounds = configs[j].getBounds();
|
---|
91 | if (gcBounds.contains(x, y)) {
|
---|
92 | return gcBounds;
|
---|
93 | }
|
---|
94 | }
|
---|
95 | }
|
---|
96 | // If point is outside all monitors, default to default monitor (?)
|
---|
97 | return env.getMaximumWindowBounds();
|
---|
98 | }
|
---|
99 |
|
---|
100 |
|
---|
101 | /**
|
---|
102 | * Returns the default background color to use for tool tip windows.
|
---|
103 | *
|
---|
104 | * @return The default background color.
|
---|
105 | */
|
---|
106 | public static Color getToolTipBackground() {
|
---|
107 |
|
---|
108 | Color c = UIManager.getColor("ToolTip.background");
|
---|
109 |
|
---|
110 | // Tooltip.background is wrong color on Nimbus (!)
|
---|
111 | if (c==null || isNimbusLookAndFeel()) {
|
---|
112 | c = UIManager.getColor("info"); // Used by Nimbus (and others)
|
---|
113 | if (c==null) {
|
---|
114 | c = SystemColor.info; // System default
|
---|
115 | }
|
---|
116 | }
|
---|
117 |
|
---|
118 | // Workaround for a bug (?) with Nimbus - calling JLabel.setBackground()
|
---|
119 | // with a ColorUIResource does nothing, must be a normal Color
|
---|
120 | if (c instanceof ColorUIResource) {
|
---|
121 | c = new Color(c.getRGB());
|
---|
122 | }
|
---|
123 |
|
---|
124 | return c;
|
---|
125 |
|
---|
126 | }
|
---|
127 |
|
---|
128 |
|
---|
129 | /**
|
---|
130 | * Returns the border used by tool tips in this look and feel.
|
---|
131 | *
|
---|
132 | * @return The border.
|
---|
133 | */
|
---|
134 | public static Border getToolTipBorder() {
|
---|
135 |
|
---|
136 | Border border = UIManager.getBorder("ToolTip.border");
|
---|
137 |
|
---|
138 | if (border==null || isNimbusLookAndFeel()) {
|
---|
139 | border = UIManager.getBorder("nimbusBorder");
|
---|
140 | if (border==null) {
|
---|
141 | border = BorderFactory.createLineBorder(SystemColor.controlDkShadow);
|
---|
142 | }
|
---|
143 | }
|
---|
144 |
|
---|
145 | return border;
|
---|
146 |
|
---|
147 | }
|
---|
148 |
|
---|
149 |
|
---|
150 | /**
|
---|
151 | * Returns whether a color is a Nimbus DerivedColor, which is troublesome
|
---|
152 | * in that it doesn't use its RGB values (uses HSB instead?) and so
|
---|
153 | * querying them is useless.
|
---|
154 | *
|
---|
155 | * @param c The color to check.
|
---|
156 | * @return Whether it is a DerivedColor
|
---|
157 | */
|
---|
158 | private static final boolean isDerivedColor(Color c) {
|
---|
159 | return c!=null && c.getClass().getName().endsWith(".DerivedColor");
|
---|
160 | }
|
---|
161 |
|
---|
162 |
|
---|
163 | /**
|
---|
164 | * Returns whether the Nimbus Look and Feel is installed.
|
---|
165 | *
|
---|
166 | * @return Whether the current LAF is Nimbus.
|
---|
167 | */
|
---|
168 | private static final boolean isNimbusLookAndFeel() {
|
---|
169 | return UIManager.getLookAndFeel().getName().equals("Nimbus");
|
---|
170 | }
|
---|
171 |
|
---|
172 |
|
---|
173 | /**
|
---|
174 | * Tweaks a <code>JEditorPane</code> so it can be used to render the
|
---|
175 | * content in a focusable pseudo-tool tip. It is assumed that the editor
|
---|
176 | * pane is using an <code>HTMLDocument</code>.
|
---|
177 | *
|
---|
178 | * @param textArea The editor pane to tweak.
|
---|
179 | */
|
---|
180 | public static void tweakTipEditorPane(JEditorPane textArea) {
|
---|
181 |
|
---|
182 | // Jump through a few hoops to get things looking nice in Nimbus
|
---|
183 | boolean isNimbus = isNimbusLookAndFeel();
|
---|
184 | if (isNimbus) {
|
---|
185 | Color selBG = textArea.getSelectionColor();
|
---|
186 | Color selFG = textArea.getSelectedTextColor();
|
---|
187 | textArea.setUI(new javax.swing.plaf.basic.BasicEditorPaneUI());
|
---|
188 | textArea.setSelectedTextColor(selFG);
|
---|
189 | textArea.setSelectionColor(selBG);
|
---|
190 | }
|
---|
191 |
|
---|
192 | textArea.setEditable(false); // Required for links to work!
|
---|
193 | textArea.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
---|
194 |
|
---|
195 | // Make selection visible even though we are not (initially) focusable.
|
---|
196 | textArea.getCaret().setSelectionVisible(true);
|
---|
197 |
|
---|
198 | // Set the foreground color. Important because when rendering HTML,
|
---|
199 | // default foreground becomes black, which may not match all LAF's
|
---|
200 | // (e.g. Substance).
|
---|
201 | Color fg = UIManager.getColor("Label.foreground");
|
---|
202 | if (fg==null || (isNimbus && isDerivedColor(fg))) {
|
---|
203 | fg = SystemColor.textText;
|
---|
204 | }
|
---|
205 | textArea.setForeground(fg);
|
---|
206 |
|
---|
207 | // Make it use the "tool tip" background color.
|
---|
208 | textArea.setBackground(TipUtil.getToolTipBackground());
|
---|
209 |
|
---|
210 | // Force JEditorPane to use a certain font even in HTML.
|
---|
211 | // All standard LookAndFeels, even Nimbus (!), define Label.font.
|
---|
212 | Font font = UIManager.getFont("Label.font");
|
---|
213 | if (font == null) { // Try to make a sensible default
|
---|
214 | font = new Font("SansSerif", Font.PLAIN, 12);
|
---|
215 | }
|
---|
216 | HTMLDocument doc = (HTMLDocument) textArea.getDocument();
|
---|
217 | doc.getStyleSheet().addRule(
|
---|
218 | "body { font-family: " + font.getFamily() +
|
---|
219 | "; font-size: " + font.getSize() + "pt" +
|
---|
220 | "; color: " + getHexString(fg) + "; }");
|
---|
221 |
|
---|
222 | }
|
---|
223 |
|
---|
224 |
|
---|
225 | } |
---|