Guest User

Untitled

a guest
Apr 25th, 2018
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.80 KB | None | 0 0
  1. /*
  2. * ===================================================
  3. * contents
  4. * ===================================================
  5. * 00- Free draw
  6. * 01- rubber
  7. * 02- draw Line
  8. * 03- draw Rectangele
  9. * 04- draw Circle
  10. * 05- draw Ellipse
  11. * 06- Text
  12. *
  13. * ----------------------------------------------------
  14. * Features
  15. * ----------------------------------------------------
  16. * - the ability to change Line color
  17. * - the ability to change Fill color
  18. * - the ability to change Line width
  19. * - Undo & Redo
  20. * - Open Image && save Image
  21. *
  22. * ____________________________________________________
  23. * problems
  24. * - undo & redo : not working with free draw and rubber
  25. * - Line & Rect & Circ ... aren't be updated while drawing
  26. * ===================================================
  27. */
  28. package paint;
  29.  
  30. import java.awt.image.RenderedImage;
  31. import java.io.File;
  32. import java.io.FileInputStream;
  33. import java.io.IOException;
  34. import java.io.InputStream;
  35. import java.util.Stack;
  36. import javafx.application.Application;
  37. import javafx.embed.swing.SwingFXUtils;
  38. import javafx.geometry.Insets;
  39. import javafx.scene.Cursor;
  40. import javafx.scene.Scene;
  41. import javafx.scene.canvas.Canvas;
  42. import javafx.scene.canvas.GraphicsContext;
  43. import javafx.scene.control.Button;
  44. import javafx.scene.control.ColorPicker;
  45. import javafx.scene.control.Label;
  46. import javafx.scene.control.Slider;
  47. import javafx.scene.control.TextArea;
  48. import javafx.scene.control.ToggleButton;
  49. import javafx.scene.control.ToggleGroup;
  50. import javafx.scene.image.Image;
  51. import javafx.scene.image.WritableImage;
  52. import javafx.scene.layout.BorderPane;
  53. import javafx.scene.layout.VBox;
  54. import javafx.scene.paint.Color;
  55. import javafx.scene.shape.Circle;
  56. import javafx.scene.shape.Ellipse;
  57. import javafx.scene.shape.Line;
  58. import javafx.scene.shape.Rectangle;
  59. import javafx.scene.shape.Shape;
  60. import javafx.scene.text.Font;
  61. import javafx.stage.FileChooser;
  62. import javafx.stage.Stage;
  63. import javax.imageio.ImageIO;
  64.  
  65. public class Paint extends Application {
  66.  
  67. @Override
  68. public void start(Stage primaryStage) {
  69. Stack<Shape> undoHistory = new Stack();
  70. Stack<Shape> redoHistory = new Stack();
  71.  
  72. /* ----------btns---------- */
  73. ToggleButton drowbtn = new ToggleButton("Draw");
  74. ToggleButton rubberbtn = new ToggleButton("Rubber");
  75. ToggleButton linebtn = new ToggleButton("Line");
  76. ToggleButton rectbtn = new ToggleButton("Rectange");
  77. ToggleButton circlebtn = new ToggleButton("Circle");
  78. ToggleButton elpslebtn = new ToggleButton("Ellipse");
  79. ToggleButton textbtn = new ToggleButton("Text");
  80.  
  81. ToggleButton[] toolsArr = {drowbtn, rubberbtn, linebtn, rectbtn, circlebtn, elpslebtn, textbtn};
  82.  
  83. ToggleGroup tools = new ToggleGroup();
  84.  
  85. for (ToggleButton tool : toolsArr) {
  86. tool.setMinWidth(90);
  87. tool.setToggleGroup(tools);
  88. tool.setCursor(Cursor.HAND);
  89. }
  90.  
  91. ColorPicker cpLine = new ColorPicker(Color.BLACK);
  92. ColorPicker cpFill = new ColorPicker(Color.TRANSPARENT);
  93.  
  94. TextArea text = new TextArea();
  95. text.setPrefRowCount(1);
  96.  
  97. Slider slider = new Slider(1, 50, 3);
  98. slider.setShowTickLabels(true);
  99. slider.setShowTickMarks(true);
  100.  
  101. Label line_color = new Label("Line Color");
  102. Label fill_color = new Label("Fill Color");
  103. Label line_width = new Label("3.0");
  104.  
  105. Button undo = new Button("Undo");
  106. Button redo = new Button("Redo");
  107. Button save = new Button("Save");
  108. Button open = new Button("Open");
  109.  
  110. Button[] basicArr = {undo, redo, save, open};
  111.  
  112. for(Button btn : basicArr) {
  113. btn.setMinWidth(90);
  114. btn.setCursor(Cursor.HAND);
  115. btn.setTextFill(Color.WHITE);
  116. btn.setStyle("-fx-background-color: #666;");
  117. }
  118. save.setStyle("-fx-background-color: #80334d;");
  119. open.setStyle("-fx-background-color: #80334d;");
  120.  
  121. VBox btns = new VBox(10);
  122. btns.getChildren().addAll(drowbtn, rubberbtn, linebtn, rectbtn, circlebtn, elpslebtn,
  123. textbtn, text, line_color, cpLine, fill_color, cpFill, line_width, slider, undo, redo, open, save);
  124. btns.setPadding(new Insets(5));
  125. btns.setStyle("-fx-background-color: #999");
  126. btns.setPrefWidth(100);
  127.  
  128. /* ----------Drow Canvas---------- */
  129. Canvas canvas = new Canvas(1080, 790);
  130. GraphicsContext gc;
  131. gc = canvas.getGraphicsContext2D();
  132. gc.setLineWidth(1);
  133.  
  134. Line line = new Line();
  135. Rectangle rect = new Rectangle();
  136. Circle circ = new Circle();
  137. Ellipse elps = new Ellipse();
  138.  
  139. canvas.setOnMousePressed(e->{
  140. if(drowbtn.isSelected()) {
  141. gc.setStroke(cpLine.getValue());
  142. gc.beginPath();
  143. gc.lineTo(e.getX(), e.getY());
  144. }
  145. else if(rubberbtn.isSelected()) {
  146. double lineWidth = gc.getLineWidth();
  147. gc.clearRect(e.getX() - lineWidth / 2, e.getY() - lineWidth / 2, lineWidth, lineWidth);
  148. }
  149. else if(linebtn.isSelected()) {
  150. gc.setStroke(cpLine.getValue());
  151. line.setStartX(e.getX());
  152. line.setStartY(e.getY());
  153. }
  154. else if(rectbtn.isSelected()) {
  155. gc.setStroke(cpLine.getValue());
  156. gc.setFill(cpFill.getValue());
  157. rect.setX(e.getX());
  158. rect.setY(e.getY());
  159. }
  160. else if(circlebtn.isSelected()) {
  161. gc.setStroke(cpLine.getValue());
  162. gc.setFill(cpFill.getValue());
  163. circ.setCenterX(e.getX());
  164. circ.setCenterY(e.getY());
  165. }
  166. else if(elpslebtn.isSelected()) {
  167. gc.setStroke(cpLine.getValue());
  168. gc.setFill(cpFill.getValue());
  169. elps.setCenterX(e.getX());
  170. elps.setCenterY(e.getY());
  171. }
  172. else if(textbtn.isSelected()) {
  173. gc.setLineWidth(1);
  174. gc.setFont(Font.font(slider.getValue()));
  175. gc.setStroke(cpLine.getValue());
  176. gc.setFill(cpFill.getValue());
  177. gc.fillText(text.getText(), e.getX(), e.getY());
  178. gc.strokeText(text.getText(), e.getX(), e.getY());
  179. }
  180. });
  181.  
  182. canvas.setOnMouseDragged(e->{
  183. if(drowbtn.isSelected()) {
  184. gc.lineTo(e.getX(), e.getY());
  185. gc.stroke();
  186. }
  187. else if(rubberbtn.isSelected()){
  188. double lineWidth = gc.getLineWidth();
  189. gc.clearRect(e.getX() - lineWidth / 2, e.getY() - lineWidth / 2, lineWidth, lineWidth);
  190. }
  191. });
  192.  
  193. canvas.setOnMouseReleased(e->{
  194. if(drowbtn.isSelected()) {
  195. gc.lineTo(e.getX(), e.getY());
  196. gc.stroke();
  197. gc.closePath();
  198. }
  199. else if(rubberbtn.isSelected()) {
  200. double lineWidth = gc.getLineWidth();
  201. gc.clearRect(e.getX() - lineWidth / 2, e.getY() - lineWidth / 2, lineWidth, lineWidth);
  202. }
  203. else if(linebtn.isSelected()) {
  204. line.setEndX(e.getX());
  205. line.setEndY(e.getY());
  206. gc.strokeLine(line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY());
  207.  
  208. undoHistory.push(new Line(line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY()));
  209. }
  210. else if(rectbtn.isSelected()) {
  211. rect.setWidth(Math.abs((e.getX() - rect.getX())));
  212. rect.setHeight(Math.abs((e.getY() - rect.getY())));
  213. //rect.setX((rect.getX() > e.getX()) ? e.getX(): rect.getX());
  214. if(rect.getX() > e.getX()) {
  215. rect.setX(e.getX());
  216. }
  217. //rect.setY((rect.getY() > e.getY()) ? e.getY(): rect.getY());
  218. if(rect.getY() > e.getY()) {
  219. rect.setY(e.getY());
  220. }
  221.  
  222. gc.fillRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
  223. gc.strokeRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
  224.  
  225. undoHistory.push(new Rectangle(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()));
  226.  
  227. }
  228. else if(circlebtn.isSelected()) {
  229. circ.setRadius((Math.abs(e.getX() - circ.getCenterX()) + Math.abs(e.getY() - circ.getCenterY())) / 2);
  230.  
  231. if(circ.getCenterX() > e.getX()) {
  232. circ.setCenterX(e.getX());
  233. }
  234. if(circ.getCenterY() > e.getY()) {
  235. circ.setCenterY(e.getY());
  236. }
  237.  
  238. gc.fillOval(circ.getCenterX(), circ.getCenterY(), circ.getRadius(), circ.getRadius());
  239. gc.strokeOval(circ.getCenterX(), circ.getCenterY(), circ.getRadius(), circ.getRadius());
  240.  
  241. undoHistory.push(new Circle(circ.getCenterX(), circ.getCenterY(), circ.getRadius()));
  242. }
  243. else if(elpslebtn.isSelected()) {
  244. elps.setRadiusX(Math.abs(e.getX() - elps.getCenterX()));
  245. elps.setRadiusY(Math.abs(e.getY() - elps.getCenterY()));
  246.  
  247. if(elps.getCenterX() > e.getX()) {
  248. elps.setCenterX(e.getX());
  249. }
  250. if(elps.getCenterY() > e.getY()) {
  251. elps.setCenterY(e.getY());
  252. }
  253.  
  254. gc.strokeOval(elps.getCenterX(), elps.getCenterY(), elps.getRadiusX(), elps.getRadiusY());
  255. gc.fillOval(elps.getCenterX(), elps.getCenterY(), elps.getRadiusX(), elps.getRadiusY());
  256.  
  257. undoHistory.push(new Ellipse(elps.getCenterX(), elps.getCenterY(), elps.getRadiusX(), elps.getRadiusY()));
  258. }
  259. redoHistory.clear();
  260. Shape lastUndo = undoHistory.lastElement();
  261. lastUndo.setFill(gc.getFill());
  262. lastUndo.setStroke(gc.getStroke());
  263. lastUndo.setStrokeWidth(gc.getLineWidth());
  264.  
  265. });
  266. // color picker
  267. cpLine.setOnAction(e->{
  268. gc.setStroke(cpLine.getValue());
  269. });
  270. cpFill.setOnAction(e->{
  271. gc.setFill(cpFill.getValue());
  272. });
  273.  
  274. // slider
  275. slider.valueProperty().addListener(e->{
  276. double width = slider.getValue();
  277. if(textbtn.isSelected()){
  278. gc.setLineWidth(1);
  279. gc.setFont(Font.font(slider.getValue()));
  280. line_width.setText(String.format("%.1f", width));
  281. return;
  282. }
  283. line_width.setText(String.format("%.1f", width));
  284. gc.setLineWidth(width);
  285. });
  286.  
  287. /*------- Undo & Redo ------*/
  288. // Undo
  289. undo.setOnAction(e->{
  290. if(!undoHistory.empty()){
  291. gc.clearRect(0, 0, 1080, 790);
  292. Shape removedShape = undoHistory.lastElement();
  293. if(removedShape.getClass() == Line.class) {
  294. Line tempLine = (Line) removedShape;
  295. tempLine.setFill(gc.getFill());
  296. tempLine.setStroke(gc.getStroke());
  297. tempLine.setStrokeWidth(gc.getLineWidth());
  298. redoHistory.push(new Line(tempLine.getStartX(), tempLine.getStartY(), tempLine.getEndX(), tempLine.getEndY()));
  299.  
  300. }
  301. else if(removedShape.getClass() == Rectangle.class) {
  302. Rectangle tempRect = (Rectangle) removedShape;
  303. tempRect.setFill(gc.getFill());
  304. tempRect.setStroke(gc.getStroke());
  305. tempRect.setStrokeWidth(gc.getLineWidth());
  306. redoHistory.push(new Rectangle(tempRect.getX(), tempRect.getY(), tempRect.getWidth(), tempRect.getHeight()));
  307. }
  308. else if(removedShape.getClass() == Circle.class) {
  309. Circle tempCirc = (Circle) removedShape;
  310. tempCirc.setStrokeWidth(gc.getLineWidth());
  311. tempCirc.setFill(gc.getFill());
  312. tempCirc.setStroke(gc.getStroke());
  313. redoHistory.push(new Circle(tempCirc.getCenterX(), tempCirc.getCenterY(), tempCirc.getRadius()));
  314. }
  315. else if(removedShape.getClass() == Ellipse.class) {
  316. Ellipse tempElps = (Ellipse) removedShape;
  317. tempElps.setFill(gc.getFill());
  318. tempElps.setStroke(gc.getStroke());
  319. tempElps.setStrokeWidth(gc.getLineWidth());
  320. redoHistory.push(new Ellipse(tempElps.getCenterX(), tempElps.getCenterY(), tempElps.getRadiusX(), tempElps.getRadiusY()));
  321. }
  322. Shape lastRedo = redoHistory.lastElement();
  323. lastRedo.setFill(removedShape.getFill());
  324. lastRedo.setStroke(removedShape.getStroke());
  325. lastRedo.setStrokeWidth(removedShape.getStrokeWidth());
  326. undoHistory.pop();
  327.  
  328. for(int i=0; i < undoHistory.size(); i++) {
  329. Shape shape = undoHistory.elementAt(i);
  330. if(shape.getClass() == Line.class) {
  331. Line temp = (Line) shape;
  332. gc.setLineWidth(temp.getStrokeWidth());
  333. gc.setStroke(temp.getStroke());
  334. gc.setFill(temp.getFill());
  335. gc.strokeLine(temp.getStartX(), temp.getStartY(), temp.getEndX(), temp.getEndY());
  336. }
  337. else if(shape.getClass() == Rectangle.class) {
  338. Rectangle temp = (Rectangle) shape;
  339. gc.setLineWidth(temp.getStrokeWidth());
  340. gc.setStroke(temp.getStroke());
  341. gc.setFill(temp.getFill());
  342. gc.fillRect(temp.getX(), temp.getY(), temp.getWidth(), temp.getHeight());
  343. gc.strokeRect(temp.getX(), temp.getY(), temp.getWidth(), temp.getHeight());
  344. }
  345. else if(shape.getClass() == Circle.class) {
  346. Circle temp = (Circle) shape;
  347. gc.setLineWidth(temp.getStrokeWidth());
  348. gc.setStroke(temp.getStroke());
  349. gc.setFill(temp.getFill());
  350. gc.fillOval(temp.getCenterX(), temp.getCenterY(), temp.getRadius(), temp.getRadius());
  351. gc.strokeOval(temp.getCenterX(), temp.getCenterY(), temp.getRadius(), temp.getRadius());
  352. }
  353. else if(shape.getClass() == Ellipse.class) {
  354. Ellipse temp = (Ellipse) shape;
  355. gc.setLineWidth(temp.getStrokeWidth());
  356. gc.setStroke(temp.getStroke());
  357. gc.setFill(temp.getFill());
  358. gc.fillOval(temp.getCenterX(), temp.getCenterY(), temp.getRadiusX(), temp.getRadiusY());
  359. gc.strokeOval(temp.getCenterX(), temp.getCenterY(), temp.getRadiusX(), temp.getRadiusY());
  360. }
  361. }
  362. } else {
  363. System.out.println("there is no action to undo");
  364. }
  365. });
  366.  
  367. // Redo
  368. redo.setOnAction(e->{
  369. if(!redoHistory.empty()) {
  370. Shape shape = redoHistory.lastElement();
  371. gc.setLineWidth(shape.getStrokeWidth());
  372. gc.setStroke(shape.getStroke());
  373. gc.setFill(shape.getFill());
  374.  
  375. redoHistory.pop();
  376. if(shape.getClass() == Line.class) {
  377. Line tempLine = (Line) shape;
  378. gc.strokeLine(tempLine.getStartX(), tempLine.getStartY(), tempLine.getEndX(), tempLine.getEndY());
  379. undoHistory.push(new Line(tempLine.getStartX(), tempLine.getStartY(), tempLine.getEndX(), tempLine.getEndY()));
  380. }
  381. else if(shape.getClass() == Rectangle.class) {
  382. Rectangle tempRect = (Rectangle) shape;
  383. gc.fillRect(tempRect.getX(), tempRect.getY(), tempRect.getWidth(), tempRect.getHeight());
  384. gc.strokeRect(tempRect.getX(), tempRect.getY(), tempRect.getWidth(), tempRect.getHeight());
  385.  
  386. undoHistory.push(new Rectangle(tempRect.getX(), tempRect.getY(), tempRect.getWidth(), tempRect.getHeight()));
  387. }
  388. else if(shape.getClass() == Circle.class) {
  389. Circle tempCirc = (Circle) shape;
  390. gc.fillOval(tempCirc.getCenterX(), tempCirc.getCenterY(), tempCirc.getRadius(), tempCirc.getRadius());
  391. gc.strokeOval(tempCirc.getCenterX(), tempCirc.getCenterY(), tempCirc.getRadius(), tempCirc.getRadius());
  392.  
  393. undoHistory.push(new Circle(tempCirc.getCenterX(), tempCirc.getCenterY(), tempCirc.getRadius()));
  394. }
  395. else if(shape.getClass() == Ellipse.class) {
  396. Ellipse tempElps = (Ellipse) shape;
  397. gc.fillOval(tempElps.getCenterX(), tempElps.getCenterY(), tempElps.getRadiusX(), tempElps.getRadiusY());
  398. gc.strokeOval(tempElps.getCenterX(), tempElps.getCenterY(), tempElps.getRadiusX(), tempElps.getRadiusY());
  399.  
  400. undoHistory.push(new Ellipse(tempElps.getCenterX(), tempElps.getCenterY(), tempElps.getRadiusX(), tempElps.getRadiusY()));
  401. }
  402. Shape lastUndo = undoHistory.lastElement();
  403. lastUndo.setFill(gc.getFill());
  404. lastUndo.setStroke(gc.getStroke());
  405. lastUndo.setStrokeWidth(gc.getLineWidth());
  406. } else {
  407. System.out.println("there is no action to redo");
  408. }
  409. });
  410.  
  411.  
  412. /*------- Save & Open ------*/
  413. // Open
  414. open.setOnAction((e)->{
  415. FileChooser openFile = new FileChooser();
  416. openFile.setTitle("Open File");
  417. File file = openFile.showOpenDialog(primaryStage);
  418. if (file != null) {
  419. try {
  420. InputStream io = new FileInputStream(file);
  421. Image img = new Image(io);
  422. gc.drawImage(img, 0, 0);
  423. } catch (IOException ex) {
  424. System.out.println("Error!");
  425. }
  426. }
  427. });
  428.  
  429. // Save
  430. save.setOnAction((e)->{
  431. FileChooser savefile = new FileChooser();
  432. savefile.setTitle("Save File");
  433.  
  434. File file = savefile.showSaveDialog(primaryStage);
  435. if (file != null) {
  436. try {
  437. WritableImage writableImage = new WritableImage(1080, 790);
  438. canvas.snapshot(null, writableImage);
  439. RenderedImage renderedImage = SwingFXUtils.fromFXImage(writableImage, null);
  440. ImageIO.write(renderedImage, "png", file);
  441. } catch (IOException ex) {
  442. System.out.println("Error!");
  443. }
  444. }
  445.  
  446. });
  447.  
  448. /* ----------STAGE & SCENE---------- */
  449. BorderPane pane = new BorderPane();
  450. pane.setLeft(btns);
  451. pane.setCenter(canvas);
  452.  
  453. Scene scene = new Scene(pane, 1200, 800);
  454.  
  455. primaryStage.setTitle("Paint");
  456. primaryStage.setScene(scene);
  457. primaryStage.show();
  458. }
  459.  
  460. public static void main(String[] args) {
  461. launch(args);
  462. }
  463. }
Add Comment
Please, Sign In to add comment