package nodebox.graphics; import clojure.lang.RT; import javax.swing.*; import java.awt.*; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.StringReader; /** * A small application for testing out the graphics functionality. */ public class Playground extends JFrame { private final JTextArea codeArea; private final Viewer viewer; public static final String INITIAL_CODE = "(def p (Path.))\n(.rect p 10 20 30 40)\np"; public Playground() throws HeadlessException { super("Playground"); codeArea = new JTextArea(INITIAL_CODE, 20, 60); codeArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); codeArea.setPreferredSize(new Dimension(400, 400)); viewer = new Viewer(); JMenuBar bar = new JMenuBar(); JMenu codeMenu = new JMenu("Code"); JMenuItem runItem = new JMenuItem(new RunAction()); codeMenu.add(runItem); bar.add(codeMenu); JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, codeArea, viewer); split.setDividerLocation(0.5); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); JButton runButton = new JButton("Run"); buttonPanel.add(runButton); runButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { doRun(); } }); JPanel mainPanel = new JPanel(new BorderLayout()); mainPanel.add(split, BorderLayout.CENTER); mainPanel.add(buttonPanel, BorderLayout.NORTH); setContentPane(mainPanel); setJMenuBar(bar); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setLocationRelativeTo(null); } public static void main(String[] args) { RT.init(); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ignored) { } System.setProperty("apple.laf.useScreenMenuBar", "true"); Playground frame = new Playground(); frame.setVisible(true); frame.codeArea.requestFocus(); frame.doRun(); } private void doRun() { String source = codeArea.getText(); Object o = clojure.lang.Compiler.load(new StringReader("(import '[nodebox.graphics Canvas Color Geometry Image Path PathElement Point Rect Size Text Transform])\n" + source)); viewer.setResult(o); } private static class Viewer extends JComponent { private Object result; @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(java.awt.Color.WHITE); g2.fill(g.getClip()); g2.setColor(java.awt.Color.BLACK); if (result instanceof Grob) { paintElement(g2, (Grob) result); } else { paintObject(g2, result); } } private void paintElement(Graphics2D g, Grob e) { g.setColor(Color.DARK_GRAY); e.draw(g); } private void paintPoints(Graphics2D g, Iterable<Point> points) { g.setColor(java.awt.Color.BLUE); for (Point p : points) { g.fillOval((int) p.x - 2, (int) p.y - 2, 4, 4); } } private void paintObject(Graphics2D g, Object object) { g.setColor(Color.DARK_GRAY); g.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); g.drawString(object == null ? "null" : object.toString(), 10, 20); } public void setResult(Object result) { this.result = result; repaint(); } } private class RunAction extends AbstractAction { private RunAction() { super("Run"); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_R, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); } @Override public void actionPerformed(ActionEvent actionEvent) { doRun(); } } }