Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.gui

File JvSwingUtils.java

 

Coverage histogram

../../img/srcFileCovDistChart5.png
39% of files have more coverage

Code metrics

36
92
19
1
387
245
41
0.45
4.84
19
2.16

Classes

Class Line # Actions
JvSwingUtils 57 92 41
0.4693877746.9%
 

Contributing tests

This file is covered by 194 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui;
22   
23    import java.awt.BorderLayout;
24    import java.awt.Color;
25    import java.awt.Component;
26    import java.awt.Font;
27    import java.awt.GridLayout;
28    import java.awt.Rectangle;
29    import java.awt.event.ActionListener;
30    import java.awt.event.MouseAdapter;
31    import java.awt.event.MouseEvent;
32    import java.util.List;
33    import java.util.Objects;
34   
35    import javax.swing.AbstractButton;
36    import javax.swing.BorderFactory;
37    import javax.swing.JButton;
38    import javax.swing.JComboBox;
39    import javax.swing.JComponent;
40    import javax.swing.JLabel;
41    import javax.swing.JMenu;
42    import javax.swing.JMenuItem;
43    import javax.swing.JPanel;
44    import javax.swing.JScrollBar;
45    import javax.swing.SwingConstants;
46    import javax.swing.border.Border;
47    import javax.swing.border.TitledBorder;
48   
49    import jalview.util.MessageManager;
50   
51    /**
52    * useful functions for building Swing GUIs
53    *
54    * @author JimP
55    *
56    */
 
57    public final class JvSwingUtils
58    {
59    /**
60    * wrap a bare html safe string to around 60 characters per line using a CSS
61    * style class specifying word-wrap and break-word
62    *
63    * @param enclose
64    * if true, add &lt;html&gt; wrapper tags
65    * @param ttext
66    *
67    * @return
68    */
 
69  22510 toggle public static String wrapTooltip(boolean enclose, String ttext)
70    {
71  22510 Objects.requireNonNull(ttext,
72    "Tootip text to format must not be null!");
73  22510 ttext = ttext.trim();
74  22510 boolean maxLengthExceeded = false;
75   
76  22510 if (ttext.contains("<br>"))
77    {
78  246 String[] htmllines = ttext.split("<br>");
79  246 for (String line : htmllines)
80    {
81  251 maxLengthExceeded = line.length() > 60;
82  251 if (maxLengthExceeded)
83    {
84  241 break;
85    }
86    }
87    }
88    else
89    {
90  22264 maxLengthExceeded = ttext.length() > 60;
91    }
92   
93  22510 if (!maxLengthExceeded)
94    {
95  13407 return enclose ? "<html>" + ttext + "</html>" : ttext;
96    }
97   
98  9103 return (enclose ? "<html>" : "")
99    // BH 2018
100    + "<style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style><div class=\"ttip\">"
101    // + "<style> p.ttip {width:350px;margin:-14px 0px -14px 0px;padding:2px;overflow-wrap:break-word;}"
102    // + "</style><p class=\"ttip\">"
103    + ttext
104    + " </div>"
105    // + "</p>"
106  9103 + ((enclose ? "</html>" : ""));
107    }
108   
 
109  0 toggle public static JButton makeButton(String label, String tooltip,
110    ActionListener action)
111    {
112  0 JButton button = new JButton();
113  0 button.setText(label);
114    // TODO: get the base font metrics for the Jalview gui from somewhere
115  0 button.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
116  0 button.setForeground(Color.black);
117  0 button.setHorizontalAlignment(SwingConstants.CENTER);
118  0 button.setToolTipText(tooltip);
119  0 button.addActionListener(action);
120  0 return button;
121    }
122   
123    /**
124    * find or add a submenu with the given title in the given menu
125    *
126    * @param menu
127    * @param submenu
128    * @return the new or existing submenu
129    */
 
130  9777 toggle public static JMenu findOrCreateMenu(JMenu menu, String submenu)
131    {
132  9777 JMenu submenuinstance = null;
133  50582 for (int i = 0, iSize = menu.getMenuComponentCount(); i < iSize; i++)
134    {
135  40805 if (menu.getMenuComponent(i) instanceof JMenu
136    && ((JMenu) menu.getMenuComponent(i)).getText()
137    .equals(submenu))
138    {
139  9206 submenuinstance = (JMenu) menu.getMenuComponent(i);
140    }
141    }
142  9777 if (submenuinstance == null)
143    {
144  571 submenuinstance = new JMenu(submenu);
145  571 menu.add(submenuinstance);
146    }
147  9777 return submenuinstance;
148   
149    }
150   
151    /**
152    *
153    * @param panel
154    * @param tooltip
155    * @param label
156    * @param valBox
157    * @return the GUI element created that was added to the layout so it's
158    * attributes can be changed.
159    */
 
160  0 toggle public static JPanel addtoLayout(JPanel panel, String tooltip,
161    JComponent label, JComponent valBox)
162    {
163  0 JPanel laypanel = new JPanel(new GridLayout(1, 2));
164  0 JPanel labPanel = new JPanel(new BorderLayout());
165  0 JPanel valPanel = new JPanel();
166  0 labPanel.setBounds(new Rectangle(7, 7, 158, 23));
167  0 valPanel.setBounds(new Rectangle(172, 7, 270, 23));
168  0 labPanel.add(label, BorderLayout.WEST);
169  0 valPanel.add(valBox);
170  0 laypanel.add(labPanel);
171  0 laypanel.add(valPanel);
172  0 valPanel.setToolTipText(tooltip);
173  0 labPanel.setToolTipText(tooltip);
174  0 valBox.setToolTipText(tooltip);
175  0 panel.add(laypanel);
176  0 panel.validate();
177  0 return laypanel;
178    }
179   
 
180  0 toggle public static void mgAddtoLayout(JPanel cpanel, String tooltip,
181    JLabel jLabel, JComponent name)
182    {
183  0 mgAddtoLayout(cpanel, tooltip, jLabel, name, null);
184    }
185   
 
186  0 toggle public static void mgAddtoLayout(JPanel cpanel, String tooltip,
187    JLabel jLabel, JComponent name, String params)
188    {
189  0 cpanel.add(jLabel);
190  0 if (params == null)
191    {
192  0 cpanel.add(name);
193    }
194    else
195    {
196  0 cpanel.add(name, params);
197    }
198  0 name.setToolTipText(tooltip);
199  0 jLabel.setToolTipText(tooltip);
200    }
201   
202    /**
203    * standard font for labels and check boxes in dialog boxes
204    *
205    * @return
206    */
207   
 
208  57 toggle public static Font getLabelFont()
209    {
210  57 return getLabelFont(false, false);
211    }
212   
 
213  61 toggle public static Font getLabelFont(boolean bold, boolean italic)
214    {
215  61 return new java.awt.Font("Verdana",
216  61 (!bold && !italic) ? Font.PLAIN
217  4 : (bold ? Font.BOLD : 0) + (italic ? Font.ITALIC : 0),
218    11);
219    }
220   
221    /**
222    * standard font for editable text areas
223    *
224    * @return
225    */
 
226  0 toggle public static Font getTextAreaFont()
227    {
228  0 return getLabelFont(false, false);
229    }
230   
231    /**
232    * clean up a swing menu. Removes any empty submenus without selection
233    * listeners.
234    *
235    * @param webService
236    */
 
237  0 toggle public static void cleanMenu(JMenu webService)
238    {
239  0 for (int i = 0; i < webService.getItemCount();)
240    {
241  0 JMenuItem item = webService.getItem(i);
242  0 if (item instanceof JMenu && ((JMenu) item).getItemCount() == 0)
243    {
244  0 webService.remove(i);
245    }
246    else
247    {
248  0 i++;
249    }
250    }
251    }
252   
253    /**
254    * Returns the proportion of its range that a scrollbar's position represents,
255    * as a value between 0 and 1. For example if the whole range is from 0 to
256    * 200, then a position of 40 gives proportion = 0.2.
257    *
258    * @see http://www.javalobby.org/java/forums/t33050.html#91885334
259    *
260    * @param scroll
261    * @return
262    */
 
263  1 toggle public static float getScrollBarProportion(JScrollBar scroll)
264    {
265    /*
266    * The extent (scroll handle width) deduction gives the true operating range
267    * of possible positions.
268    */
269  1 int possibleRange = scroll.getMaximum() - scroll.getMinimum()
270    - scroll.getModel().getExtent();
271  1 float valueInRange = scroll.getValue()
272    - (scroll.getModel().getExtent() / 2f);
273  1 float proportion = valueInRange / possibleRange;
274  1 return proportion;
275    }
276   
277    /**
278    * Returns the scroll bar position in its range that would match the given
279    * proportion (between 0 and 1) of the whole. For example if the whole range
280    * is from 0 to 200, then a proportion of 0.25 gives position 50.
281    *
282    * @param scrollbar
283    * @param proportion
284    * @return
285    */
 
286  1 toggle public static int getScrollValueForProportion(JScrollBar scrollbar,
287    float proportion)
288    {
289    /*
290    * The extent (scroll handle width) deduction gives the true operating range
291    * of possible positions.
292    */
293  1 float fraction = proportion
294    * (scrollbar.getMaximum() - scrollbar.getMinimum()
295    - scrollbar.getModel().getExtent())
296    + (scrollbar.getModel().getExtent() / 2f);
297  1 return Math.min(Math.round(fraction), scrollbar.getMaximum());
298    }
299   
 
300  16 toggle public static void jvInitComponent(AbstractButton comp, String i18nString)
301    {
302  16 setColorAndFont(comp);
303  16 if (i18nString != null && !i18nString.isEmpty())
304    {
305  16 comp.setText(MessageManager.getString(i18nString));
306    }
307    }
308   
 
309  6 toggle public static void jvInitComponent(JComponent comp)
310    {
311  6 setColorAndFont(comp);
312    }
313   
 
314  22 toggle private static void setColorAndFont(JComponent comp)
315    {
316  22 comp.setBackground(Color.white);
317  22 comp.setFont(JvSwingUtils.getLabelFont());
318    }
319   
320    /**
321    * A helper method to build a drop-down choice of values, with tooltips for
322    * the entries
323    *
324    * @param entries
325    * @param tooltips
326    */
 
327  0 toggle public static JComboBox<Object> buildComboWithTooltips(
328    List<Object> entries, List<String> tooltips)
329    {
330  0 JComboBox<Object> combo = new JComboBox<>();
331  0 final ComboBoxTooltipRenderer renderer = new ComboBoxTooltipRenderer();
332  0 combo.setRenderer(renderer);
333  0 for (Object attName : entries)
334    {
335  0 combo.addItem(attName);
336    }
337  0 renderer.setTooltips(tooltips);
338  0 final MouseAdapter mouseListener = new MouseAdapter()
339    {
 
340  0 toggle @Override
341    public void mouseEntered(MouseEvent e)
342    {
343  0 int j = combo.getSelectedIndex();
344  0 if (j > -1)
345    {
346  0 combo.setToolTipText(tooltips.get(j));
347    }
348    }
 
349  0 toggle @Override
350    public void mouseExited(MouseEvent e)
351    {
352  0 combo.setToolTipText(null);
353    }
354    };
355  0 for (Component c : combo.getComponents())
356    {
357  0 c.addMouseListener(mouseListener);
358    }
359  0 return combo;
360    }
361   
362    /**
363    * Adds a titled border to the component in the default font and position (top
364    * left), optionally witht italic text
365    *
366    * @param comp
367    * @param title
368    * @param italic
369    */
 
370  0 toggle public static TitledBorder createTitledBorder(JComponent comp,
371    String title, boolean italic)
372    {
373  0 Font font = comp.getFont();
374  0 if (italic)
375    {
376  0 font = new Font(font.getName(), Font.ITALIC, font.getSize());
377    }
378  0 Border border = BorderFactory.createTitledBorder("");
379  0 TitledBorder titledBorder = BorderFactory.createTitledBorder(border,
380    title, TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION,
381    font);
382  0 comp.setBorder(titledBorder);
383   
384  0 return titledBorder;
385    }
386   
387    }