Java Reference
In-Depth Information
files. Next, the showOpenDialog method is called to display an Open File dialog. JFileChooser
also has a lot of additional options you can configure, such as filtering which files to show. The
result of this method is an integer determining whether the user selected a file or cancelled the
dialog, or an error occurred. Next, the getSelectedFile method retrieves your file. Note that
JFileChooser still utilizes the legacy File class. Next, a built‐in utility class called ImageIO does
the heavy lifting regarding reading image files. This class reads in common file formats, such as
PNG, JPG, BMP, and GIF files, and returns a BufferedImage object to store the image data. Next,
it iterates over all pixels in the image and applies a simple trick to determine whether the pixel
color should be converted to a black pixel. Dark colors are converted to black, whereas light colors
are not; that is what the if ((c.getBlue() < 128 || c.getRed() < 128 || c.getGreen()
< 128) && c.getAlpha() == 255) line does. Once all the black pixels are gathered, the
paintPanel object is instructed to add them.
6. The save method works similarly. Here, a fresh image is constructed with the width and height
equal to the current width and height of the paint panel. Next, it loops over each pixel again and
sets them to black when necessary. Note that some additional logic is applied to make the filename
selected with showSaveDialog end in .png , as there is no way to force the JFileChooser to do
this for you. (This is because file extensions are just a convention to tell the operating system what
the default program should be to open files ending in a particular suffix. There is nothing prevent-
ing you from saving a PNG image as image.txt and opening it with an image editor afterward.)
7. Now take a look at the SimplePaintPanel class. This class extends JPanel and implements a
mouse and mouse motion event listener by using the MouseAdapter class.
8. The mouse‐related methods that are implemented are mouseDragged and mousePressed . The lat-
ter determines which button (left or right) is being pressed. When the mouse is dragged, it looks
at the mouse button currently being pressed and determines whether black pixels should be added
or removed. You might wonder why you can't just use ev.getButton() in the mouseDragged
method to determine which mouse button is being pressed. The reason for this is that this will
always return 0, as getButton() only returns the button number when the state has changed.
Since you keep holding down the mouse button whilst dragging, no button state is changing. You
can, however, use SwingUtilities.isLeftMouseButton(ev) instead, which will work, but here
things were done manually to show off how the mouse event listener works as well.
9. The second interesting aspect to note is the custom paint method for this class. First, the whole panel
surface is filled out with white, after which a pixel is drawn for each point in the blackPixels set.
10. Finally, it is important to know that you should tell Java when “my surface has changed; you
should draw me again.” This is what is done with the invalidate method. A repaint call is
placed right after this to instruct Java to redraw the component (which will have Java make a call
to the paint method).
11. You will notice this yourself when drawing quickly; the drawing code is horribly inefficient. There
are many reasons for this. First, working with a set of pixels is not ideal, especially not for larger
images. Second, Swing components were never really designed to perform high‐speed drawing
updates, which is what is done here while dragging. In a real painting application, you need to look
for better-suited drawing components (those exist). That said, this example helps to explain various
concepts, and custom drawing code can still be helpful whenever you know components will not
need to be redrawn continuously.
Search WWH ::




Custom Search