100% found this document useful (1 vote)
15 views

Rich client programming plugging into the NetBeans Platform 1. print Edition Tulach - Read the ebook online or download it to own the full content

The document provides information on downloading the book 'Rich Client Programming: Plugging into the NetBeans Platform' and other related ebooks from ebookultra.com. It includes links to various recommended titles and details about the book's authors, ISBN, and publication year. Additionally, it outlines the book's contents and structure, covering topics such as modular programming and GUI development within the NetBeans platform.

Uploaded by

mioaranazaan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
15 views

Rich client programming plugging into the NetBeans Platform 1. print Edition Tulach - Read the ebook online or download it to own the full content

The document provides information on downloading the book 'Rich Client Programming: Plugging into the NetBeans Platform' and other related ebooks from ebookultra.com. It includes links to various recommended titles and details about the book's authors, ISBN, and publication year. Additionally, it outlines the book's contents and structure, covering topics such as modular programming and GUI development within the NetBeans platform.

Uploaded by

mioaranazaan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

Visit https://ebookultra.

com to download the full version and


explore more ebooks or textbooks

Rich client programming plugging into the NetBeans


Platform 1. print Edition Tulach

_____ Click the link below to download _____


https://ebookultra.com/download/rich-client-programming-
plugging-into-the-netbeans-platform-1-print-edition-tulach/

Explore and download more ebooks or textbooks at ebookultra.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Pro Netbeans IDE 6 Rich Client Platform Edition Adam Myatt

https://ebookultra.com/download/pro-netbeans-ide-6-rich-client-
platform-edition-adam-myatt/

The Definitive Guide to NetBeans Platform 1st Edition


Heiko Böck

https://ebookultra.com/download/the-definitive-guide-to-netbeans-
platform-1st-edition-heiko-bock/

The Definitive Guide to NetBeans Platform 1st Edition


Heiko Böck (Auth.)

https://ebookultra.com/download/the-definitive-guide-to-netbeans-
platform-1st-edition-heiko-bock-auth/

Programming Wireless Devices with the Java 2 Platform 2nd


Edition Roger Riggs

https://ebookultra.com/download/programming-wireless-devices-with-the-
java-2-platform-2nd-edition-roger-riggs/
History in the Vernacular 1. paperback print. Edition
Raziuddin Aquil

https://ebookultra.com/download/history-in-the-vernacular-1-paperback-
print-edition-raziuddin-aquil/

NetBeans The Definitive Guide 1st Edition Tim Boudreau

https://ebookultra.com/download/netbeans-the-definitive-guide-1st-
edition-tim-boudreau/

The Client First Edition John Grisham

https://ebookultra.com/download/the-client-first-edition-john-grisham/

20 Recipes for Programming PhoneGap Cross Platform Mobile


Development for Android and iPhone 1st Edition Munro

https://ebookultra.com/download/20-recipes-for-programming-phonegap-
cross-platform-mobile-development-for-android-and-iphone-1st-edition-
munro/

Philosophy and German literature 1700 1990 1. pbk. print


Edition Saul

https://ebookultra.com/download/philosophy-and-german-
literature-1700-1990-1-pbk-print-edition-saul/
Rich client programming plugging into the NetBeans
Platform 1. print Edition Tulach Digital Instant
Download
Author(s): Tulach, Jaroslav; Boudreau, Tim; Wielenga, Geertjan
ISBN(s): 9780132354806, 0132354802
Edition: 1. print
File Details: PDF, 5.69 MB
Year: 2007
Language: english
Rich Client Programming
This page intentionally left blank
Rich Client Programming
Plugging into the NetBeans Platform TM

Tim Boudreau
Jaroslav Tulach
Geertjan Wielenga

Upper Saddle River, NJ • Boston • Indianapolis • San Francisco


New York • Toronto • Montreal • London • Munich • Paris • Madrid
Capetown • Sydney • Tokyo • Singapore • Mexico City
Copyright © 2007 Sun Microsystems, Inc.
4150 Network Circle, Santa Clara, California 95054 U.S.A.
All rights reserved.
Sun Microsystems, Inc. has intellectual property rights relating to implementations of the technology described in this
publication. In particular, and without limitation, these intellectual property rights may include one or more U.S. patents,
foreign patents, or pending applications.
Sun, Sun Microsystems, the Sun logo, NetBeans, J2EE, and all Sun and Java based trademarks and logos are trademarks or
registered trademarks of Sun Microsystems, Inc., in the United States and other countries. UNIX is a registered trademark in
the United States and other countries, exclusively licensed through X/Open Company, Ltd.
THIS PUBLICATION IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THIS PUBLICATION COULD INCLUDE TECHNICAL
INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION
HEREIN; THESE CHANGES WILL BE INCORPORATED IN NEW EDITIONS OF THE PUBLICATION. SUN
MICROSYSTEMS, INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S)AND/OR THE
PROGRAM(S) DESCRIBED IN THIS PUBLICATION AT ANY TIME.

This Book Is Safari Enabled


The Safari Enabled icon on the cover of your favorite technology book means the book is available through
Safari Bookshelf. When you buy this book, you get free access to the online edition for 45 days.
Safari Bookshelf is an electronic reference library that lets you easily search thousands of technical books, find code samples,
download chapters, and access technical information whenever and wherever you need it.
To gain 45-day Safari Enabled access to this book:
• Go to http://www.prenhallprofessional.com/safarienabled
• Complete the brief registration form
• Enter the coupon code 32IE-M6EH-YU9W-QRHE-V51D

If you have difficulty registering on Safari Bookshelf or accessing the online edition, please e-mail
[email protected].

Visit us on the Web: www.prenhallprofessional.com


Library of Congress Cataloging-in-Publication Data
Boudreau, Tim.
Rich client programming : plugging into the NetBeans platform / Tim Boudreau, Jaroslav Tulach, Geertjan Wielenga.
p. cm.
Includes bibliographical references and index.
ISBN 0-13-235480-2 (pbk. : alk. paper)
1. Java (Computer program language) 2. Computer programming. I. Tulach, Jaroslav. II. Wielenga, Geertjan. III. Title.
QA76.73.J38B672 2007
005.13'3--dc22___________________________________2007007068
All rights reserved. Printed in the United States of America. This publication is protected by copyright, and permission must
be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any
form or by any means, electronic, mechanical, photocopying, recording, or likewise. For information regarding permissions,
write to:
Pearson Education, Inc.
Rights and Contracts Department
One Lake Street
Upper Saddle River, NJ 07458
Fax: (201) 236-3290
ISBN 0-13-235480-2
Text printed in the United States on recycled paper at Courier in Stoughton, Massachusetts.
First printing, April 2007
Contents

Foreword by Jonathan Schwartz xv

Foreword by Jan Chalupa xvii

Preface xix

About the Authors and Contributors xxvii

Acknowledgments xxxi

Chapter One Getting Started with the NetBeans Platform 1


1.1 Setting Up the IDE 1
1.2 NetBeans IDE Basics 3
1.2.1 Creating a Module 3
1.2.2 Creating an Application 4
1.2.3 Using File Templates 6
1.2.4 Declaring Dependencies 7
1.2.5 Running a Module 8
1.2.6 Branding an Application 8
1.2.7 Distributing an Application 9

Chapter Two The Benefits of Modular Programming 11


2.1 Distributed Development 11
2.2 Modular Applications 13

v
vi Contents

2.2.1 Versioning 13
2.2.2 Secondary Versioning Information 14
2.2.3 Dependency Management 15
2.3 A Modular Programming Manifesto 15
2.4 Using NetBeans to Do Modular Programming 19

Chapter Three Modular Architecture 23


3.1 Modules—The Assembly Units of a Modular Application 23
3.2 Types of Modules 24
3.2.1 End-User Interface Module 24
3.2.2 Simple Library 25
3.2.3 Multiple Vendor Support 26
3.2.4 Modular Library 27
3.3 Module Lifecycle 29
3.4 Groups of Modules 33

Chapter Four Loosely Coupled Communication 39


4.1 Registration and Discovery 39
4.2 MetaInf Services 41
4.3 The Global Lookup 43
4.4 Writing an Extension Point 46

Chapter Five Lookup 49


5.1 Objects That Own Lookups 53
5.2 Lookup as a Communication Mechanism 55
5.3 Lookups and Proxying 58
5.4 Lookup and Selection 62
5.5 Writing Lookup-Sensitive Actions 63
5.6 Tracking the Global Selection 64
5.7 Legacy Variants of the Lookup Pattern in NetBeans APIs 65
5.8 Common Lookup Patterns 66

Chapter Six Filesystems 69


6.1 FileSystems and FileObjects 70
6.2 What Kinds of FileSystems Will I Be Dealing With? 71
6.3 Layering 72
6.4 XML Filesystems 73
Contents vii

6.5 Declarative Registration II: The System Filesystem 74


6.5.1 How the System Filesystem Works 75
6.5.2 The System Filesystem Is Read/Write 76
6.5.3 Using FileChangeEvents from the System Filesystem 77
6.5.4 Exploring the System Filesystem—Menus 78
6.6 Getting from FileObjects to Java Objects 88
6.6.1 Using Factory Methods to Create Objects from .instance Files 90
6.6.2 Programmatic Access to the System Filesystem 93
6.6.3 Using .settings Files 94
6.7 Browsing the System Filesystem 96
6.8 Conclusions 96
6.8.1 Commonly Used Folders in the System Filesystem 96

Chapter Seven Threading, Listener Patterns, and MIME Lookup 103


7.1 Creating the Modules and SPI 104
7.2 Implementing ListModelProvider 107
7.2.1 Setting Up Dependencies 107
7.2.2 Creating XmlListModelProvider 109
7.2.3 Registering XmlListModelProvider 123
7.3 Providing a UI Component 123
7.3.1 The MIME Lookup SPI and API 124
7.3.2 Providing a Window Component to Show List Models 125
7.4 Using the Pseudo Navigator 132
7.5 Conclusion: PseudoNavigator—What’s Wrong with This Picture? 132

Chapter Eight The Window System 135


8.1 What the Window System Does 137
8.2 Classes in the Window System API 139
8.3 Using TopComponent 141
8.4 Persisting State across Sessions 145
8.4.1 Window System Persistence Modes 147
8.5 Window System Persistence Data 147
8.6 Creating Editor-Style (Nondeclarative) TopComponents 152
8.6.1 Opening Your Component Somewhere Else 153
8.7 Advanced Window System Configuration: Defining Your Own Modes 153
8.8 Using TopComponent Groups 158
8.8.1 Opening a Component Group Programmatically 161
viii Contents

Chapter Nine Nodes, Explorer Views, Actions, and Presenters 163


9.1 The Nodes API 164
9.1.1 Using the Nodes API 167
9.2 The Explorer API 177
9.2.1 Types of Explorer View Components 177
9.2.2 Creating a TopComponent to Display Nodes 179
9.2.3 Adding a Detail View 182
9.2.4 Adding Another Detail View Using the Explorer API 184
9.3 Actions 190
9.3.1 Presenters 192
9.3.2 The Actions API and Standard NetBeans Actions 195
9.3.3 Installing Global Actions in Menus, Toolbars, and Keyboard
Shortcuts 196
9.3.4 Context-Aware Actions 197
9.4 Node Properties 199
9.5 Nodes and DataObjects: Creating a System Filesystem Browser 203
9.6 Epilogue: Of Nodes, Property Sheets, and User Interface Design 205

Chapter Ten DataObjects and DataLoaders 207


10.1 DataObjects: Where Do They Come From? 210
10.2 Adding Support for a New File Type 212
10.2.1 Adding Support for Manifest Files to NetBeans 212
10.2.2 Providing a Manifest Object from Manifest Files 218
10.2.3 Providing ManifestProvider from ManifestDataObject and
ManifestDataNode 219
10.2.4 Icon Badging 223
10.2.5 Testing ManifestDataObject with JUnit 228
10.3 Using Custom File Types Internally 234
10.4 Serialized Objects and the System Filesystem 235

Chapter Eleven Graphical User Interfaces 237


11.1 Introduction 237
11.2 Creating a New GUI Form 240
11.3 Placing and Aligning a Component in a Form 240
11.4 Setting Component Size and Resizability 242
11.5 Specifying Component Behavior and Appearance 244
11.6 Generating Event Listening and Handling Methods 244
Contents ix

11.7 Customizing Generated Code 247


11.8 Building an Explorer View Visually 249
11.9 Previewing a Form 250
11.10 Using Custom Beans in the Form Editor 250
11.11 Using Different Layout Managers 251

Chapter Twelve Multiview Editors 253


12.1 Introduction 253
12.2 Getting Started 255
12.3 Understanding Multiview Editors 256
12.4 Creating the Editor’s Infrastructure 257
12.5 Creating the Source View 261
12.5.1 Describing a Source MultiViewElement 261
12.5.2 Creating a Source Editor 263
12.5.3 Adding the Source View to the Multiview Editor 267
12.6 Creating the Visual View 269
12.6.1 Adding a Visual View to the Multiview Editor 269
12.7 Finishing the Sample 271

Chapter Thirteen Syntax Highlighting 273


13.1 Introduction 273
13.2 Preparing to Create Syntax Highlighting 274
13.3 Creating Token IDs 275
13.4 Creating a Lexical Analyzer 277
13.5 Extending the Options Window 281
13.6 Registering the Syntax Highlighting in the Layer File 284
13.7 Finishing Up 286

Chapter Fourteen Code Completion 287


14.1 Introduction 287
14.2 Understanding Code Completion 289
14.3 Code Completion Query Types 291
14.4 Preparing to Work with the CompletionProvider Interface 291
14.5 Implementing a CompletionProvider 293
14.6 Implementing a CompletionItem 296
14.7 Adding a Filter to the CompletionProvider 300
x Contents

14.8 Adding Documentation to the Code Completion Box 304


14.9 Adding a Tooltip to the Code Completion Box 305

Chapter Fifteen Component Palettes 307


15.1 Introduction 307
15.1.1 Understanding the Component Palette 308
15.1.2 Creating Your First Palette 311
15.2 Adding Items to a Palette 313
15.2.1 Adding Items to Your First Palette 314
15.2.2 Letting the User Add Items to the Palette 321
15.3 Dragging and Dropping Palette Items 323
15.3.1 Defining a Drop Target 325
15.3.2 Defining a Drag Image 326
15.3.3 Defining a Drop Event 328
15.3.4 Defining a Drag Gesture 330
15.4 Adding Supporting Features to a Palette 331
15.4.1 Adding Actions to the Palette 332
15.4.2 Adding a Filter and Refreshing the Palette 335
15.4.3 Adding a Property Change Listener 338
15.4.4 Setting Palette Attributes 339
15.4.5 Providing a Palette Manager 341
15.5 Creating a Palette for a Text-Based Editor 344
15.5.1 Associating a Palette with a Text-Based Editor 344
15.5.2 Adding Items to a Text-Based Editor’s Palette 347
15.5.3 Formatting Dropped Items in a Text-Based Editor 350
15.5.4 Letting the User Add Items to a Text-Based Editor’s Palette 351

Chapter Sixteen Hyperlinks 355


16.1 Introduction 355
16.1.1 Preparing to Provide Hyperlinks 356
16.1.2 The HyperlinkProvider Class 356
16.1.3 Getting Started Really Quickly 356
16.2 Preparing to Work with the HyperlinkProvider Class 357
16.3 Hyperlinks in Manifest Files 359
16.3.1 Identifying Hyperlinks 360
16.3.2 Setting the Length of a Hyperlink 361
16.3.3 Opening the Referenced Document 362
16.3.4 Finishing Up 364
Contents xi

Chapter Seventeen Annotations 367


17.1 Introduction 367
17.2 Preparing to Create an Error Annotation 368
17.3 Creating an Error Annotation 368
17.3.1 Understanding the Error Annotation DTD 370
17.3.2 Registering an Error Annotation 375
17.3.3 Installing an Error Annotation 376
17.4 Preparing to Use an Error Annotation 376
17.5 Using an Error Annotation 377
17.5.1 Describing an Annotation 378
17.5.2 Attaching and Detaching Annotations 379
17.5.3 Defining a Request Processor Task 381
17.5.4 Annotating Part of a Line 382
17.6 Finishing Up 383

Chapter Eighteen Options Windows 385


18.1 Introduction 385
18.1.1 Your First Options Window Extension 385
18.2 Looking at the Options Window Extension Files 389
18.2.1 The AdvancedOption Class 389
18.2.2 The OptionsPanelController Class 390
18.2.3 The Visual Options Panels 392
18.3 Creating a Primary Panel 393
18.3.1 Your First Primary Panel 393
18.3.2 Reordering Options Panels 395
18.4 Adding Settings to the Options Window 396
18.4.1 Example: Using the Preferences API 396

Chapter Nineteen Web Frameworks 399


19.1 Introduction 399
19.1.1 Preparing to Provide Support for a Web Framework 400
19.1.2 The WebFrameworkProvider Class 401
19.1.3 Getting Started Really Quickly 402
19.1.4 Example: Basic Registration 402
19.2 Preparing to Work with the WebFrameworkProvider Class 404
19.3 Providing a Framework Configuration Panel 406
19.3.1 Creating the Configuration Panel 407
xii Contents

19.3.2 Example: Adding a Configuration Panel to the


WebFrameworkProvider 410
19.3.3 Coding the Configuration Panel 411
19.4 Creating a Source Structure 413
19.4.1 Preparing to Use the extend() Method 414
19.4.2 Example: Defining the extend() Method 414
19.4.3 Creating Templates 416
19.4.4 A Template for Creating a Java File 416
19.4.5 Preparing to Use a Template to Programmatically Create a Java File
417
19.4.6 Using a Template to Programmatically Create a Java File 419
19.4.7 Trying Out the Framework Support Module 422
19.5 Letting the User Select a Library in the Frameworks Panel 423
19.6 Project Properties Dialog Box and Web Frameworks 424
19.6.1 Example: isInWebModule() Method 426
19.7 Finishing Up 427

Chapter Twenty Web Services 429


20.1 Introduction 429
20.2 Creating and Testing a Web Service Client 430
20.3 Integrating the Web Service Client 435

Chapter Twenty-One JavaHelp Documentation 441


21.1 Creating a Help Set 442
21.1.1 Adding New Help Topics 445
21.2 Removing the IDE’s Help Sets 446
21.3 Branding the Help Set’s Default Texts 449

Chapter Twenty-Two Update Centers 453


22.1 Introduction 453
22.2 Adding the IDE’s Update Center Functionality 454
22.3 Creating and Distributing an Autoupdate Descriptor 456
22.3.1 Using the IDE to Create an Autoupdate Descriptor 456
22.3.2 Uploading the Autoupdate Descriptor and NBM Files 457
22.4 Distributing the URL to the Autoupdate Descriptor 458
22.4.1 Generating a Module for Registering an Autoupdate Descriptor 459
22.4.2 Making the User Manually Register an Autoupdate Descriptor 460
Contents xiii

22.5 Downloading NBM Files from an Update Center 461


22.6 Publishing Updates to Existing Modules 462

Chapter Twenty-Three Use Case 1: Jens Trapp on NetBeans Module


Development 463
23.1 Introduction 463
23.2 Calling the External Tool 465
23.2.1 Creating the Tidy Error Check Action 465
23.2.2 Retrieving the Filename 468
23.2.3 Running HTML Tidy 469
23.2.4 Resolving Dependencies 473
23.2.5 Running the Example 473
23.3 Handling the Output 476
23.3.1 Printing the Output 476
23.3.2 Listening to the Output 479
23.3.3 Parsing the Output 481
23.3.4 Annotating Errors in the Source Editor 484
23.4 Configuring the Tool 491
23.4.1 Extending the Options Window 491
23.4.2 Persisting the Options 494
23.5 Formatting and Converting Files 496
23.5.1 Manipulating Files 497
23.5.2 Seeing the Difference 504
23.6 Controlling the Conversion 505
23.6.1 Creating the Wizard 505
23.6.2 Connecting the Wizard 517

Chapter Twenty-Four Use Case 2: Rich Unger on Application


Development 521
24.1 Introduction 521
24.2 Getting Started 522
24.3 Creating Support for the audio/wav MIME Type 526
24.4 Encapsulating Audio Data in the WavDataObject 530
24.5 Creating a Component for Viewing WAV Files 533
24.6 Converting WAV Editor to Multiview 535
24.7 Creating an API for Plugging in Additional Views 542
24.8 Implementing Your Own API to Provide a New View 544
xiv Contents

Appendix A Advanced Module System Techniques 551


A.1 Hiding Implementation Details 551
A.2 Design for Extensibility 553
A.3 Splitting API and Implementation 555
A.4 Do I Really Need Cyclic Dependency? 559
A.5 Crossing the Informational Divide 563
A.6 Restricting Access to Friends 565
A.7 Having Public as Well as Friend API 566
A.8 A Final Word on Modularity 568

Appendix B Common Idioms and Code Patterns in NetBeans 569


B.1 Things You Do Differently in NetBeans Than in Plain Swing Code 569
B.2 Things That Represent Files 571
B.3 Working with Lookup 573
B.4 Projects 573

Appendix C Performance 575


C.1 Responsiveness versus Performance 577
C.2 Performance Tips for Module Authors 578
C.3 Writing Modules That Are Good Citizens 579

Index 583
Foreword
by Jonathan Schwartz

Great technology stays just that—great technology—without great tools. Great


tools enable great technology to reach global audiences, transform industries,
and, quite literally, change the face of the Internet. And now you understand
our view on the importance of NetBeans—to Sun, to the Internet, and to the
user community at large.
Now, every product or network service starts with an idea. Turning ideas
into reality is what NetBeans has been all about, ever since a very small team
in Prague joined a bigger team in Menlo Park, California—and an even bigger
team across the globe. From that small beginning, among a small but loyal
community of users and developers, NetBeans has become the fastest growing
multiplatform development environment we’ve ever seen.
The growth has been tremendous—a result of fierce competition, innova-
tion, reinvention, and commitment; and we see no limit to the growth across
the world.
As I said back in the days when I was running Sun’s Developer Tools
group, there are two ways to understand the strategy of a technology company.
The first is to see how they compensate their sales force, to understand their
immediate tactical priorities. The second is to look at the roadmap for their
developer tools, to understand their longer-term, strategic priorities.

xv
xvi Foreword

To that end, there is no product at Sun that better represents the future
we envision than NetBeans. And on behalf of Sun, as just one member among
many in the community now chartered with its evolution, and as one among
many in the corporate user communities, I can say without reservation that
it’s a thrilling future indeed.

Jonathan Schwartz
Chief Executive Officer and President of Sun Microsystems, Inc.
blogs.sun.com/jonathan
Foreword
by Jan Chalupa

I started using NetBeans Developer 2.0 in the late 1990s, but I didn’t care about
its internals until I joined Sun and the NetBeans team in 2000 to work on
NetBeans 3.0. I was coming from the world of Win 32 APIs, MFC, and COM,
was moderately familiar with Java libraries and Swing, read the “Gang of Four”
bible and all kinds of other books on design patterns and object-oriented
programming. In many aspects, what I found in the NetBeans APIs didn’t re-
semble anything I was used to. “What kind of pattern is this Cookie thing?”
I wondered. “Why is the class that represents a simple view or window called
TopComponent?” “What is the difference among FileObjects, DataObjects,
and Nodes?” “SplittedPanel? Doesn’t sound like correct grammar to me.”
And surprisingly, despite the prevalent code hacking and antiauthority culture
inherent to the NetBeans core team, almost everything in NetBeans was
accessible through a singleton class called TopManager.
However, soon I started to find out that no matter how weird some of the
names or concepts could seem, NetBeans was architected with reusability and
extensibility in mind and allowed developers to add new features easily—or
even build their own applications by reusing NetBeans core classes as a
framework. I came to realize that NetBeans wasn’t just an IDE, but also a very
powerful concept that could save application developers years of development
time. NetBeans was a platform.

xvii
xviii Foreword

I also figured out why some of the building blocks looked unfamiliar and
a little awkward at first glance. NetBeans started as a students’ project in the
mid-nineties. Most of the developers, including the architects, were university
students or fresh graduates with very little experience in software design. They
worked extremely hard while learning on the fly. Sometimes inventing the
wheel, sometimes introducing new names for existing things, and sometimes,
admittedly, making design mistakes. In spite of all this, the original idea of an
extensible application platform implemented in Java turned out to be very
smart, innovative, and forward-looking.
NetBeansTM: The Definitive Guide (O’Riley), written in 2001–2002 and the
only comprehensive book on NetBeans APIs to date, was the first attempt to
make the NetBeans Platform available to a wider developer audience. Unfor-
tunately, it was the time when the most serious architectural flaws began to
emerge and became blockers for future development of the platform. By the
time NetBeansTM: The Definitive Guide was published, some of the APIs de-
scribed in the book were gone and new APIs were introduced. The primary
focus had shifted to making a really solid IDE, while the platform evangeliza-
tion had been put on the back burner, known only to those who were really
close to the NetBeans developer community.
Nevertheless, the NetBeans Platform did not disappear. Over several years,
it just got better and more mature. SplittedPanel got deprecated. So did
TopManager, replaced with the Lookup concept allowing for feature discov-
erability and intermodule communication in a distributed and loosely coupled
modular architecture. Many APIs got polished and stabilized. NetBeans IDE
5.0 added extensive support for developing modules and building applications
based on the NetBeans Platform. Creating a new module became simpler than
ever before. The platform.netbeans.org site was established and became
a valuable source of documentation, articles, and tutorials about the platform.
The only thing that was still missing was a new book. I would like to thank
Tim, Jarda, Geertjan, and many other contributors for filling this gap. I believe
it will make the NetBeans Platform accessible to many new developers.

Jan Chalupa
NetBeans Director
Preface

Welcome to the world of rich client development on the NetBeans Platform.


Though the Internet boom pushed much programming effort to the
server side, the demand for quality desktop software remains and is arguably
increasing. Some of the reasons include
• Web pages, which are generally the interfaces for server-driven
applications, often are insufficient for the needs of the end user.
• Not every application requires a constant Internet connection, and some
applications need to function offline.
In this book, we will focus on using the NetBeans Platform as a framework
for creating rich client applications that can be written once and then run on
any operating system. The NetBeans Platform is the foundation of the
NetBeans IDE, which helps hundreds of thousands of programmers develop
applications of all sizes and complexity. As such, the platform is a very power-
ful and robust base that you can use for your own applications, whether they
are commercial applications or in-house solutions. In addition, we will show
you what you need to know to create modules to plug into the NetBeans
IDE itself.

xix
Other documents randomly have
different content
The Project Gutenberg eBook of The Revolt of
the Oyster
This ebook is for the use of anyone anywhere in the United States
and most other parts of the world at no cost and with almost no
restrictions whatsoever. You may copy it, give it away or re-use it
under the terms of the Project Gutenberg License included with this
ebook or online at www.gutenberg.org. If you are not located in the
United States, you will have to check the laws of the country where
you are located before using this eBook.

Title: The Revolt of the Oyster

Author: Don Marquis

Release date: May 1, 2016 [eBook #51917]


Most recently updated: October 23, 2024

Language: English

Credits: Produced by David Widger from page images generously


provided by the Internet Archive

*** START OF THE PROJECT GUTENBERG EBOOK THE REVOLT OF


THE OYSTER ***
THE REVOLT OF THE OYSTER
By Don Marquis
Garden City, New York

Doubleday, Page and Company

1922
CONTENTS
THE REVOLT OF THE OYSTER
“IF WE COULD ONLY SEE”
HOW HANK SIGNED THE PLEDGE
ACCURSED HAT
ROONEY'S TOUCHDOWN
TOO AMERICAN
THE SADDEST MAN
DOGS AND BOYS (As told by the dog)
BILL PATTERSON
BLOOD WILL TELL (As told by the dog)
BEING A PUBLIC CHARACTER (As told by the dog)
WRITTEN IN BLOOD (As told by the dogs)
THE REVOLT OF THE OYSTER
“Our remote ancestor was probably arboreal.”—Eminent scientist.

F
rom his hut in the tree-top Probably Arboreal looked lazily
down a broad vista, still strewn with fallen timber as the result
of a whirlwind that had once played havoc in that part of the
forest, toward the sea. Beyond the beach of hard white sand the
water lay blue and vast and scarcely ruffled by the light morning
wind. All the world and his wife were out fishing this fine day.
Probably Arboreal could see dozens of people from where he
crouched, splashing in the water or moving about the beach; and
even hear their cries borne faintly to him on the breeze. They fished,
for the most part, with their hands; and when one caught a fish it
was his custom to eat it where he caught it, standing in the sea.
In Probably Arboreal's circle, one often bathed and breakfasted
simultaneously; if a shark or saurian were too quick for one, one
sometimes was breakfasted upon as one bathed.
In the hut next to Probably Arboreal, his neighbour, Slightly
Simian, was having an argument with Mrs. Slightly, as usual. And, as
usual, it concerned the proper manner of bringing up the children.
Probably listened with the bored distaste of a bachelor.
“I will slap his feet every time he picks things up with them!”
screamed Slightly Simian's wife, an accredited shrew, in her shrill
falsetto..
“It's natural for a child to use his feet that way,” insisted the good-
natured Slightly, “and I don't intend to have the boy punished for
what's natural.” Probably Arboreal grinned; he could fancy the
expression on Old Sim's face as his friend made this characteristically
plebeian plea.
“You can understand once for all, Slightly,” said that gentleman's
wife in a tone of finality, “that I intend to supervise the bringing-up
of these children. Just because your people had neither birth nor
breeding nor manners——”
“Mrs. S.!” broke in Slightly, with a warning in his voice. “Don't you
work around to anything caudal, now, Mrs. S.! Or there'll be trouble.
You get me?”
On one occasion Mrs. Slightly had twitted her spouse with the fact
that his grandfather had a tail five inches long; she had never done
so again. Slightly Simian himself, in his moments of excitement,
picked things up with his feet, but like many other men of humble
origin who have become personages in their maturity, he did not
relish having such faults commented upon.
“Poor old Sim,” mused Probably Arboreal, as he slid down the tree
and ambled toward the beach, to be out of range of the family
quarrel. “She married him for his property, and now she's sore on
him because there isn't more of it.”
Nevertheless, in spite of the unpleasant effect of the quarrel,
Probably found his mind dwelling upon matrimony that morning. A
girl with bright red hair, into which she had tastefully braided a
number of green parrot feathers, hit him coquettishly between the
shoulder blades with a handful of wet sand and gravel as he went
into the water. Ordinarily he would either have taken no notice at all
of her, or else would have broken her wrist in a slow, dignified,
manly sort of way. But this morning he grabbed her tenderly by the
hair and sentimentally ducked her. When she was nearly drowned he
released her. She came out of the water squealing with rage like a
wild-cat and bit him on the shoulder.
“Parrot Feathers,” he said to her, with an unwonted softness in his
eyes, as he clutched her by the throat and squeezed, “beware how
you trifle with a man's affections—some day I may take you
seriously!”
He let the girl squirm loose, and she scrambled out upon the
beach and threw shells and jagged pieces of flint at him, with an
affectation of coyness. He chased her, caught her by the hair again,
and scored the wet skin on her arms with a sharp stone, until she
screamed with the pain, and as he did it he hummed an old love
tune, for to-day there was an April gladness in his heart.
“Probably! Probably Arboreal!” He spun around to face the girl's
father, Crooked Nose, who was contentedly munching a mullet.
“Probably,” said Crooked Nose, “you are flirting with my daughter!”
“Father!” breathed the girl, ashamed of her parent's tactlessness.
“How can you say that!”
“I want to know,” said Crooked Nose, as sternly as a man can who
is masticating mullet, “whether your intentions are serious and
honourable.”
“Oh, father!” said Parrot Feathers again. And putting her hands in
front of her face to hide her blushes she ran off. Nevertheless, she
paused when a dozen feet away and threw a piece of drift-wood at
Probably Arboreal. It hit him on the shin, and as he rubbed the spot,
watching her disappear into the forest, he murmured aloud, “Now, I
wonder what she means by that!”
“Means,” said Crooked Nose. “Don't be an ass, Probably! Don't
pretend to me you don't know what the child means. You made her
love you. You have exercised your arts of fascination on an innocent
young girl, and now you have the nerve to wonder what she means.
What'll you give me for her?”
“See here, Crooked Nose,” said Probably, “don't bluster with me.”
His finer sensibilities were outraged. He did not intend to be coerced
into matrimony by any father, even though he were pleased with
that father's daughter. “I'm not buying any wives to-day, Crooked
Nose.”
“You have hurt her market value,” said Crooked Nose, dropping his
domineering air, and affecting a willingness to reason. “Those marks
on her arms will not come off for weeks. And what man wants to
marry a scarred-up woman unless he has made the scars himself?”
“Crooked Nose,” said Probably Arboreal, angry at the whole world
because what might have been a youthful romance had been given
such a sordid turn by this disgusting father, “if you don't go away I
will scar every daughter you've got in your part of the woods. Do
you get me?”
“I wish you'd look them over,” said Crooked Nose. “You might do
worse than marry all of them.”
“I'll marry none of them!” cried Probably, in a rage, and turned to
go into the sea again.
A heavy boulder hurtled past his head. He whirled about and
discovered Crooked Nose in the act of recovering his balance after
having flung it. He caught the old man half way between the beach
and the edge of the forest. The clan, including Crooked Nose's four
daughters, gathered round in a ring to watch the fight.
It was not much of a combat. When it was over, and the girls took
hold of what remained of their late parent to drag him into the
woods, Probably Arboreal stepped up to Parrot Feathers and laid his
hand upon her arm.
“Feathers,” he said, “now that there can be no question of
coercion, will you and your sisters marry me?”
She turned toward him with a sobered face. Grief had turned her
from a girl into a woman.
“Probably,” she said, “you are only making this offer out of
generosity. It is not love that prompts it. I cannot accept. As for my
sisters, they must speak for themselves.”
“You are angry with me, Feathers?”
The girl turned sadly away. Probably watched the funeral cortège
winding into the woods, and then went moodily back to the ocean.
Now that she had refused him, he desired her above all things. But
how to win her? He saw clearly that it could be no question of brute
force. It had gone beyond that. If he used force with her, it must
infallibly remind her of the unfortunate affair with her father. Some
heroic action might attract her to him again. Probably resolved to be
a hero at the very earliest opportunity.
In the meantime he would breakfast. Breakfast had already been
long delayed; and it was as true then, far back in the dim dawn of
time, as it is now, that he who does not breakfast at some time
during the day must go hungry to bed at night. Once more Probably
Arboreal stepped into the ocean—stepped in without any
premonition that he was to be a hero indeed; that he was chosen by
Fate, by Destiny, by the Presiding Genius of this planet, by whatever
force or intelligence you will, to champion the cause of all Mankind in
a crucial struggle for human supremacy.
He waded into the water up to his waist, and bent forward with
his arms beneath the surface, patiently waiting. It was thus that our
remote ancestors fished. Fish ran larger in those days, as a rule. In
the deeper waters they were monstrous. The smaller fish therefore
sought the shallows where the big ones, greedy cannibals, could not
follow them. A man seldom stood in the sea as Probably Arboreal
was doing more than ten minutes without a fish brushing against
him either accidentally or because the fish thought the man was
something good to eat. As soon as a fish touched him, the man
would grab for it. If he were clumsy and missed too many fish, he
starved to death. Experts survived because they were expert; by a
natural process of weeding out the awkward it had come about that
men were marvellously adept. A bear who stands by the edge of a
river watching for salmon at the time of the year when they rim up
stream to spawn, and scoops them from the water with a deft twitch
of his paw, was not more quick or skillful than Probably Arboreal.
Suddenly he pitched forward, struggling; he gave a gurgling
shout, and his head disappeared beneath the water.
When it came up again, he twisted toward the shore, with lashing
arms and something like panic on his face, and shouted:
“Oh! Oh! Oh!” he cried. “Something has me by the foot!”
Twenty or thirty men and women who heard the cry stopped
fishing and straightened up to look at him.
“Help! Help!” he shouted again. “It is pulling me out to sea!”
A knock-kneed old veteran, with long intelligent-looking mobile
toes, broke from the surf and scurried to the safety of the beach,
raising the cry:
“A god! A god! A water-god has caught Probably Arboreal!”
“More likely a devil!” cried Slightly Simian, who had followed
Probably to the water.
And all his neighbours plunged to land and left Probably Arboreal
to his fate, whatever his fate was to be. But since spectacles are
always interesting, they sat down comfortably on the beach to see
how long it would be before Probably Arboreal disappeared. Gods
and devils, sharks and octopi, were forever grabbing one of their
number and making off to deep water with him to devour him at
their leisure. If the thing that dragged the man were seen, if it
showed itself to be a shark or an octopus, a shark or an octopus it
was; if it were unseen, it got the credit of being a god or a devil.
“Help me!” begged Probably Arboreal, who was now holding his
own, although he was not able to pull himself into shallower water.
“It is not a god or a devil. It doesn't feel like one. And it isn't a
shark, because it hasn't any teeth. It is an animal like a cleft stick,
and my foot is in the cleft.”
But they did not help him. Instead, Big Mouth, a seer and vers
libre poet of the day, smitten suddenly with an idea, raised a chant,
and presently all the others joined in. The chant went like this:

“Probably, he killed Crooked Nose,


He killed him with his fists.
And Crooked Nose, he sent his ghost to sea
To catch his slayer by the foot!
The ghost of Crooked Nose will drown his
slayer,
Drown, drown, drown his slayer,
The ghost of Crooked Nose will drown his
slayer,
Drown his slayer in the seal”
“You are a liar, Big Mouth!” spluttered Probably Arboreal, hopping
on one foot and thrashing the water with his arms. “It is not a
ghost; it is an animal.”
But the chant kept up, growing louder and louder:

“The ghost of Crooked Nose will drown his


slayer!
Drown, drown, drown his slayer,
Drown his slayer in the sea!”

Out of the woods came running more and more people at the
noise of the chant. And as they caught what was going on, they took
up the burden of it, until hundreds and thousands of them were
singing it.
But, with a mighty turn and struggle, Probably Arboreal went
under again, as to his head and body; his feet for an instant swished
into the air, and everyone but Probably Arboreal himself saw what
was hanging on to one of them.
It was neither ghost, shark, god, nor devil. It was a monstrous
oyster; a bull oyster, evidently. All oysters were much larger in those
days than they are now, but this oyster was a giant, a mastodon, a
mammoth among oysters, even for those days.
“It is an oyster, an oyster, an oyster!” cried the crowd, as Probably
Arboreal's head and shoulders came out of the water again.
Big Mouth, the poet, naturally chagrined, and hating to yield up
his dramatic idea, tried to raise another chant:

“The ghost of Crooked Nose went into an


oyster,
The oyster caught his slayer by the foot
To drown, drown, drown him in the sea!”
But it didn't work. The world had seen that oyster, and had
recognized it for an oyster.
“Oyster! Oyster! Oyster!” cried the crowd sternly at Big Mouth.
The bard tried to persevere, but Slightly Simian, feeling the crowd
with him, advanced menacingly and said:
“See here, Big Mouth, we know a ghost when we see one, and we
know an oyster! Yon animal is an oyster! You sing that it is an oyster,
or shut up!”
“Ghost, ghost, ghost,” chanted Big Mouth, tentatively. But he got
no farther. Slightly Simian killed him with a club, and the matter was
settled. Literary criticism was direct, straightforward, and effective in
those days.
“But, oh, ye gods of the water, what an oyster!” cried Mrs. Slightly
Simian.
And as the thought took them all, a silence fell over the multitude.
They looked at the struggling man in a new community of idea.
Oysters they had seen before, but never an oyster like this. Oysters
they knew not as food; but they had always regarded them as rather
ineffectual and harmless creatures. Yet this bold oyster was actually
giving battle, and on equal terms, to a man! Were oysters
henceforth to be added to the number of man's enemies? Were
oysters about to attempt to conquer mankind? This oyster, was he
the champion of the sea, sent up out of its depths, to grapple with
mankind for supremacy?
Dimly, vaguely, as they watched the man attempt to pull the
oyster ashore, and the oyster attempt to pull the man out to sea,
some sense of the importance of this struggle was felt by mankind.
Over forest, beach, and ocean hung the sense of momentous things.
A haze passed across the face of the bright morning sun; the breeze
died down; it was as if all nature held her breath at this struggle.
And if mankind upon the land was interested, the sea was no less
concerned. For, of sudden, and as if by preconcerted signal, a
hundred thousand oysters poked their heads above the surface of
the waters and turned their eyes—they had small fiery opalescent
eyes in those days—upon the combat.
At this appearance, mankind drew back with a gasp, but no word
was uttered. The visible universe, perturbed earth and bending
heavens alike, was tense and dumb. On their part, the oysters made
no attempt to go to the assistance of their champion. Nor did
mankind leap to the rescue of Probably Arboreal. Tacitly, each side,
in a spirit of fair play, agreed not to interfere; agreed to leave the
combat to the champions; agreed to abide by the issue.
But while they were stirred and held by the sense of tremendous
things impending, neither men nor oysters could be expected to
understand definitely what almost infinite things depended upon this
battle. There were no Darwins then. Evolution had not yet evolved
the individual able to catch her at it.
But she was on her way. This very struggle was one of the crucial
moments in the history of evolution. There have always been these
critical periods when the two highest species in the world were
about equal in intelligence, and it was touch and go as to which
would survive and carry on the torch, and which species would lose
the lead and become subservient. There have always been exact
instants when the spirit of progress hesitated as between the forms
of life, doubtful as to which one to make its representative.
Briefly, if the oyster conquered the man, more and more oysters,
emboldened by this success, would prey upon men. Man, in the
course of a few hundred thousand years, would become the creature
of the oyster; the oyster's slave and food. Then the highest type of
life on the planet would dwell in the sea. The civilization which was
not yet would be a marine growth when it did come; the intellectual
and spiritual and physical supremacy held by the biped would pass
over to the bivalve.
Thought could not frame this concept then; neither shellfish nor
tree-dweller uttered it. But both the species felt it; they watched
Probably Arboreal and the oyster with a strangling emotion, with a
quivering intentness, that was none the less poignant because there
was no Huxley or Spencer present to interpret it for them; they
thrilled and sweat and shivered with the shaken universe, and the
red sun through its haze peered down unwinking like the vast
bloodshot eye of life.
An hour had passed by in silence except for the sound of the
battle, more and more men and more and more oysters had
gathered about the scene of the struggle; the strain was telling on
both champions. Probably Arboreal had succeeded in dragging the
beast some ten feet nearer the shore, but the exertion had told upon
him; he was growing tired; he was breathing with difficulty; he had
swallowed a great deal of salt water. He too was dimly conscious of
the importance of this frightful combat; he felt himself the
representative of the human race. He was desperate but cool; he
saved his breath; he opposed to the brute force of the oyster the
cunning of a man. But he was growing weaker; he felt it.
If only those for whom he was fighting would fling him some word
of encouragement! He was too proud to ask it, but he felt bitterly
that he was not supported, for he could not realize what emotion
had smitten dumb his fellow men. He had got to the place where a
word of spiritual comfort and encouragement would have meant as
much as fifty pounds of weight in his favour.
He had, in fact, arrived at the Psychological Moment. There were
no professing psychologists then; but there was psychology; and it
worked itself up into moments even as it does to-day.
Probably Arboreal's head went under the water, tears and salt
ocean mingled nauseatingly in his mouth.
“I am lost,” he gurgled.
But at that instant a shout went up—the shrill, high cry of a
woman. Even in his agony he recognized that voice—the voice of
Parrot Feathers! With a splendid rally he turned his face toward the
shore.
She was struggling through the crowd, fighting her way to the
front rank with the fury of a wildcat. She had just buried her father,
and the earth was still dark and damp upon her hands, but the
magnificent creature had only one thought now. She thought only of
her lover, her heroic lover; in her nobility of soul she had been able
to rise above the pettiness of spirit which another woman might
have felt; she knew no pique or spite. Her lover was in trouble, and
her place was nigh him; so she flung a false maidenly modesty to
the winds and acknowledged him and cheered him on, careless of
what the assembled world might think.
She arrived at the Psychological Moment.
“Probably! Probably!” she cried. “Don't give up! Don't give up! For
my sake!”
For her sake! The words were like fire in the veins of the
struggling hero. He made another bursting effort, and gained a yard.
But the rally had weakened him; the next instant his head went
under the water once more. Would it ever appear again? There was
a long, long moment, while all mankind strangled and gasped in
sympathetic unison, and then our hero's dripping head did emerge.
It had hit a stone under water, and it was bleeding, but it emerged.
One eye was nearly closed. 4 +
“Watch him! Watch him!” shouted Parrot Feathers. “Don't let him
do that again! When he has you under water he whacks your eye
with his tail. He's trying to blind you!”
And, indeed, these seemed to be the desperate oyster's tactics. If
he could once destroy our hero's sight, the end would soon come.
“Probably—do you hear me?”
He nodded his head; he was beyond speech.
“Take a long breath and dive! Do you get me? Dive! Dive at your
own feet! Grab your feet in your hands and roll under water in a
bunch! Roll toward the beach!”'
It was a desperate manouvre, especially for a man who had
already been under water so much that morning. But the situation
was critical and called for the taking of big chances. It would either
succeed—or fail. And death was no surer if it failed than if he
waited. Probably Arboreal ceased to think; he yielded up his
reasoning powers to the noble and courageous woman on the sand;
he dived and grabbed his feet and rolled.
“Again! Again!” she cried. “Another long breath and roll again!”
Her bosom heaved, as if she were actually breathing for him. To
Probably Arboreal, now all but drowned, and almost impervious to
feeling, it also seemed as if he were breathing with her lungs; and
yet he hardly dared to dive and roll again. He struggled in the water
and stared at her stupidly.
She sent her unusual and electric personality thrilling into him
across the intervening distance; she held him with her eyes, and
filled him with her spirit.
“Roll!” she commanded. “Probably! Roll!”
And under the lash of her courage, he rolled again. Three more
times he rolled... and then... unconscious, but still breathing, he was
in her arms.
As he reached the land half a million oysters sank into the sea in
the silence of defeat and despair, while from the beaches rose a
mighty shout.
The sun, as if it gestured, flung the mists from its face, and
beamed benignly.
“Back! Back! Give him air!” cried Parrot Feathers, as she addressed
herself to the task of removing the oyster from his foot.
The giant beast was dying, and its jaws were locked in the rigour
of its suffering. There was no way to remove it gently. Parrot
Feathers laid her unconscious hero's foot upon one rock, and broke
the oyster loose with another.
Incidentally she smashed Probably Arboreal's toe.
He sat up in pained surprise. Unthinkingly, as you or I would put a
hurt finger into our mouths, he put his crushed toe into his mouth.
At that period of man's history the trick was not difficult. And then
——
A beatific smile spread over his face!
Man had tasted the oyster!
In half an hour, mankind was plunging into the waves searching
for oysters. The oyster's doom was sealed. His monstrous pretension
that he belonged in the van of evolutionary progress was killed
forever. He had been tasted, and found food. He would never again
battle for supremacy. Meekly he yielded to his fate. He is food to this
day.
Parrot Feathers and Probably Arboreal were married after
breakfast. On the toes of their first child were ten cunning,
diminutive oyster shells. Mankind, up to that time, had had sharp
toenails like the claws of birds. But the flat, shell-like toenails, the
symbols of man's triumph over, and trampling down of, the oyster
were inherited from the children of this happy couple.
They persist to this day.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookultra.com

You might also like