blob: a8b3ce5b7e0986a2b5459bbbde2f7e2cae1f64e8 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!-- -*- xhtml -*- -->
<title>NetBeans Platform Paint Application Tutorial for NetBeans Platform 7.0</title>
<link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/>
<meta name="AUDIENCE" content="NBUSER"/>
<meta name="TYPE" content="ARTICLE"/>
<meta name="EXPIRES" content="N"/>
<meta name="developer" content="gwielenga@netbeans.org"/>
<meta name="indexed" content="y"/>
<meta name="description"
content="A guide to creating a Paint application."/>
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
<!-- Use is subject to license terms.-->
</head>
<body>
<h1>NetBeans Platform Paint Application Tutorial</h1>
<p>This tutorial takes you through the basics of using NetBeans IDE to develop rich-client applications
on top of the NetBeans Platform. When you develop applications on top of the NetBeans Platform, you are
developing on top of the NetBeans IDE's core. All the modules belonging to the IDE that are not relevant to
your application are excluded, but those that are useful are kept. By reusing features readily available in IDE's core,
you save yourself a lot of time and energy. </p>
<p><strong class="notes">Note: </strong>This document uses the NetBeans IDE 7.0 Release
or above. If you
are using an earlier version, see <a href="691/nbm-paintapp.html">the previous version
of this document</a>.</p>
<p><b>Contents</b></p>
<p><img src="../../images/articles/70/netbeans-stamp.gif" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 7.0" title="Content on this page applies to NetBeans IDE 7.0"/></p>
<ul class="toc">
<li><a href="#intro">Introduction to the Paint Application</a></li>
<li><a href="#setup">Setting Up the Paint Application</a>
<ul>
<li><a href="#creatingModuleSuite">Creating the Application Skeleton</a></li>
<li><a href="#creatingLibWrapModule">Creating the Library Wrapper Module</a></li>
<li><a href="#creatingModProj">Creating the Module</a></li>
<li><a href="#specifyingModProjDep">Specifying the Module's Dependencies</a></li>
</ul></li>
<li><a href="#impMod">Creating and Embedding the Paint Canvas</a>
<ul>
<li><a href="#creatingCanv">Creating the Canvas</a></li>
<li><a href="#prepTopComp">Preparing the TopComponent Class</a></li>
<li><a href="#fillSkelMeth">Filling out the Skeleton Methods</a></li>
</ul></li>
</ul>
<p><b>To follow this tutorial, you need the software and resources listed in the following
table.</b></p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
<td class="tbltd1">version 7.0 or above</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td>
<td class="tbltd1">Version 6 or above</td>
</tr>
</tbody>
</table>
<p><a name="intro"></a></p><h2>Introduction to the Paint Application</h2>
<p>This tutorial is designed to get you going as quickly as possible.
You will create a simple application on the NetBeans Platform. The
application allows the user to
paint on the screen:</p>
<p><img src="../../images/tutorials/paintapp/70/result-without-menus.png" alt="image of completed application"/></p>
<p>This initial version is far from a full fledged
paint application, but it demonstrates a very simple case of creating an application on top of the NetBeans Platform.</p>
<p><b class="notes">Note:</b> The
<a href="nbm-google.html">NetBeans Plugin Quick Start</a> is a better tutorial for you if, instead of
rich-client applications, you want to
learn about NetBeans modules. </p>
<p>In this tutorial, we recreate an application that
is a sample delivered with the IDE. To see the final
product, or to troubleshoot problems while working
through this tutorial, get the sample from the
New Project wizard. Go to File | New Project, then
Samples | NetBeans Modules | Paint Application, shown below:</p>
<p><img src="../../images/tutorials/paintapp/70/sample-in-new-project.png" alt="name and location panel"/></p>
<p><a name="setup"></a></p><h2>Setting Up the Paint Application</h2>
<p>In this section, you create the structure of your application. You first need to create an application skeleton, which you
can do via a wizard. The application depends on a library, so you will also create a library wrapper module that will
contain the library's JAR file. Finally, you will create the module that will contain your code.</p>
<div class="indent">
<p><a name="creatingModuleSuite"></a></p><h3 class="tutorial">Creating the Application Skeleton</h3>
<p>The "NetBeans Platform Application" template will create your application's skeleton.
The skeleton will consist of a set of modules that
work together to form the basis of your application. You will use the Project Properties dialog to assign your application's splashscreen,
application name, and the type and number of NetBeans modules that you want to use. You can also take advantage
of such actions as creating a ZIP distribution and building a Java WebStart (JNLP) application, which are
important tools in making your application available to other users.</p>
<ol>
<li><p>Choose File &gt; New Project. Under Categories, select NetBeans Modules. Under projects,
select NetBeans Platform Application:</p>
<p><img src="../../images/tutorials/paintapp/70/paintapp-proj-wiz.png" alt="project template"/></p>
<p>Click Next.</p></li>
<li>In the Name and Location panel, type <tt>PaintApp</tt> in Project Name.
Change the
Project Location to any directory on your computer. Check the
Set as Main Project checkbox. Click Finish.</li>
<li><p>The new application skeleton opens in the IDE. Look at the new
project structure:</p>
<p><img src="../../images/tutorials/paintapp/70/paintapp-proj-wiz2.png" alt="project template"/></p>
You see two subnodes in the Projects window. The first subnode, the "Modules" node,
shows you the custom modules that are part of the application. Right now, as you can
see, there are none. You can right-click on this subnode and then invoke wizards
for creating new modules or for wrapping external JARs into the application.
modules to the application. The "Important Files" node shows the build scripts and
other supporting files used by the application.</li>
</ol>
<p>Now that we have an application, let's include an external JAR file that
will be useful in our Paint Application.</p>
<h3 class="tutorial"><a name="creatingLibWrapModule"></a>Creating the Library Wrapper Module</h3>
<p>A library wrapper module is a module whose JAR file contains no code&#8212;it is just a
pointer to a library. It turns the library into a NetBeans module, so that all the protections of the NetBeans
classloader system apply to it&#8212;without modifying the original JAR file. Your application can then depend on the
library just as if the library were just another NetBeans module. And, if new versions of the library become available,
you can distribute them without needing to distribute anything except a single NetBeans Module (NBM) file for the wrapper library.</p>
<p><b class="notes">Note:</b> One of the benefits of building on the NetBeans Platform is that its user interface is based on Swing&#8212;the
standard user interface toolkit for Java. Since Swing has been around for a long time, there are a lot
of Swing components you can reuse in your application. In this tutorial, you reuse an existing color chooser
JavaBean (you can find the source for it in NetBeans CVS under <tt>contrib/coloreditor</tt>). The JAR file is called <tt>ColorChooser.jar</tt>.
You can download the library here:</p>
<p><a href="http://java.net/projects/colorchooser/sources/svn/show/trunk/www/release?rev=82">http://java.net/projects/colorchooser/sources/svn/show/trunk/www/release?rev=82</a></p>
<p>Save it anywhere in your filesystem. </p>
<p>Do the following to create a library wrapper module for the
<tt>ColorChooser.jar</tt> file:</p>
<ol>
<li>Right-click the "Modules" node in the Paint Application.
Select Add New Library.</li>
<li><p>In the Select Library panel, in the "Library" text box, either type in the path
to <tt>ColorChooser.jar</tt> or browse to its location.
Leave the "License" text field empty. If you intend to distribute the completed product, you should
include the external library's license file.</p>
<p><img src="../../images/tutorials/paintapp/70/paintapp-lib-wiz1.png" alt="name and location panel"/></p>
<p>Click Next.</p></li>
<li><p>In the Name and Location panel, fill in the project name, set the project location,
and notice that the "Add to Module Suite" drop-down shows that the module will be
added to the application. </p>
<p><img src="../../images/tutorials/paintapp/70/paintapp-lib-wiz2.png" alt="name and location panel"/></p>
<p>Click Next.</p></li>
<li><p>In the Basic Module Configuration panel, type a unique name in the code name base, specify a module display
name, and accept the suggested location of the module's localizing bundle:</p>
<p><img src="../../images/tutorials/paintapp/70/paintapp-lib-wiz3.png" alt="name and location panel"/></p>
<p>Click Finish.</p></li></ol>
<p>The module that wraps the selected <tt>colorchooser.jar</tt> is created by the IDE.
The structure of the new module is shown in the Projects window. The "Modules" node
in the application's structure
shows that the module is part of the application.</p>
<h3 class="tutorial"><a name="creatingModProj"></a>Creating the Functionality Module</h3>
<p>Now you need a module to contain the actual code you're going to write.</p>
<ol>
<li>Right-click the "Modules" node in the Paint Application. Select Add New.</li>
<li><p>In the Name and Location panel, type <tt>Paint</tt> in Project Name.</p>
<p><img src="../../images/tutorials/paintapp/70/paintapp-mod-wiz1.png" alt="name and location panel"/></p>
<p>Notice that the module sources will be stored within a folder in
the application's directory on disk. Click Next.</p></li>
<li><p>In the Basic Module Configuration panel, type <tt>org.netbeans.paint</tt> as the
"Code Name Base". The code name base is a unique string identifying the module
to other modules in the application.
Leave everything unchanged and you should see the following:</p>
<p><img src="../../images/tutorials/paintapp/70/paintapp-mod-wiz2.png" alt="name and location panel"/></p>
<p>Click Finish. The IDE creates the <tt>Paint</tt>
project.</p></li>
<li><p>Take a look at the structure of your application.
The project contains all of your sources and
project metadata, such as the project's Ant build script. The project
opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its
file structure in the Files window (Ctrl-2). For example, the Projects
window should look as follows:</p>
<p><br/><img src="../../images/tutorials/paintapp/70/paintapp-mod-wiz3.png" alt="name and location panel"/></p>
</li>
</ol>
<p>You have created the application structure. Let's now add some code!</p>
<h3 class="tutorial"><a name="specifyingModProjDep"></a>Specifying the Module's Dependencies</h3>
<p>You will need to subclass several classes that belong to the <a href="http://bits.netbeans.org/dev/javadoc/index.html">NetBeans APIs</a>.
In addition, the project depends on the <tt>ColorChooser.jar</tt> file.
All NetBeans APIs are implemented by modules, so completing both of these tasks really just means
adding some modules to the list of modules that our module needs in order to run.</p>
<ol>
<li>In the Projects window, right-click the <tt>Paint</tt> project node and choose Properties.
The Project Properties dialog box opens. Under Categories, click Libraries.</li>
<li><p>For each of the API's listed in the table below, click "Add Dependency..." and then, in the Filter text box, start typing the name of the
class that you want to subclass.</p>
<table width="76%" border="1">
<tbody>
<tr>
<td>
<div><b>Class</b></div>
</td>
<td>
<div><b>API</b></div>
</td>
<td>
<div><b>Purpose</b></div>
</td>
</tr>
<tr>
<td><tt>ColorChooser</tt></td>
<td><tt>ColorChooser</tt></td>
<td>Library wrapper module for the color chooser component you created.</td>
</tr>
<tr>
<td><tt>Lookup</tt></td>
<td><tt>Lookup API</tt></td>
<td>Enables loosely coupled communication between modules.</td>
</tr>
<tr>
<td><tt>ActionID</tt></td>
<td><tt>UI Utilities API</tt></td>
<td>Provides annotations for registering Actions
in the NetBeans Platform virtual filesystem.</td>
</tr>
<tr>
<td><tt>Messages</tt></td>
<td><tt>Utilities API</tt></td>
<td>Provides a variety of general utility classes,
including support for internationalization
via the Bundle class and @Messages annotation.</td>
</tr>
<tr>
<td><tt>TopComponent</tt></td>
<td><tt>Window System API</tt></td>
<td>Gives you access to the NetBeans window system.</td>
</tr>
</tbody>
</table>
<br/>
<p>The first column in the table above lists all the classes that you will subclass in this tutorial.
In each case, start typing the class name in the Filter and watch the Module list narrow. Use the table's second column to pick the appropriate API (or, in the case of <tt>ColorChooser</tt>, the library) from the narrowed Module list and then click OK to confirm the choice.
Click OK to exit the Project Properties dialog box.</p></li>
<li><p>In the Projects window, expand the Paint module's project node and
then expand the Libraries node. Notice that all the libraries you have
selected are displayed:</p>
<p><img src="../../images/tutorials/paintapp/70/libfilter2.png" alt="initial-proj-window"/></p></li>
<li>Expand the Paint module's Important Files node and double-click
the Project Metadata node. Notice that the API's you
selected have been declared as module dependencies
in the file.</li>
</ol>
</div>
<h2><a name="impMod"></a>Creating and Embedding the Paint Canvas</h2>
<div class="indent">
<h3 class="tutorial"><a name="creatingCanv"></a>Creating the Canvas</h3>
<p>The next step is to create the actual component on which the user can paint. Here, you use a pure Swing component&#8212;so, let's
skip the details of its implementation and just provide the final version. The color chooser bean, which you created the library
wrapper module for, is used in the source code for this panel&#8212;when you run the finished application, you will see it
in the toolbar of the panel for editing images.</p>
<ol>
<li>In the Projects window, expand the <tt>Paint</tt> node, then expand the Source Packages node, and then
right-click the <tt>org.netbeans.paint</tt> node. Choose New &gt; Java Class.</li>
<li>Enter <tt>PaintCanvas</tt> as the Class Name. Ensure that <tt>org.netbeans.paint</tt> is listed as the
Package. Click Finish. <tt>PaintCanvas.java</tt> opens in the Source editor.</li>
<li>Replace the default content of the file with the content found
<a href="../images/tutorials/paintapp/70/PaintCanvas.java">here</a>.
If you named your package something other than <tt>org.netbeans.paint</tt>, correct the package name in the
Source editor.</li>
</ol>
<h3 class="tutorial"><a name="prepTopComp"></a>Preparing the TopComponent Class</h3>
<p>Now you'll write the only class in this application that needs to
touch the <a href="http://bits.netbeans.org/dev/javadoc/index.html">NetBeans APIs</a>. It is a <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a></tt> class. A <tt>TopComponent</tt> class is
just a <tt>JPanel</tt> class which the NetBeans windowing system knows how to talk
to&#8212;so that it can be put inside a tabbed
container inside the main window.</p>
<ol>
<li>In the Projects window, expand the <tt>Paint</tt> node, then expand the Source Packages node, and then
right-click the <tt>org.netbeans.paint</tt> node. Choose New &gt; Java Class.
Enter <tt>PaintTopComponent</tt> as the Class Name. Ensure that <tt>org.netbeans.paint</tt> is listed as the
Package. Click Finish. <tt>PaintTopComponent.java</tt> opens in the Source editor.</li>
<li>Near the top of the file, change the class declaration to the following:
<pre class="examplecode">public class PaintTopComponent extends TopComponent implements ActionListener, ChangeListener {</pre></li>
<li>Press Ctrl-Shift-I to fix imports and click OK. The IDE makes the necessary import package
declarations at the top of the file:
<pre class="examplecode">import java.awt.event.ActionListener;
import javax.swing.event.ChangeListener;
import org.openide.windows.TopComponent;</pre>
</li>
<li><p>Notice the red line under the class declaration that you just entered. Position the cursor in the line and notice that a
light bulb appears in the left margin. Click the light bulb (or press Alt-Enter), as shown below:</p>
<p><img src="../../images/tutorials/paintapp/lightbulb-60.png" alt="Lightbulb."/></p>
Select Implement all
abstract methods. The IDE generates two method skeletons&#8212;<tt>actionPerformed()</tt> and <tt>stateChanged()</tt>. You will fill these
out later in this tutorial.</li>
<li>Register the <tt>PaintTopComponent</tt> in the window system by adding annotations
to the top of the class, as shown here:
<pre class="examplecode"><a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.Description.html">@TopComponent.Description</a>(preferredID = "PaintTopComponent",
iconBase = "/org/netbeans/paint/new_icon.png", persistenceType = TopComponent.PERSISTENCE_ALWAYS)
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.Registration.html">@TopComponent.Registration</a>(mode = "editor", openAtStartup = true)
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionID.html">@ActionID</a>(category = "Window", id = "org.netbeans.paint.PaintTopComponent")
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionReferences.html">@ActionReferences</a>({
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionReference.html">@ActionReference</a>(path = "Menu/Window", position = 0),
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionReference.html">@ActionReference</a>(path = "Toolbars/File", position = 0)
})
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.OpenActionRegistration.html">@TopComponent.OpenActionRegistration</a>(displayName = "#CTL_NewCanvasAction")
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a>({"CTL_NewCanvasAction=New Canvas"})</pre>
<p>Notice that the <tt>PaintTopComponent</tt> will be displayed
in the main area of the application, defined by the "editor"
position. When the application starts, the window will be open.
An action will be created for opening the window. The user will be
able to invoke the action from a menu item and a toolbar button.</p></li>
<li><p>Add these two icons to "org/netbeans/paint":</p>
<p><img src="../../images/tutorials/paintapp/70/new_icon.png" alt="Lightbulb."/>
<img src="../../images/tutorials/paintapp/70/new_icon24.png" alt="Lightbulb."/></p>
<p>The 16x16 pixel icon will be used for the Small Toolbar Icons display,
while the 24x24 pixel icon will be used for the Large Toolbar display.</p>
</li>
<li>Add the following variable declarations to the top of the <tt>PaintTopComponent</tt> class and
then fix the import statements (Ctrl-Shift-I).
<pre class="examplecode"> private PaintCanvas canvas = new PaintCanvas(); //The component the user draws on
private final JComponent preview = canvas.getBrushSizeView(); //A component in the toolbar that shows the paintbrush size
private final JSlider brushSizeSlider = new JSlider(1, 24); //A slider to set the brush size
private final JToolBar toolbar = new JToolBar(); //The toolbar
private final ColorChooser color = new ColorChooser(); //Our color chooser component from the ColorChooser library
private final JButton clear = new JButton(LBL_Clear()); //A button to clear the canvas
private final JLabel label = new JLabel(LBL_Foreground()); //A label for the color chooser
private final JLabel brushSizeLabel = new JLabel(LBL_BrushSize()); //A label for the brush size slider
private static int ct = 0; //A counter you use to provide names for new images
</pre>
<p>Change the <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a> annotation at the top of the class
to the following:</p>
<pre class="examplecode"><a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a>({
"CTL_NewCanvasAction=New Canvas",
"LBL_Clear=Clear",
"LBL_Foreground=Foreground",
"LBL_BrushSize=Brush Size"})</pre>
</li>
<li>Define the constructor:
<pre class="examplecode">
public PaintTopComponent() {
initComponents();
setDisplayName(UnsavedImageNameFormat(ct++));
}</pre>
<p>Now change the <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a> annotation at the top of the class
to the following:</p>
<pre class="examplecode"><a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a>({
"CTL_NewCanvasAction=New Canvas",
"LBL_Clear=Clear",
"LBL_Foreground=Foreground",
"LBL_BrushSize=Brush Size",
"# {0} - image",
"UnsavedImageNameFormat=Image {0}"})</pre>
<p>You have added an annotation that defines
two keys in a bundle file that will be created when you build the module.
The annotation specifies the text that will be used to identify a new
image file in the application.
For example, when a user clicks New Canvas for the first time in
your completed application, a tab will appear above the Source Editor
with the label, 'Image 0'.</p></li>
<li><p>Next, the first Java call you see above is to a method you haven't written yet, <tt>initComponents()</tt>,
which will add a toolbar and a PaintCanvas to your <tt>TopComponent</tt>. Because you haven't written the method yet,
a red line appears underneath it here. As before, click the light bulb (or press Alt-Enter) and
accept the suggestion to let the IDE create the method for you.</p></li>
<li><p>Right-click the application and choose Run. The application starts up.
Under the Window menu, choose New Canvas a few times and notice that
you now have multiple canvases:</p>
<p><img src="../../images/tutorials/paintapp/70/run-app1.png" alt="initial-proj-window"/></p></li>
</ol>
<p>At this stage, you have created a window, and initialized a set of variables
that you will need as you build the user interface of the application. You could
use the Matisse GUI Builder for this but, as you will see in the next section,
you can also simply use plain Java code.</p>
<h3 class="tutorial"><a name="fillSkelMeth"></a>Filling Out the Skeleton Methods</h3>
<p>In this section, we code the user interface of
our application. We could also use the IDE's GUI
Builder to visually design the layout.</p>
<ol>
<li>The <tt>initComponents()</tt> method installs components in your panel, so
that the user has something to interact with. You generated its skeleton method during
the previous section in the <tt>PaintTopComponent.java</tt> class. Fill it out as follows:
<pre class="examplecode"> private void initComponents() {
setLayout(new BorderLayout());
//Configure our components, attach listeners:
color.addActionListener(this);
clear.addActionListener(this);
brushSizeSlider.setValue(canvas.getBrushDiameter());
brushSizeSlider.addChangeListener(this);
color.setColor(canvas.getColor());
color.setMaximumSize(new Dimension(16, 16));
//Install the toolbar and the painting component:
add(toolbar, BorderLayout.NORTH);
add(new JScrollPane(canvas), BorderLayout.CENTER);
//Configure the toolbar:
toolbar.setLayout(new FlowLayout(FlowLayout.LEFT, 7, 7));
toolbar.setFloatable(false);
//Now populate our toolbar:
toolbar.add(label);
toolbar.add(color);
toolbar.add(brushSizeLabel);
toolbar.add(brushSizeSlider);
toolbar.add(preview);
toolbar.add(clear);
}
</pre>
<p>Press Ctrl-Shift-I to generate the required import statements. </p></li>
<li>Fill out the other two methods that you generated. They are used for listening to the
<tt>PaintTopComponent</tt> class:
<pre class="examplecode"> @Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
canvas.clear();
} else if (e.getSource() instanceof ColorChooser) {
ColorChooser cc = (ColorChooser) e.getSource();
canvas.setColor(cc.getColor());
}
}</pre>
<pre class="examplecode"> @Override
public void stateChanged(ChangeEvent e) {
canvas.setBrushDiameter(brushSizeSlider.getValue());
}</pre>
</li>
<li>Check that the <tt>PaintTopComponent</tt> has this content:
<pre class="examplecode">package org.netbeans.paint;
import javax.swing.JButton;
import javax.swing.JLabel;
import net.java.dev.colorchooser.ColorChooser;
import javax.swing.JToolBar;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.TopComponent;
import static org.netbeans.paint.Bundle.*;
@TopComponent.Description(preferredID = "PaintTopComponent", iconBase = "/org/netbeans/paint/new_icon.png", persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = true)
@ActionID(category = "Window", id = "org.netbeans.paint.PaintTopComponent")
@ActionReferences({
@ActionReference(path = "Menu/Window", position = 0),
@ActionReference(path = "Toolbars/File", position = 0)
})
@TopComponent.OpenActionRegistration(displayName = "#CTL_NewCanvasAction")
@Messages({
"CTL_NewCanvasAction=New Canvas",
"LBL_Clear=Clear",
"LBL_Foreground=Foreground",
"LBL_BrushSize=Brush Size",
"# {0} - image",
"UnsavedImageNameFormat=Image {0}"})
public class PaintTopComponent extends TopComponent implements ActionListener, ChangeListener {
private PaintCanvas canvas = new PaintCanvas(); //The component the user draws on
private final JComponent preview = canvas.getBrushSizeView(); //A component in the toolbar that shows the paintbrush size
private final JSlider brushSizeSlider = new JSlider(1, 24); //A slider to set the brush size
private final JToolBar toolbar = new JToolBar(); //The toolbar
private final ColorChooser color = new ColorChooser(); //Our color chooser component from the ColorChooser library
private final JButton clear = new JButton(LBL_Clear()); //A button to clear the canvas
private final JLabel label = new JLabel(LBL_Foreground()); //A label for the color chooser
private final JLabel brushSizeLabel = new JLabel(LBL_BrushSize()); //A label for the brush size slider
private static int ct = 0; //A counter you use to provide names for new images
public PaintTopComponent() {
initComponents();
setDisplayName(UnsavedImageNameFormat(ct++));
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
canvas.clear();
} else if (e.getSource() instanceof ColorChooser) {
ColorChooser cc = (ColorChooser) e.getSource();
canvas.setColor(cc.getColor());
}
}
@Override
public void stateChanged(ChangeEvent e) {
canvas.setBrushDiameter(brushSizeSlider.getValue());
}
private void initComponents() {
setLayout(new BorderLayout());
//Configure our components, attach listeners
color.addActionListener(this);
clear.addActionListener(this);
brushSizeSlider.setValue(canvas.getBrushDiameter());
brushSizeSlider.addChangeListener(this);
color.setColor(canvas.getColor());
color.setMaximumSize(new Dimension(16, 16));
//Install the toolbar and the painting component:
add(toolbar, BorderLayout.NORTH);
add(new JScrollPane(canvas), BorderLayout.CENTER);
//Configure the toolbar
toolbar.setLayout(new FlowLayout(FlowLayout.LEFT, 7, 7));
toolbar.setFloatable(false);
//Now populate our toolbar:
toolbar.add(label);
toolbar.add(color);
toolbar.add(brushSizeLabel);
toolbar.add(brushSizeSlider);
toolbar.add(preview);
toolbar.add(clear);
}
}</pre>
</li>
<li><p>Run the application again and notice that you now have a functioning
paint canvas:</p>
<p><img src="../../images/tutorials/paintapp/70/run-app2.png" alt="initial-proj-window"/></p></li>
</ol>
<p>That's it! You have completed the first part
of the Paint Application. In the next part,
you learn how to integrate with the NetBeans
Platform's save functionality, which will
enable the user to save images when changes
have been made.</p>
<div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans Platform Paint Application Tutorial">Send Us Your Feedback</a></div>
</body>
</html>