package com.drawbridge.syntaxtests; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.SwingUtilities; import javax.swing.UIManager; import com.drawbridge.text.DBDocument; import com.drawbridge.utils.Utils; public class ParsonsTest extends JFrame { /** * */ private static final long serialVersionUID = 5285045907764420446L; public static ParsonsTest instance = null; private Container mContent; private DBDocument doc; private JProgressBar pb = null; private int numberOfPreviousQuestions = 0; private DragNDropPanel ap; public static ParsonsTest getInstance(){ if(instance != null) return instance; else{ instance = new ParsonsTest(); return instance; } } private ParsonsTest(){ super("SyntaxTest"); initUI(); } private void initUI() { setName("DrawBridge SyntaxTest"); setLocation(0, 0); setPreferredSize(new Dimension(1200, 500)); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { Utils.out.println(this.getClass(), "Error setting native LAF: " + e); } setLayout(new BorderLayout()); mContent = getContentPane(); BoxLayout bl = new BoxLayout(mContent, BoxLayout.Y_AXIS); mContent.setLayout(bl); mContent.add(Box.createVerticalStrut(10)); //Add Question Label JLabel question = new JLabel("Move the tiles into the correct positiion."); question.setAlignmentX(Component.CENTER_ALIGNMENT); mContent.add(question); mContent.add(Box.createVerticalGlue()); //Add Answer Panel ap = new DragNDropPanel(); mContent.add(ap); ap.setBorder(BorderFactory.createLineBorder(Color.black)); mContent.add(Box.createVerticalGlue()); //Add Progress Bar pb = new JProgressBar(); pb.setValue(50); mContent.add(pb); mContent.setBackground(Color.white); this.pack(); mContent.setVisible(true); } public enum Answer{ ANSWER_YES, ANSWER_NO, ANSWER_NOTSURE }; class DragNDropPanel extends JPanel{ /** * */ private static final long serialVersionUID = -8826233465168304565L; ArrayList<SyntaxBlock> blockList = new ArrayList<SyntaxBlock>(); ArrayList<DropTarget> dropTargets = new ArrayList<DropTarget>(); public DragNDropPanel(){ setLayout(new BorderLayout()); setLayout(null); setPreferredSize(new Dimension(800, 300)); this.setMaximumSize(new Dimension(800, 300)); setSize(new Dimension(800, 300)); // Add blocks String code = "var x = 2 + 2;"; String [] pieces = code.split("[ ]"); for(int i = 0; i < pieces.length; i++){ SyntaxBlock newBlock = new SyntaxBlock(this, pieces[i]); blockList.add(newBlock); DropTarget newDropTarget = new DropTarget(); dropTargets.add(newDropTarget); add(newDropTarget); add(newBlock); } // BlockDeclaration db = new BlockDeclaration(null, null, "X"); // DropTarget newDrop = new DropTarget(); // add(db); // db.removeMouseListener(db.getMouseListeners()[0]); // db.removeMouseMotionListener(db.getMouseMotionListeners()[0]); // add(newDrop); SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { boolean notAllBlocksHaveGraphics = false; while(notAllBlocksHaveGraphics){ notAllBlocksHaveGraphics = true; for(Component c : DragNDropPanel.this.getComponents()){ if(c.getGraphics() == null) notAllBlocksHaveGraphics = false; } try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } // Position the blocks when we have graphics int currentWidth = 0; ArrayList<SyntaxBlock> tmp = (ArrayList<SyntaxBlock>) blockList.clone(); for(int i = 0; i < blockList.size(); i++){ currentWidth += 10; int index = (int) Math.round(Math.random() * (tmp.size()-1)); tmp.get(index).setLocation(currentWidth, 10); currentWidth += tmp.get(index).getWidth(); tmp.remove(index); } positionDropTargets(); } }); } public ArrayList<DropTarget> getDropTargets() { return dropTargets; } public void positionDropTargets() { int currentWidth = 0; for(int i = 0; i < dropTargets.size(); i++){ currentWidth += 10; dropTargets.get(i).setLocation(currentWidth, 100); if(dropTargets.get(i).syntaxBlock != null) dropTargets.get(i).syntaxBlock.setLocation(currentWidth, 100); currentWidth += dropTargets.get(i).getWidth(); } } } class SyntaxBlock extends JComponent{ /** * */ private static final long serialVersionUID = -6778131075172674136L; String text; DragNDropPanel parent; public SyntaxBlock(DragNDropPanel parent, String text){ this.parent = parent; setSize(new Dimension(30, 50)); this.text = text; setBackground(Color.white); Font font = new Font("Arial", Font.BOLD, 25); setFont(font); SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { int count = 0; while(SyntaxBlock.this.getGraphics() == null && count < 200){ try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } count++; } int requiredWidth = SyntaxBlock.this.getGraphics().getFontMetrics().stringWidth(SyntaxBlock.this.text) + 20; SyntaxBlock.this.setSize(requiredWidth, SyntaxBlock.this.getHeight()); } }); MouseAdapter ma = new MouseAdapter(){ Point mouseDown = null; @Override public void mousePressed(MouseEvent e) { Utils.playClick(); mouseDown = e.getPoint(); Utils.out.println(getClass(), "Point down:" + e.getPoint().toString()); SyntaxBlock.this.getParent().setComponentZOrder(SyntaxBlock.this, 0); } @Override public void mouseDragged(MouseEvent e) { MouseEvent pme = SwingUtilities.convertMouseEvent(e.getComponent(), e, SyntaxBlock.this.getParent()); SyntaxBlock.this.setLocation(pme.getPoint().x - mouseDown.x, pme.getPoint().y - mouseDown.y); } @Override public void mouseReleased(MouseEvent e){ Utils.playClick(); // Get Point in Parent ArrayList<DropTarget> dropTargets = SyntaxBlock.this.parent.getDropTargets(); // Find out which target is the drop target int dropped = -1; for(int i = 0; i < dropTargets.size(); i++){ MouseEvent pme = SwingUtilities.convertMouseEvent(e.getComponent(), e, dropTargets.get(i)); if(dropTargets.get(i).contains(pme.getPoint()) && dropTargets.get(i).syntaxBlock == null){ dropped = i; } } for(int i = 0; i < dropTargets.size(); i++){ DropTarget d = dropTargets.get(i); if(d.syntaxBlock == SyntaxBlock.this){ d.syntaxBlock = null; d.setSize(d.getPreferredSize()); SyntaxBlock.this.parent.positionDropTargets(); } if(i == dropped){ //Then that's the drop target! Utils.out.println(getClass(), "Found target:" + dropTargets.get(i).getLocation().toString()); SyntaxBlock.this.setLocation(dropTargets.get(i).getX(), dropTargets.get(i).getY()); dropTargets.get(i).setSize(SyntaxBlock.this.getWidth(), SyntaxBlock.this.getHeight()); SyntaxBlock.this.parent.positionDropTargets(); dropTargets.get(i).setSyntaxBlock(SyntaxBlock.this); } } } }; addMouseMotionListener(ma); addMouseListener(ma); } @Override public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.setColor(Color.decode("#CCCCCC")); g2.fillRoundRect(0, 0, getWidth()-1, 50, 15, 15); g2.setColor(Color.black); g2.drawString(text, 10, 32); } } class DropTarget extends JComponent{ /** * */ private static final long serialVersionUID = 8493479227913150925L; final Dimension size = new Dimension(30, 50); SyntaxBlock syntaxBlock = null; public DropTarget(){ setSize(new Dimension(30, 50)); setPreferredSize(new Dimension(30, 50)); SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { DropTarget.this.setSize(30, 50); } }); } public void setSyntaxBlock(SyntaxBlock syntaxBlock) { this.syntaxBlock = syntaxBlock; } @Override public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.setColor(Color.white); g2.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 15, 15); g2.setColor(Color.decode("#CCCCCC")); g2.drawRoundRect(0, 0, getWidth()-1, getHeight()-1, 15, 15); } } }