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);
}
}
}