package arcane.ui.util;
import com.google.common.collect.MapMaker;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.text.Element;
import javax.swing.text.StyleConstants;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.ImageView;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.concurrent.ConcurrentMap;
/**
* UI utility functions.
*
* @author Forge
* @version $Id: UI.java 10038 2011-06-25 08:29:06Z jendave.hudson@gmail.com $
*/
public class UI {
/** Constant <code>imageCache</code> */
static private ConcurrentMap<URI, Image> imageCache = new MapMaker().softValues().makeMap();
/**
* <p>getToggleButton.</p>
*
* @return a {@link javax.swing.JToggleButton} object.
*/
static public JToggleButton getToggleButton() {
JToggleButton button = new JToggleButton();
button.setMargin(new Insets(2, 4, 2, 4));
return button;
}
/**
* <p>getButton.</p>
*
* @return a {@link javax.swing.JButton} object.
*/
static public JButton getButton() {
JButton button = new JButton();
button.setMargin(new Insets(2, 4, 2, 4));
return button;
}
/**
* <p>setTitle.</p>
*
* @param panel a {@link javax.swing.JPanel} object.
* @param title a {@link java.lang.String} object.
*/
static public void setTitle(JPanel panel, String title) {
Border border = panel.getBorder();
if (border instanceof TitledBorder) {
((TitledBorder) panel.getBorder()).setTitle(title);
panel.repaint();
} else
panel.setBorder(BorderFactory.createTitledBorder(title));
}
/**
* <p>getFileURL.</p>
*
* @param path a {@link java.lang.String} object.
* @return a {@link java.net.URL} object.
*/
static public URL getFileURL(String path) {
File file = new File(path);
if (file.exists()) {
try {
return file.toURI().toURL();
} catch (MalformedURLException ignored) {
}
}
return UI.class.getResource(path);
}
/**
* <p>getImageIcon.</p>
*
* @param path a {@link java.lang.String} object.
* @return a {@link javax.swing.ImageIcon} object.
*/
static public ImageIcon getImageIcon(String path) {
InputStream stream = null;
try {
try {
stream = UI.class.getResourceAsStream(path);
if (stream == null && new File(path).exists()) stream = new FileInputStream(path);
if (stream == null) throw new RuntimeException("Image not found: " + path);
byte[] data = new byte[stream.available()];
stream.read(data);
return new ImageIcon(data);
} finally {
if (stream != null)
stream.close();
}
} catch (IOException ex) {
throw new RuntimeException("Error reading image: " + path);
}
}
/**
* <p>setHTMLEditorKit.</p>
*
* @param editorPane a {@link javax.swing.JEditorPane} object.
*/
static public void setHTMLEditorKit(JEditorPane editorPane) {
editorPane.getDocument().putProperty("imageCache", imageCache); // Read internally by ImageView, but never written.
// Extend all this shit to cache images.
editorPane.setEditorKit(new HTMLEditorKit() {
private static final long serialVersionUID = -562969765076450440L;
public ViewFactory getViewFactory() {
return new HTMLFactory() {
public View create(Element elem) {
Object o = elem.getAttributes().getAttribute(StyleConstants.NameAttribute);
if (o instanceof HTML.Tag) {
HTML.Tag kind = (HTML.Tag) o;
if (kind == HTML.Tag.IMG) return new ImageView(elem) {
public URL getImageURL() {
URL url = super.getImageURL();
// Put an image into the cache to be read by other ImageView methods.
if (url != null && imageCache.get(url) == null)
try {
imageCache.put(url.toURI(), Toolkit.getDefaultToolkit().createImage(url));
} catch (URISyntaxException e) {
}
return url;
}
};
}
return super.create(elem);
}
};
}
});
}
/**
* <p>setVerticalScrollingView.</p>
*
* @param scrollPane a {@link javax.swing.JScrollPane} object.
* @param view a {@link java.awt.Component} object.
*/
static public void setVerticalScrollingView(JScrollPane scrollPane, final Component view) {
final JViewport viewport = new JViewport();
viewport.setLayout(new ViewportLayout() {
private static final long serialVersionUID = -4436977380450713628L;
public void layoutContainer(Container parent) {
viewport.setViewPosition(new Point(0, 0));
Dimension viewportSize = viewport.getSize();
int width = viewportSize.width;
int height = Math.max(view.getPreferredSize().height, viewportSize.height);
viewport.setViewSize(new Dimension(width, height));
}
});
viewport.setView(view);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setViewport(viewport);
}
/**
* <p>getDisplayManaCost.</p>
*
* @param manaCost a {@link java.lang.String} object.
* @return a {@link java.lang.String} object.
*/
static public String getDisplayManaCost(String manaCost) {
manaCost = manaCost.replace("/", "");
manaCost = manaCost.replace("X 0", "X");
// A pipe in the cost means "process left of the pipe as the card color, but display right of the pipe as the cost".
int pipePosition = manaCost.indexOf("{|}");
if (pipePosition != -1) manaCost = manaCost.substring(pipePosition + 3);
return manaCost;
}
/**
* <p>invokeLater.</p>
*
* @param runnable a {@link java.lang.Runnable} object.
*/
static public void invokeLater(Runnable runnable) {
EventQueue.invokeLater(runnable);
}
/**
* <p>invokeAndWait.</p>
*
* @param runnable a {@link java.lang.Runnable} object.
*/
static public void invokeAndWait(Runnable runnable) {
if (EventQueue.isDispatchThread()) {
runnable.run();
return;
}
try {
EventQueue.invokeAndWait(runnable);
} catch (InterruptedException ex) {
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}
/**
* <p>setSystemLookAndFeel.</p>
*/
static public void setSystemLookAndFeel() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
System.err.println("Error setting look and feel:");
ex.printStackTrace();
}
}
/**
* <p>setDefaultFont.</p>
*
* @param font a {@link java.awt.Font} object.
*/
static public void setDefaultFont(Font font) {
for (Object key : Collections.list(UIManager.getDefaults().keys())) {
Object value = UIManager.get(key);
if (value instanceof javax.swing.plaf.FontUIResource) UIManager.put(key, font);
}
}
}