paintComponent()
interact thru instance variables.
paintComponent() method first draws the BufferedImage,
then draws the current shape, which may be changing as the mouse is being
dragged.
When the mouse is released, the current shape is drawn into the BufferedImage.
The Graphics2D class allows more extensive graphics operations
than the Graphics class. In this case it's needed to work with the BufferedImage.
Because Graphics2D is a child class (subclass) of
Graphics, it's easy to downcast the Graphics object that is passed
to paintComponent(). After downcasting, all Graphics2D operations
become available.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
// PaintDemo.java - Simple painting program.
// Illustrates use of mouse and BufferedImage.
// Fred Swartz 2002-12-02
// Possible Enhancements:
// * Clear drawing area
// * Other shapes (line, outline shapes, text, ...)
// * Color selection.
// * An eraser.
// * Create a real toobar.
// * Save/Load
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.image.BufferedImage;
////////////////////////////////////////////////////////////// PaintDemo
class PaintDemo {
//============================================================= main
public static void main(String[] args) {
PaintWindow window = new PaintWindow();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}//end main
}//endclass PaintDemo
//////////////////////////////////////////////////////////// PaintWindow
class PaintWindow extends JFrame {
PaintPanel canvas = new PaintPanel();
//====================================================== constructor
public PaintWindow() {
//--- create the buttons
JButton circleButton = new JButton("Circle");
circleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
canvas.setShape(PaintPanel.CIRCLE);
}});
JButton rectangleButton = new JButton("Rectangle");
rectangleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
canvas.setShape(PaintPanel.RECTANGLE);
}});
//--- layout the buttons
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(2, 1));
buttonPanel.add(circleButton);
buttonPanel.add(rectangleButton);
//--- layout the window
Container content = this.getContentPane();
content.setLayout(new BorderLayout());
content.add(buttonPanel, BorderLayout.WEST);
content.add(canvas , BorderLayout.CENTER);
this.setTitle("Paint Demo");
this.pack();
}//end constructor
}//endclass PaintWindow
///////////////////////////////////////////////////////////// PaintPanel
class PaintPanel extends JPanel implements MouseListener,
MouseMotionListener {
//--- Public constants used to specify shape being drawn.
public static final int NONE = 0;
public static final int LINE = 1;
public static final int RECTANGLE = 2;
public static final int CIRCLE = 3;
//--- Variables to store the current figure info
private int _shape = NONE;
private int _currentStartX = 0; // where mouse first pressed
private int _currentStartY = 0;
private int _currentEndX = 0; // where dragged to or released
private int _currentEndY = 0;
//--- BufferedImage to store the underlying saved painting.
// Will be initialized first time paintComponent is called.
private BufferedImage _bufImage = null;
//--- Private constant for size of paint area.
private static final int SIZE = 600; // size of paint area
//====================================================== constructor
public PaintPanel() {
setPreferredSize(new Dimension(SIZE, SIZE));
setBackground(Color.white);
//--- Add the mouse listeners.
this.addMouseListener(this);
this.addMouseMotionListener(this);
}//endconstructor
//========================================================= setShape
public void setShape(int shape) {
//--- Provided so users can set the shape.
_shape = shape;
}//end setShape
//=================================================== paintComponent
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g; // downcast to Graphics2D
if (_bufImage == null) {
//--- This is the first time, initialize _bufImage
int w = this.getWidth();
int h = this.getHeight();
_bufImage = (BufferedImage)this.createImage(w, h);
Graphics2D gc = _bufImage.createGraphics();
gc.setColor(Color.white);
gc.fillRect(0, 0, w, h); // fill in background
}
g2.drawImage(_bufImage, null, 0, 0); // draw previous shapes
drawCurrentShape(g2);
}//end paintComponent
//================================================= drawCurrentShape
private void drawCurrentShape(Graphics2D g2) {
//--- Draws current shape on a graphics context, either
// on the context passed to paintComponent, or the
// context for the BufferedImage.
switch (_shape) {
case NONE :
break;
case CIRCLE:
g2.fillOval(_currentStartX, _currentStartY,
_currentEndX - _currentStartX,
_currentEndY - _currentStartY);
break;
case RECTANGLE:
g2.fillRect(_currentStartX, _currentStartY,
_currentEndX - _currentStartX,
_currentEndY - _currentStartY);
break;
default: // should never happen
g2.drawString("Huh?", 10, 20);
break;
}
}//end paintComponent
//===================================================== mousePressed
public void mousePressed(MouseEvent e) {
_currentStartX = e.getX(); // save x coordinate of the click
_currentStartY = e.getY(); // save y
_currentEndX = _currentStartX; // set end to same pixel
_currentEndY = _currentStartY;
}//end mousePressed
//===================================================== mouseDragged
public void mouseDragged(MouseEvent e) {
_currentEndX = e.getX(); // save new x and y coordinates
_currentEndY = e.getY();
this.repaint(); // show new shape
}//end mouseDragged
//==================================================== mouseReleased
public void mouseReleased(MouseEvent e) {
// This will save the shape that has been dragged by
// drawing it onto the bufferedImage where all shapes
// are written.
_currentEndX = e.getX(); // save ending coordinates
_currentEndY = e.getY();
//--- Draw the current shape onto the buffered image.
Graphics2D grafarea = _bufImage.createGraphics();
drawCurrentShape(grafarea);
this.repaint();
}//end mouseReleased
//========================================== ignored mouse listeners
public void mouseMoved (MouseEvent e) {}
public void mouseEntered (MouseEvent e) {}
public void mouseExited (MouseEvent e) {}
public void mouseClicked (MouseEvent e) {}
}//endclass PaintPanel |