+
+ /**
+ * Add a {@link JScrollPane} around the given panel and use a sensible (for
+ * me) increment for the mouse wheel.
+ *
+ * @param pane
+ * the panel to wrap in a {@link JScrollPane}
+ * @param allowHorizontal
+ * allow horizontal scrolling (not always desired)
+ *
+ * @return the {@link JScrollPane}
+ */
+ static public JScrollPane scroll(JComponent pane, boolean allowHorizontal) {
+ return scroll(pane, allowHorizontal, true);
+ }
+
+ /**
+ * Add a {@link JScrollPane} around the given panel and use a sensible (for
+ * me) increment for the mouse wheel.
+ *
+ * @param pane
+ * the panel to wrap in a {@link JScrollPane}
+ * @param allowHorizontal
+ * allow horizontal scrolling (not always desired)
+ * @param allowVertical
+ * allow vertical scrolling (usually yes, but sometimes you only
+ * want horizontal)
+ *
+ * @return the {@link JScrollPane}
+ */
+ static public JScrollPane scroll(JComponent pane, boolean allowHorizontal,
+ boolean allowVertical) {
+ JScrollPane scroll = new JScrollPane(pane);
+
+ scroll.getVerticalScrollBar().setUnitIncrement(16);
+ scroll.getHorizontalScrollBar().setUnitIncrement(16);
+
+ if (!allowHorizontal) {
+ scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ }
+ if (!allowVertical) {
+ scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
+ }
+
+ return scroll;
+ }
+
+ /**
+ * Show a confirmation message to the user to show him the changes since
+ * last version.
+ * <p>
+ * HTML 3.2 supported, links included (the user browser will be launched if
+ * possible).
+ * <p>
+ * If this is already the latest version, a message will still be displayed.
+ *
+ * @param parentComponent
+ * determines the {@link java.awt.Frame} in which the dialog is
+ * displayed; if <code>null</code>, or if the
+ * <code>parentComponent</code> has no {@link java.awt.Frame}, a
+ * default {@link java.awt.Frame} is used
+ * @param updates
+ * the new version
+ * @param introText
+ * an introduction text before the list of changes
+ * @param title
+ * the title of the dialog
+ *
+ * @return TRUE if the user clicked on OK, false if the dialog was dismissed
+ */
+ static public boolean showUpdatedDialog(Component parentComponent,
+ VersionCheck updates, String introText, String title) {
+
+ StringBuilder builder = new StringBuilder();
+ final JEditorPane updateMessage = new JEditorPane("text/html", "");
+ if (introText != null && !introText.isEmpty()) {
+ builder.append(introText);
+ builder.append("<br>");
+ builder.append("<br>");
+ }
+ for (Version v : updates.getNewer()) {
+ builder.append("\t<b>" //
+ + "Version " + v.toString() //
+ + "</b>");
+ builder.append("<br>");
+ builder.append("<ul>");
+ for (String item : updates.getChanges().get(v)) {
+ builder.append("<li>" + item + "</li>");
+ }
+ builder.append("</ul>");
+ }
+
+ // html content
+ updateMessage.setText("<html><body>" //
+ + builder//
+ + "</body></html>");
+
+ // handle link events
+ updateMessage.addHyperlinkListener(new HyperlinkListener() {
+ @Override
+ public void hyperlinkUpdate(HyperlinkEvent e) {
+ if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED))
+ try {
+ Desktop.getDesktop().browse(e.getURL().toURI());
+ } catch (IOException ee) {
+ ee.printStackTrace();
+ } catch (URISyntaxException ee) {
+ ee.printStackTrace();
+ }
+ }
+ });
+ updateMessage.setEditable(false);
+ updateMessage.setBackground(new JLabel().getBackground());
+ updateMessage.addHyperlinkListener(new HyperlinkListener() {
+ @Override
+ public void hyperlinkUpdate(HyperlinkEvent evn) {
+ if (evn.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+ if (Desktop.isDesktopSupported()) {
+ try {
+ Desktop.getDesktop().browse(evn.getURL().toURI());
+ } catch (IOException e) {
+ } catch (URISyntaxException e) {
+ }
+ }
+ }
+ }
+ });
+
+ return JOptionPane.showConfirmDialog(parentComponent, updateMessage,
+ title, JOptionPane.DEFAULT_OPTION) == JOptionPane.OK_OPTION;
+ }
+
+ /**
+ * Set the given {@link JButton} as "pressed" (selected, but with more UI
+ * visibility).
+ * <p>
+ * The {@link JButton} will answer {@link JButton#isSelected()} if it is
+ * pressed.
+ *
+ * @param button
+ * the button to select/press
+ * @param pressed
+ * the new "pressed" state
+ */
+ static public void setButtonPressed(JButton button, boolean pressed) {
+ if (buttonNormal == null) {
+ JButton defButton = new JButton(" ");
+ buttonNormal = defButton.getBackground();
+ if (buttonNormal.getBlue() >= 128) {
+ buttonPressed = new Color( //
+ Math.max(buttonNormal.getRed() - 100, 0), //
+ Math.max(buttonNormal.getGreen() - 100, 0), //
+ Math.max(buttonNormal.getBlue() - 100, 0));
+ } else {
+ buttonPressed = new Color( //
+ Math.min(buttonNormal.getRed() + 100, 255), //
+ Math.min(buttonNormal.getGreen() + 100, 255), //
+ Math.min(buttonNormal.getBlue() + 100, 255));
+ }
+ }
+
+ button.setSelected(pressed);
+ button.setBackground(pressed ? buttonPressed : buttonNormal);
+ }
+
+ /**
+ * Set the given {@link Window} to full screen mode, on the desktop it
+ * currently resides on.
+ * <p>
+ * Can be cancelled by calling again with a NULL value.
+ *
+ * @param win
+ * the window to set to full screen
+ */
+ static public void setFullscreenWindow(Window win) {
+ GraphicsEnvironment env = GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ GraphicsDevice[] screens = env.getScreenDevices();
+
+ if (win == null) {
+ for (GraphicsDevice screen : screens) {
+ if (win == null) {
+ screen.setFullScreenWindow(null);
+ }
+ }
+
+ return;
+ }
+
+ Rectangle r = win.getBounds();
+ Point center = new Point(r.x + r.width / 2, r.y + r.height / 2);
+
+ GraphicsDevice current = null;
+ for (GraphicsDevice screen : screens) {
+ GraphicsConfiguration[] confs = screen.getConfigurations();
+ for (GraphicsConfiguration conf : confs) {
+ if (conf.getBounds().contains(center)) {
+ current = screen;
+ break;
+ }
+ }
+
+ if (current != null)
+ break;
+ }
+
+ if (current == null) {
+ current = GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice();
+ }
+
+ current.setFullScreenWindow(win);
+ }