Layers
The layers feature is an ArrayList of BufferedImages. Unlike a static array, the ArrayList allows for objects, such as layers, to be created and deleted after initialization. I decided to use the BufferedImage class instead of its superclass, the Image class, due to its capability to implement transparency. The layers have to be transparent so that the layers painted underneath are still visible.
26 27 28 29 30 31 32 33 | public Layers(PaintApp pLab) { // Creates an ArrayList of BufferedImages to contain the layers and creates an initial layer paintLab = pLab; imageArray = new ArrayList<BufferedImage>(); BufferedImage bImage = new BufferedImage(paintLab.getAppWidth(), paintLab.getCanvasHeight(), BufferedImage.TYPE_INT_ARGB); imageArray.add(bImage); // Adds the first layer cLayerNum = 0 ; } |
public Layers(PaintApp pLab) { // Creates an ArrayList of BufferedImages to contain the layers and creates an initial layer paintLab = pLab; imageArray = new ArrayList<BufferedImage>(); BufferedImage bImage = new BufferedImage(paintLab.getAppWidth(), paintLab.getCanvasHeight(), BufferedImage.TYPE_INT_ARGB); imageArray.add(bImage); // Adds the first layer cLayerNum = 0; }
When the user decides to delete a layer, the layer cannot be deleted immediately. The requested layer is first set to a blank image to clear the canvas when repaint() is called.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | public void deleteLayer() { // User deletes the current layer if ((cLayerNum != imageArray.size() - 1 ) || (cLayerNum > 0 )) { // If the current layer is not the only layer left BufferedImage bImage = new BufferedImage(paintLab.getAppWidth(), paintLab.getCanvasHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D buffg = (Graphics2D) bImage.getGraphics(); buffg.fillRect( 0 , 0 , paintLab.getAppWidth(), paintLab.getCanvasHeight()); // Creates a blank image the size of the canvas imageArray.set(cLayerNum, bImage); // Sets the current layer to this blank image deleteLayer = true ; changeLayer = true ; paintLab.repaint(); // The blank image (user-requested deleted layer) clears the canvas and the other layers are redrawn on top } else { // User cannot delete the only layer JOptionPane.showMessageDialog( null , "Sorry, but you cannot delete your only layer." ); paintLab.repaint(); } } |
public void deleteLayer() { // User deletes the current layer if ((cLayerNum != imageArray.size() - 1) || (cLayerNum > 0)) { // If the current layer is not the only layer left BufferedImage bImage = new BufferedImage(paintLab.getAppWidth(), paintLab.getCanvasHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D buffg = (Graphics2D) bImage.getGraphics(); buffg.fillRect(0, 0, paintLab.getAppWidth(), paintLab.getCanvasHeight()); // Creates a blank image the size of the canvas imageArray.set(cLayerNum, bImage); // Sets the current layer to this blank image deleteLayer = true; changeLayer = true; paintLab.repaint(); // The blank image (user-requested deleted layer) clears the canvas and the other layers are redrawn on top } else { // User cannot delete the only layer JOptionPane.showMessageDialog(null, "Sorry, but you cannot delete your only layer."); paintLab.repaint(); } }
When the repaint() calls paintLayers(), the blank layer is drawn with the other layers drawn on top. The layer's off-screen image is then deleted from the ArrayList. In order to prevent the other layers from constantly flickering while the user is painting, only the new current layer's graphics are updated.
095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | public void paintLayers(Graphics2D g2Frame) { // When a layer is created or deleted, or the user decides to switch to a different layer if (layersArray.deleteLayer) { // A layer is deleted (can be any layer, not just the last layer in imageArray, that is not the only layer lef) g2Frame.drawImage(layersArray.getImageArray().get(layersArray.getcLayerNum()), 0 , getMenuHeight(), this ); // Draws the blank deleted layer // Otherwise, the deleted layer will remain and is not erased on screen for ( int k = 0 ; k < layersArray.getImageArray().size(); k++) { // Then draws the rest of the layers in ascending order if (k!=layersArray.getcLayerNum()) { g2Frame.drawImage(layersArray.getImageArray().get(k), 0 , getMenuHeight(), this ); } } layersArray.deleteLayer = false ; layersArray.getImageArray().remove(layersArray.getcLayerNum()); // Removes the blank deleted layer from imageArray if (layersArray.getcLayerNum() == layersArray.getImageArray().size()) // If the deleted layer was the last layer, then decrease cLayerNum layersArray.setcLayerNum(layersArray.getcLayerNum() - 1 ); // If not, then cLayerNum is not decreased // eg If the third layer is deleted, then the next layer which used to be the fourth layer is now the third layer g2Frame.drawImage(layersArray.getImageArray().get(layersArray.getcLayerNum()), 0 , getMenuHeight(), this ); // The current layer is drawn last for visibility } else { // If you are not deleting a layer, update only the current layer's graphics. // If you constantly redrawing the other layers, then those other layers will flicker in the background g2Frame.drawImage(layersArray.getImageArray().get(layersArray.getcLayerNum()), 0 , getMenuHeight(), this ); } if (layersArray.changeLayer) { // If a layer is created or deleted, or the user switches to the previous or next layer menuBar.changeLayerMenu(); // Layer status is updated layersArray.changeLayer = false ; } } |
public void paintLayers(Graphics2D g2Frame) { // When a layer is created or deleted, or the user decides to switch to a different layer if (layersArray.deleteLayer) { // A layer is deleted (can be any layer, not just the last layer in imageArray, that is not the only layer lef) g2Frame.drawImage(layersArray.getImageArray().get(layersArray.getcLayerNum()), 0, getMenuHeight(), this); // Draws the blank deleted layer // Otherwise, the deleted layer will remain and is not erased on screen for (int k = 0; k < layersArray.getImageArray().size(); k++) { // Then draws the rest of the layers in ascending order if (k!=layersArray.getcLayerNum()) { g2Frame.drawImage(layersArray.getImageArray().get(k), 0, getMenuHeight(), this); } } layersArray.deleteLayer = false; layersArray.getImageArray().remove(layersArray.getcLayerNum()); // Removes the blank deleted layer from imageArray if (layersArray.getcLayerNum() == layersArray.getImageArray().size()) // If the deleted layer was the last layer, then decrease cLayerNum layersArray.setcLayerNum(layersArray.getcLayerNum() - 1); // If not, then cLayerNum is not decreased // eg If the third layer is deleted, then the next layer which used to be the fourth layer is now the third layer g2Frame.drawImage(layersArray.getImageArray().get(layersArray.getcLayerNum()), 0, getMenuHeight(), this); // The current layer is drawn last for visibility } else { // If you are not deleting a layer, update only the current layer's graphics. // If you constantly redrawing the other layers, then those other layers will flicker in the background g2Frame.drawImage(layersArray.getImageArray().get(layersArray.getcLayerNum()), 0, getMenuHeight(), this); } if (layersArray.changeLayer) { // If a layer is created or deleted, or the user switches to the previous or next layer menuBar.changeLayerMenu(); // Layer status is updated layersArray.changeLayer = false; } }