package tk.amberide.ide.swing; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.TextAttribute; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @author Tudor */ public class LabelBuilder { private ArrayList<Component> bits = new ArrayList<Component>(); private Color foreground = UIManager.getColor("Label.foreground"), active = new Color(240, 0, 0); private Font font; private int cursor; /** * Sets the text foreground color * * @param color the color */ public void setForeground(Color color) { foreground = color; } /** * Sets the active text color * * @param color the color; */ public void setActive(Color color) { active = color; } /** * Sets the text font * * @param fon the font; */ public void setFont(Font fon) { font = fon; } /** * Sets the mouseover cursor * * @param curse the cursor id */ public void setCursor(int curse) { cursor = curse; } /** * Appends a normal label * * @param text the text to display * @return this object */ public LabelBuilder append(String text) { JLabel label = new JLabel(text); label.setForeground(foreground); label.setFont(font); label.setCursor(new Cursor(cursor)); bits.add(label); return this; } /** * Appends an action label * * @param text the text to display * @param act the action to perform on click * @return this object */ public LabelBuilder action(String text, final AbstractAction act) { final JLabel button = new JLabel(text); button.setForeground(foreground); button.setFont(font); button.setCursor(new Cursor(cursor)); button.setOpaque(false); button.setFocusable(false); button.setBorder(null); button.addMouseListener(new MouseAdapter() { Font font; Color color; boolean active, clicked; @Override public void mousePressed(MouseEvent e) { active = clicked = true; color = e.getComponent().getForeground(); e.getComponent().setForeground(LabelBuilder.this.active); } @Override public void mouseReleased(MouseEvent e) { if (active) { if (clicked) { EventQueue.invokeLater(new Runnable() { public void run() { act.actionPerformed(new ActionEvent(button, ActionEvent.ACTION_PERFORMED, "label_action")); } }); } mouseExited(e); active = false; } } @Override public void mouseEntered(MouseEvent e) { if (!active) { font = e.getComponent().getFont(); Map attributes = font.getAttributes(); attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); e.getComponent().setFont(font.deriveFont(attributes)); } } @Override public void mouseExited(MouseEvent e) { e.getComponent().setFont(font); if (clicked) { e.getComponent().setForeground(color); clicked = false; } } }); bits.add(button); return this; } /** * Appends a hyperlinked label * * @param text the text to display * @param uri the link, in String form * @return this object */ public LabelBuilder hyperlink(String text, String uri) { try { return hyperlink(text, new URI(uri)); } catch (URISyntaxException ex) { throw new RuntimeException("invalid uri", ex); } } /** * Appends a hyperlinked label * * @param text the text to display * @param uri the link * @return this object */ public LabelBuilder hyperlink(String text, final URI uri) { action(text, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { if (Desktop.isDesktopSupported()) { try { Desktop.getDesktop().browse(uri); } catch (IOException io) { throw new RuntimeException("IO error while opening URI", io); } } else { throw new UnknownError("desktop not supported"); } } }); return this; } /** * Generates a container for this compound label * * @return a JPanel hosting all labels */ public JPanel create() { JPanel panel = new JPanel(new GridBagLayout()); for (Component comp : bits) { panel.add(comp); } return panel; } public List<Component> createRaw() { return bits; } }