/* DigitalGridActionListener.java
* This class defines the Action Listener for the 'Digitzed Molecular Canvas'.
* Whenever this class is initiated, a grid is drawn onto the screen
* on which the user can start drawing.
* The drawing is to be performed by simple clicking on the
* on the grid boxes.
* The user can also deselect a box by clicking on it again.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class DigitalGridActionListener implements ActionListener {
static DrawCanvas canvas;
static Graphics2D graphics2D;
// Set Default Save Flags
static boolean isToBeSaved = false;
static boolean savedFunctionCalled = false;
static JDialog jDialog = new JDialog();
static double brickHeight = 3; // Set default Brick Height
static double brickWidth = 7; // Set default Brick Width
static ArrayList<XYCoordinates> xyCoordinatesBrickList = new ArrayList<XYCoordinates>();
static DrawDataStack digitizedDataStack = new DrawDataStack();
static boolean[][] gridValueAddedArray = new boolean[15][23];
@Override
public void actionPerformed(ActionEvent e) {
if (!MainFrame.newBrickCreated) {
MainFrame.dnaBrick = new DNABrick(brickHeight, brickWidth);
MainFrame.newBrickCreated = true;
}
if (MainFrame.currentWindow == 3) {
canvas.setVisible(false);
xyCoordinatesBrickList.clear();
digitizedDataStack.clearData();
isToBeSaved = false;
MainFrame.newBrickCreated = false;
MainFrame.panelLeft.remove(0);
}
/* This area checks if you're coming from the Free Hand Molecular Canvas
* If yes, then it will give a pop-up to save any unsaved Draw Data
*/
if (MainFrame.currentWindow == 2) {
if (FreeGridActionListener.isToBeSaved && !FreeGridActionListener.savedFunctionCalled) {
Object[] options = {"Yes",
"No",
"Cancel"};
int userChoice = JOptionPane.showOptionDialog(null,
"Would you like to save the DNA Seq before leaving?",
"Save Resource",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[2]);
if (userChoice == 0) { // Yes
JFileChooser jFileChooser = new JFileChooser();
int returnVal = jFileChooser.showSaveDialog(null);
File file = jFileChooser.getSelectedFile();
BufferedWriter bufferedWriter = null;
if (returnVal == JFileChooser.APPROVE_OPTION) {
if(MainFrame.currentWindow == 2) {
try {
FreeGridActionListener.isToBeSaved = false;
ArrayList<Integer> xCoordinateList = FreeGridActionListener.xCoordinateBrickList;
ArrayList<Integer> yCoordinateList = FreeGridActionListener.yCoordinateBrickList;
bufferedWriter = new BufferedWriter(new FileWriter(file.getAbsolutePath() + ".csv"));
writeHeadersCanvas(bufferedWriter, xCoordinateList.size());
bufferedWriter.write("\n\nDraw Sequence Coordinates\n\n");
for (int i = 0; i < xCoordinateList.size(); i++) {
bufferedWriter.write("Brick Number: " + (i + 1));
bufferedWriter.write(",");
bufferedWriter.write("X Coordinate: " + xCoordinateList.get(i));
bufferedWriter.write(",");
bufferedWriter.write("Y Coordinate: " + yCoordinateList.get(i) + "\n");
}
bufferedWriter.write("\n\nDNA Brick Sequence\n\n");
bufferedWriter.write(MainFrame.dnaBrick.toString());
bufferedWriter.write("\n\n Generated using DNA Pen. (http://www.guptalab.org/dnapen/)");
bufferedWriter.close();
JOptionPane.showMessageDialog(null, "File Saved Successfully !",
"Success!", JOptionPane.INFORMATION_MESSAGE);
FreeGridActionListener.savedFunctionCalled = true;
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "The File could not be Saved!",
"Error!", JOptionPane.INFORMATION_MESSAGE);
}
}
}
} else if (userChoice == 2) { // Cancel
return;
}
}
// Reset and clear Free Hand Molecular Canvas from the screen.
FreeGridActionListener.canvas.setVisible(false);
FreeGridActionListener.xCoordinateBrickList.clear();
FreeGridActionListener.yCoordinateBrickList.clear();
FreeGridActionListener.isToBeSaved = false;
MainFrame.newBrickCreated = false;
MainFrame.panelLeft.remove(0);
}
// Set value of currentWindow to 3 to indicate that Digital Molecular Canvas is active.
MainFrame.currentWindow = 3;
MainFrame.mainFrame.setTitle("DNA Pen - Digitised Molecular Canvas");
MainFrame.mainFrame.setExtendedState(Frame.MAXIMIZED_BOTH);
// Define the Canvas and the Output Box
JPanel jPanel = new JPanel();
MainFrame.panelLeft.add(jPanel);
jPanel.setSize(1366, 700);
jPanel.setLayout(new GridLayout(1, 1));
canvas = new DrawCanvas();
jPanel.add(canvas);
canvas.setVisible(true);
MainFrame.mainFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent arg0) {
System.out.println("\nOpened");
}
@Override
public void windowIconified(WindowEvent arg0) {
System.out.println("\nMinimed");
// jPanel.setVisible(false);
}
@Override
public void windowDeiconified(WindowEvent arg0) {
System.out.println("\nMaximized");
// jPanel.setVisible(true);
}
@Override
public void windowActivated(WindowEvent arg0) {
System.out.println("\nActivated");
// jPanel.setVisible(true);
}
});
// MainFrame.panelLeft.add(jPanel);
// MainFrame.mainFrame.pack();
}
// Draw Method
public class DrawCanvas extends Canvas {
BasicStroke basicStroke;
int X, Y, pressed = 0;
float dashes[] = { 5f, 5f };
public DrawCanvas() {
for(int i = 0; i < 15; i++) {
for(int j = 0; j < 23; j++) {
gridValueAddedArray[i][j] = false;
}
}
xyCoordinatesBrickList.clear();
digitizedDataStack.clearData();
setBackground(Color.white);
addMouseListener(new MyMouseListener());
addMouseMotionListener(new MyMouseListener());
setSize(1366, 680);
basicStroke = new BasicStroke(1f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL, 10f, dashes, 0f);
}
@Override
public void update(Graphics g) {
paint(g);
}
@Override
public void paint(Graphics g) {
graphics2D = (Graphics2D) g;
if(pressed == 1) {
graphics2D.setColor(Color.black);
graphics2D.setStroke(basicStroke);
System.out.println(X - (X % 90));
System.out.println(Y - (Y % 30));
if (!gridValueAddedArray[X / 90][Y / 30]) {
fillElement(X, Y);
} else {
removeElement(X, Y);
}
} else if (pressed == 2) {
graphics2D.setColor(Color.white);
graphics2D.fillRect(0, 0, 1366, 680);
for(int i = 0; i < 15; i++) {
for(int j = 0; j < 23; j++) {
gridValueAddedArray[i][j] = false;
}
}
xyCoordinatesBrickList.clear();
digitizedDataStack.clearData();
int constY = 0;
int constX = 0;
graphics2D.setColor(Color.black);
while (constY < 680) {
graphics2D.draw(new Line2D.Float(0, constY, 1366, constY));
constY += 30;
}
while (constX < 1366) {
graphics2D.draw(new Line2D.Float(constX, 0, constX, 680));
constX += 90;
}
} else if (pressed == 4) {
XYCoordinates xyCoordinates = DigitalGridActionListener.digitizedDataStack.popData();
int X = xyCoordinates.getxCoordinate();
int Y = xyCoordinates.getyCoordinate();
undoAction(X, Y);
} else {
int constY = 0;
int constX = 0;
while (constY < 680) {
graphics2D.draw(new Line2D.Float(0, constY, 1366, constY));
constY += 30;
}
while (constX < 1366) {
graphics2D.draw(new Line2D.Float(constX, 0, constX, 680));
constX += 90;
}
}
}
public void undoAction(int xCoordinate, int yCoordinate) {
int constY = 0;
int constX = 0;
while (constY < 680) {
graphics2D.draw(new Line2D.Float(0, constY, 1366, constY));
constY += 30;
}
while (constX < 1366) {
graphics2D.draw(new Line2D.Float(constX, 0, constX, 680));
constX += 90;
}
System.out.println("\n" + (xCoordinate - (xCoordinate % 90)));
System.out.println("\n" + (yCoordinate - (yCoordinate % 30)));
System.out.println("\nUndo How Many Times");
graphics2D.setColor(Color.white);
graphics2D.fillRect(xCoordinate - (xCoordinate % 90), yCoordinate - (yCoordinate % 30), 90, 30);
gridValueAddedArray[xCoordinate / 90][yCoordinate / 30] = false;
int xValue = 0;
int yValue = 0;
for (int i = 0; i < xyCoordinatesBrickList.size(); i++) {
xValue = xyCoordinatesBrickList.get(i).getxCoordinate();
yValue = xyCoordinatesBrickList.get(i).getyCoordinate();
if (xValue == (xCoordinate / 90) && yValue == (yCoordinate / 30)) {
xyCoordinatesBrickList.remove(i);
}
}
pressed = 0;
}
public void fillElement(int xCoordinate, int yCoordinate) {
graphics2D.setColor(Color.lightGray);
graphics2D.fillRect(xCoordinate - (xCoordinate % 90), yCoordinate - (yCoordinate % 30), 90, 30);
gridValueAddedArray[xCoordinate / 90][yCoordinate / 30] = true;
xyCoordinatesBrickList.add(new XYCoordinates(xCoordinate / 90, yCoordinate / 30));
digitizedDataStack.pushData(new XYCoordinates(xCoordinate, yCoordinate));
}
public void removeElement(int xCoordinate, int yCoordinate) {
graphics2D.setColor(Color.white);
graphics2D.fillRect(xCoordinate - (xCoordinate % 90), yCoordinate - (yCoordinate % 30), 90, 30);
gridValueAddedArray[xCoordinate / 90][yCoordinate / 30] = false;
digitizedDataStack.removeSpecificElement(xCoordinate, yCoordinate);
int xValue = 0;
int yValue = 0;
for (int i = 0; i < xyCoordinatesBrickList.size(); i++) {
xValue = xyCoordinatesBrickList.get(i).getxCoordinate();
yValue = xyCoordinatesBrickList.get(i).getyCoordinate();
if (xValue == (xCoordinate / 90) && yValue == (yCoordinate / 30)) {
xyCoordinatesBrickList.remove(i);
}
}
}
class MyMouseListener extends MouseAdapter implements MouseMotionListener {
@Override
public void mousePressed(MouseEvent e) {
isToBeSaved = true;
savedFunctionCalled = false;
pressed = 1;
X = e.getX();
Y = e.getY();
canvas.repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
pressed = 0;
canvas.repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
canvas.repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
String string = "(" + Integer.toString(e.getX()) + ", "
+ Integer.toString(e.getY()) + ")";
canvas.repaint();
}
}
}
public void writeHeadersCanvas(BufferedWriter bufferedWriter, int listSize) {
try {
double brickHeight = MainFrame.dnaBrick.getBrickHeight();
double brickWidth = MainFrame.dnaBrick.getBrickWidth();
int minWidth = (int)(brickWidth / 1.75);
int minHeight = (int)(brickHeight / .6);
int[] halfTiles = calcHalfTiles(brickHeight, brickWidth);
int fullTiles = calcFullTiles(brickHeight, brickWidth);
int stickyEnds = calcStickyEnds(brickHeight, brickWidth);
int totalNumberSeq = calcTotalNumberSeq(halfTiles, fullTiles, stickyEnds);
DNADomains dnaDomains = MainFrame.dnaBrick.getDnaDomains();
bufferedWriter.write("Base DNA Sequence: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqOne() + dnaDomains.getDomainSeqTwo() +
dnaDomains.getDomainSeqThree() + dnaDomains.getDomainSeqFour() + "\n\n");
bufferedWriter.write("Domain Sequence 1: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqOne() + "\n");
bufferedWriter.write("Domain Sequence 2: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqTwo() + "\n");
bufferedWriter.write("Domain Sequence 3: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqThree() + "\n");
bufferedWriter.write("Domain Sequence 4: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqFour() + "\n");
bufferedWriter.write("Brick Height: ");
bufferedWriter.write(",");
bufferedWriter.write(Double.toString(brickHeight) + " nm" + "\n");
bufferedWriter.write("Brick Width: ");
bufferedWriter.write(",");
bufferedWriter.write(Double.toString(brickWidth) + " nm" + "\n\n");
bufferedWriter.write("Total Number of Bricks: ");
bufferedWriter.write(",");
bufferedWriter.write(listSize + "\n");
bufferedWriter.write("Number of Base DNA Sequences Required: ");
bufferedWriter.write(",");
bufferedWriter.write(totalNumberSeq * listSize + "\n\n");
bufferedWriter.write("Half-Tile Sequence of Domain 1 and Domain 2: ( L1.1 - L1." + minWidth +
" )" );
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqOne() + dnaDomains.getDomainSeqTwo() + "\n");
bufferedWriter.write("Required number of Half-Tiles: ");
bufferedWriter.write(",");
bufferedWriter.write((halfTiles[0] / 2) + "\n\n");
bufferedWriter.write("Half-Tile Sequence of Domain 3 and Domain 4: ( L" + (minHeight + 1) + ".1 - L"
+ (minHeight + 1) + "." + minWidth + " )");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqThree() + dnaDomains.getDomainSeqFour() + "\n");
bufferedWriter.write("Required number of Half-Tiles: ");
bufferedWriter.write(",");
bufferedWriter.write((halfTiles[0] / 2) + "\n\n");
bufferedWriter.write("Half-Tile Sequence of Domain 2 and Domain 3: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqTwo() + dnaDomains.getDomainSeqThree() + "\n");
bufferedWriter.write("Required number of Half-Tiles: ");
bufferedWriter.write(",");
bufferedWriter.write((halfTiles[1] / 2) * listSize + "\n\n");
bufferedWriter.write("Half-Tile Sequence of Domain 1 and Domain 4: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqOne() + dnaDomains.getDomainSeqFour() + "\n");
bufferedWriter.write("Required number of Half-Tiles: ");
bufferedWriter.write(",");
bufferedWriter.write((halfTiles[1] / 2) * listSize + "\n\n");
bufferedWriter.write("Full-Tile Sequence: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqOne() + dnaDomains.getDomainSeqTwo() +
dnaDomains.getDomainSeqThree() + dnaDomains.getDomainSeqFour() + "\n");
bufferedWriter.write("Required number of Full-Tiles: ");
bufferedWriter.write(",");
bufferedWriter.write(fullTiles * listSize + "\n\n");
bufferedWriter.write("Sticky-End Sequence of Domain 1 and Domain 4: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqOne() + dnaDomains.getDomainSeqFour() + "\n");
bufferedWriter.write("Required number of Sticky Ends: ");
bufferedWriter.write(",");
bufferedWriter.write((stickyEnds / 2) * listSize + "\n\n");
bufferedWriter.write("Sticky-End Sequence of Domain 2 and Domain 3: ");
bufferedWriter.write(",");
bufferedWriter.write(dnaDomains.getDomainSeqTwo() + dnaDomains.getDomainSeqThree() + "\n");
bufferedWriter.write("Required number of Sticky Ends: ");
bufferedWriter.write(",");
bufferedWriter.write((stickyEnds / 2) * listSize + "\n\n");
} catch (Exception e1) {
JOptionPane.showMessageDialog(null, "Exception Occurred !",
"Error!", JOptionPane.INFORMATION_MESSAGE);
}
}
public int[] calcHalfTiles(double brickHeight, double brickWidth) {
int[] halfTiles = new int[2];
for (int i = 0; i < halfTiles.length; i++) {
halfTiles[i] = 0;
}
halfTiles[0] += 2 * (brickWidth / 1.75);
halfTiles[1] += 2 * Math.ceil(brickHeight / 1.2);
return halfTiles;
}
public int calcFullTiles(double brickHeight, double brickWidth) {
int fullTiles = 0;
int oddRows = (int) Math.ceil(brickHeight / 1.2);
int evenRows = (int)(brickHeight / 0.6) - oddRows;
fullTiles += oddRows * ((brickWidth / 1.75) - 1);
fullTiles += evenRows * (brickWidth /1.75);
return fullTiles;
}
public int calcStickyEnds(double brickHeight, double brickWidth) {
int stickyEnds = 0;
stickyEnds += 2 * Math.ceil(brickHeight / 1.2);
return stickyEnds;
}
public int calcTotalNumberSeq(int[] halfTiles, int fullTiles, int stickyEnds) {
int totalNumberSeq = 0;
for (int i = 0; i < halfTiles.length; i++) {
totalNumberSeq += halfTiles[i];
}
totalNumberSeq = totalNumberSeq / 2;
totalNumberSeq += fullTiles;
totalNumberSeq += stickyEnds / 2;
return totalNumberSeq;
}
}
每当我最小化窗口时,画布上的数据都会被清理并返回空画布......如何在最小化窗口的同时保存状态......我试图在鼠标侦听器上重新绘制,但它没有用