package com.levigo.samplelib.ui; import java.awt.BorderLayout; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import jsyntaxpane.DefaultSyntaxKit; import com.google.common.io.ByteStreams; import com.google.common.io.CharStreams; import com.google.common.io.InputSupplier; public class SourceViewerFrame extends JFrame { private static final long serialVersionUID = 1L; private static final class ByteArraySourceInputSupplier implements NamedInputSupplier<String> { private final byte[] data; private final String name; private ByteArraySourceInputSupplier(byte[] data, String name) { this.data = data; this.name = name; } @Override public String getInput() throws IOException { return CharStreams.toString(CharStreams.newReaderSupplier(ByteStreams.newInputStreamSupplier(data), Charset.defaultCharset())); } @Override public String getName() { return name; } } public static interface NamedInputSupplier<T> extends InputSupplier<T> { String getName(); } private static class StringInputSupplier implements NamedInputSupplier<String> { private final String input; private final String name; public StringInputSupplier(String name, String input) { super(); this.name = name; this.input = input; } @Override public String getInput() throws IOException { return input; } @Override public String getName() { return name; } } @SuppressWarnings("unchecked") public static SourceViewerFrame forBinary(final String name, final byte[] data) { return new SourceViewerFrame(new ByteArraySourceInputSupplier(data, name)); } @SuppressWarnings("unchecked") public static SourceViewerFrame forClasses(Class<?>... classes) { final NamedInputSupplier<String>[] inputs = new NamedInputSupplier[classes.length]; for (int i = 0; i < inputs.length; i++) { inputs[i] = resolveClassSource(classes[i]); } return new SourceViewerFrame(inputs); } @SuppressWarnings("unchecked") public static SourceViewerFrame forString(final String name, final String data) { return new SourceViewerFrame(new StringInputSupplier(name, data)); } private static NamedInputSupplier<String> resolveClassSource(final Class<?> c) { return new NamedInputSupplier<String>() { @Override public String getInput() throws IOException { return CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() { @Override public InputStream getInput() throws IOException { final String filename = '/' + c.getName().replace('.', '/') + ".java"; return SourceViewerFrame.class.getResourceAsStream(filename); } }, Charset.defaultCharset())); } @Override public String getName() { return c.getSimpleName(); } }; } public SourceViewerFrame(NamedInputSupplier<String>... input) { setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setSize(800, 600); getContentPane().setLayout(new BorderLayout()); final JTabbedPane tabbedPane = new JTabbedPane(); getContentPane().add(tabbedPane); for (NamedInputSupplier<String> in : input) { final JEditorPane editorPane = new JEditorPane(); tabbedPane.addTab(in.getName(), new JScrollPane(editorPane)); editorPane.setEditable(false); if (in.getName().endsWith(".xml")) editorPane.setContentType("text/xml"); else editorPane.setContentType("text/java"); try { editorPane.setText(in.getInput()); } catch (IOException e) { e.printStackTrace(); editorPane.setText("FAILED TO LOAD SOURCE CODE"); } } } }