aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/java/awt
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>2005-07-16 00:30:23 +0000
committerTom Tromey <tromey@gcc.gnu.org>2005-07-16 00:30:23 +0000
commitf911ba985aa7fe0096c386c5be385ac5825ea527 (patch)
treea0b991cf5866ae1d616639b906ac001811d74508 /libjava/classpath/java/awt
parent6f4434b39b261de5317dc81ddfdd94d2e1d62b11 (diff)
downloadgcc-f911ba985aa7fe0096c386c5be385ac5825ea527.zip
gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.gz
gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.bz2
Initial revision
From-SVN: r102074
Diffstat (limited to 'libjava/classpath/java/awt')
-rw-r--r--libjava/classpath/java/awt/AWTError.java64
-rw-r--r--libjava/classpath/java/awt/AWTEvent.java278
-rw-r--r--libjava/classpath/java/awt/AWTEventMulticaster.java1209
-rw-r--r--libjava/classpath/java/awt/AWTException.java64
-rw-r--r--libjava/classpath/java/awt/AWTKeyStroke.java660
-rw-r--r--libjava/classpath/java/awt/AWTPermission.java121
-rw-r--r--libjava/classpath/java/awt/ActiveEvent.java61
-rw-r--r--libjava/classpath/java/awt/Adjustable.java171
-rw-r--r--libjava/classpath/java/awt/AlphaComposite.java167
-rw-r--r--libjava/classpath/java/awt/AttributeValue.java98
-rw-r--r--libjava/classpath/java/awt/BasicStroke.java248
-rw-r--r--libjava/classpath/java/awt/BorderLayout.java731
-rw-r--r--libjava/classpath/java/awt/BufferCapabilities.java253
-rw-r--r--libjava/classpath/java/awt/Button.java466
-rw-r--r--libjava/classpath/java/awt/Canvas.java354
-rw-r--r--libjava/classpath/java/awt/CardLayout.java483
-rw-r--r--libjava/classpath/java/awt/Checkbox.java649
-rw-r--r--libjava/classpath/java/awt/CheckboxGroup.java173
-rw-r--r--libjava/classpath/java/awt/CheckboxMenuItem.java355
-rw-r--r--libjava/classpath/java/awt/Choice.java638
-rw-r--r--libjava/classpath/java/awt/Color.java1008
-rw-r--r--libjava/classpath/java/awt/ColorPaintContext.java195
-rw-r--r--libjava/classpath/java/awt/Component.java6017
-rw-r--r--libjava/classpath/java/awt/ComponentOrientation.java215
-rw-r--r--libjava/classpath/java/awt/Composite.java73
-rw-r--r--libjava/classpath/java/awt/CompositeContext.java71
-rw-r--r--libjava/classpath/java/awt/Container.java2026
-rw-r--r--libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java413
-rw-r--r--libjava/classpath/java/awt/Cursor.java224
-rw-r--r--libjava/classpath/java/awt/DefaultFocusTraversalPolicy.java109
-rw-r--r--libjava/classpath/java/awt/DefaultKeyboardFocusManager.java536
-rw-r--r--libjava/classpath/java/awt/Dialog.java553
-rw-r--r--libjava/classpath/java/awt/Dimension.java234
-rw-r--r--libjava/classpath/java/awt/DisplayMode.java164
-rw-r--r--libjava/classpath/java/awt/Event.java185
-rw-r--r--libjava/classpath/java/awt/EventDispatchThread.java94
-rw-r--r--libjava/classpath/java/awt/EventQueue.java552
-rw-r--r--libjava/classpath/java/awt/FileDialog.java318
-rw-r--r--libjava/classpath/java/awt/FlowLayout.java364
-rw-r--r--libjava/classpath/java/awt/FocusTraversalPolicy.java103
-rw-r--r--libjava/classpath/java/awt/Font.java1336
-rw-r--r--libjava/classpath/java/awt/FontFormatException.java65
-rw-r--r--libjava/classpath/java/awt/FontMetrics.java425
-rw-r--r--libjava/classpath/java/awt/Frame.java649
-rw-r--r--libjava/classpath/java/awt/GradientPaint.java229
-rw-r--r--libjava/classpath/java/awt/Graphics.java767
-rw-r--r--libjava/classpath/java/awt/Graphics2D.java158
-rw-r--r--libjava/classpath/java/awt/GraphicsConfigTemplate.java106
-rw-r--r--libjava/classpath/java/awt/GraphicsConfiguration.java218
-rw-r--r--libjava/classpath/java/awt/GraphicsDevice.java292
-rw-r--r--libjava/classpath/java/awt/GraphicsEnvironment.java244
-rw-r--r--libjava/classpath/java/awt/GridBagConstraints.java195
-rw-r--r--libjava/classpath/java/awt/GridBagLayout.java1069
-rw-r--r--libjava/classpath/java/awt/GridBagLayoutInfo.java70
-rw-r--r--libjava/classpath/java/awt/GridLayout.java360
-rw-r--r--libjava/classpath/java/awt/HeadlessException.java72
-rw-r--r--libjava/classpath/java/awt/IllegalComponentStateException.java71
-rw-r--r--libjava/classpath/java/awt/Image.java203
-rw-r--r--libjava/classpath/java/awt/ImageCapabilities.java107
-rw-r--r--libjava/classpath/java/awt/Insets.java158
-rw-r--r--libjava/classpath/java/awt/ItemSelectable.java75
-rw-r--r--libjava/classpath/java/awt/JobAttributes.java500
-rw-r--r--libjava/classpath/java/awt/KeyEventDispatcher.java82
-rw-r--r--libjava/classpath/java/awt/KeyEventPostProcessor.java81
-rw-r--r--libjava/classpath/java/awt/KeyboardFocusManager.java1478
-rw-r--r--libjava/classpath/java/awt/Label.java314
-rw-r--r--libjava/classpath/java/awt/LayoutManager.java92
-rw-r--r--libjava/classpath/java/awt/LayoutManager2.java100
-rw-r--r--libjava/classpath/java/awt/List.java1263
-rw-r--r--libjava/classpath/java/awt/MediaTracker.java697
-rw-r--r--libjava/classpath/java/awt/Menu.java468
-rw-r--r--libjava/classpath/java/awt/MenuBar.java423
-rw-r--r--libjava/classpath/java/awt/MenuComponent.java1324
-rw-r--r--libjava/classpath/java/awt/MenuContainer.java71
-rw-r--r--libjava/classpath/java/awt/MenuItem.java603
-rw-r--r--libjava/classpath/java/awt/MenuShortcut.java207
-rw-r--r--libjava/classpath/java/awt/PageAttributes.java482
-rw-r--r--libjava/classpath/java/awt/Paint.java79
-rw-r--r--libjava/classpath/java/awt/PaintContext.java76
-rw-r--r--libjava/classpath/java/awt/Panel.java173
-rw-r--r--libjava/classpath/java/awt/Point.java245
-rw-r--r--libjava/classpath/java/awt/Polygon.java613
-rw-r--r--libjava/classpath/java/awt/PopupMenu.java169
-rw-r--r--libjava/classpath/java/awt/PrintGraphics.java57
-rw-r--r--libjava/classpath/java/awt/PrintJob.java104
-rw-r--r--libjava/classpath/java/awt/Rectangle.java749
-rw-r--r--libjava/classpath/java/awt/RenderingHints.java803
-rw-r--r--libjava/classpath/java/awt/Robot.java423
-rw-r--r--libjava/classpath/java/awt/ScrollPane.java615
-rw-r--r--libjava/classpath/java/awt/ScrollPaneAdjustable.java200
-rw-r--r--libjava/classpath/java/awt/Scrollbar.java825
-rw-r--r--libjava/classpath/java/awt/Shape.java203
-rw-r--r--libjava/classpath/java/awt/Stroke.java65
-rw-r--r--libjava/classpath/java/awt/SystemColor.java462
-rw-r--r--libjava/classpath/java/awt/TextArea.java629
-rw-r--r--libjava/classpath/java/awt/TextComponent.java739
-rw-r--r--libjava/classpath/java/awt/TextField.java541
-rw-r--r--libjava/classpath/java/awt/TexturePaint.java75
-rw-r--r--libjava/classpath/java/awt/Toolkit.java995
-rw-r--r--libjava/classpath/java/awt/Transparency.java67
-rw-r--r--libjava/classpath/java/awt/Window.java1125
-rw-r--r--libjava/classpath/java/awt/color/CMMException.java63
-rw-r--r--libjava/classpath/java/awt/color/ColorSpace.java183
-rw-r--r--libjava/classpath/java/awt/color/ICC_ColorSpace.java314
-rw-r--r--libjava/classpath/java/awt/color/ICC_Profile.java1244
-rw-r--r--libjava/classpath/java/awt/color/ICC_ProfileGray.java133
-rw-r--r--libjava/classpath/java/awt/color/ICC_ProfileRGB.java227
-rw-r--r--libjava/classpath/java/awt/color/ProfileDataException.java64
-rw-r--r--libjava/classpath/java/awt/color/package.html46
-rw-r--r--libjava/classpath/java/awt/datatransfer/Clipboard.java114
-rw-r--r--libjava/classpath/java/awt/datatransfer/ClipboardOwner.java57
-rw-r--r--libjava/classpath/java/awt/datatransfer/DataFlavor.java1034
-rw-r--r--libjava/classpath/java/awt/datatransfer/FlavorMap.java75
-rw-r--r--libjava/classpath/java/awt/datatransfer/FlavorTable.java73
-rw-r--r--libjava/classpath/java/awt/datatransfer/MimeTypeParseException.java70
-rw-r--r--libjava/classpath/java/awt/datatransfer/StringSelection.java158
-rw-r--r--libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java169
-rw-r--r--libjava/classpath/java/awt/datatransfer/Transferable.java83
-rw-r--r--libjava/classpath/java/awt/datatransfer/UnsupportedFlavorException.java65
-rw-r--r--libjava/classpath/java/awt/datatransfer/package.html47
-rw-r--r--libjava/classpath/java/awt/dnd/Autoscroll.java70
-rw-r--r--libjava/classpath/java/awt/dnd/DnDConstants.java77
-rw-r--r--libjava/classpath/java/awt/dnd/DnDEventMulticaster.java74
-rw-r--r--libjava/classpath/java/awt/dnd/DragGestureEvent.java156
-rw-r--r--libjava/classpath/java/awt/dnd/DragGestureListener.java63
-rw-r--r--libjava/classpath/java/awt/dnd/DragGestureRecognizer.java179
-rw-r--r--libjava/classpath/java/awt/dnd/DragSource.java257
-rw-r--r--libjava/classpath/java/awt/dnd/DragSourceAdapter.java126
-rw-r--r--libjava/classpath/java/awt/dnd/DragSourceContext.java200
-rw-r--r--libjava/classpath/java/awt/dnd/DragSourceDragEvent.java102
-rw-r--r--libjava/classpath/java/awt/dnd/DragSourceDropEvent.java89
-rw-r--r--libjava/classpath/java/awt/dnd/DragSourceEvent.java93
-rw-r--r--libjava/classpath/java/awt/dnd/DragSourceListener.java97
-rw-r--r--libjava/classpath/java/awt/dnd/DragSourceMotionListener.java64
-rw-r--r--libjava/classpath/java/awt/dnd/DropTarget.java293
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetAdapter.java100
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetContext.java188
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetDragEvent.java140
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetDropEvent.java170
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetEvent.java56
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetListener.java89
-rw-r--r--libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java73
-rw-r--r--libjava/classpath/java/awt/dnd/MouseDragGestureRecognizer.java131
-rw-r--r--libjava/classpath/java/awt/dnd/package.html46
-rw-r--r--libjava/classpath/java/awt/dnd/peer/DragSourceContextPeer.java57
-rw-r--r--libjava/classpath/java/awt/dnd/peer/DropTargetContextPeer.java68
-rw-r--r--libjava/classpath/java/awt/dnd/peer/DropTargetPeer.java48
-rw-r--r--libjava/classpath/java/awt/dnd/peer/package.html46
-rw-r--r--libjava/classpath/java/awt/event/AWTEventListener.java65
-rw-r--r--libjava/classpath/java/awt/event/AWTEventListenerProxy.java155
-rw-r--r--libjava/classpath/java/awt/event/ActionEvent.java226
-rw-r--r--libjava/classpath/java/awt/event/ActionListener.java59
-rw-r--r--libjava/classpath/java/awt/event/AdjustmentEvent.java222
-rw-r--r--libjava/classpath/java/awt/event/AdjustmentListener.java58
-rw-r--r--libjava/classpath/java/awt/event/ComponentAdapter.java97
-rw-r--r--libjava/classpath/java/awt/event/ComponentEvent.java137
-rw-r--r--libjava/classpath/java/awt/event/ComponentListener.java84
-rw-r--r--libjava/classpath/java/awt/event/ContainerAdapter.java79
-rw-r--r--libjava/classpath/java/awt/event/ContainerEvent.java135
-rw-r--r--libjava/classpath/java/awt/event/ContainerListener.java70
-rw-r--r--libjava/classpath/java/awt/event/FocusAdapter.java79
-rw-r--r--libjava/classpath/java/awt/event/FocusEvent.java181
-rw-r--r--libjava/classpath/java/awt/event/FocusListener.java69
-rw-r--r--libjava/classpath/java/awt/event/HierarchyBoundsAdapter.java78
-rw-r--r--libjava/classpath/java/awt/event/HierarchyBoundsListener.java70
-rw-r--r--libjava/classpath/java/awt/event/HierarchyEvent.java253
-rw-r--r--libjava/classpath/java/awt/event/HierarchyListener.java62
-rw-r--r--libjava/classpath/java/awt/event/InputEvent.java381
-rw-r--r--libjava/classpath/java/awt/event/InputMethodEvent.java303
-rw-r--r--libjava/classpath/java/awt/event/InputMethodListener.java70
-rw-r--r--libjava/classpath/java/awt/event/InvocationEvent.java237
-rw-r--r--libjava/classpath/java/awt/event/ItemEvent.java155
-rw-r--r--libjava/classpath/java/awt/event/ItemListener.java62
-rw-r--r--libjava/classpath/java/awt/event/KeyAdapter.java88
-rw-r--r--libjava/classpath/java/awt/event/KeyEvent.java1740
-rw-r--r--libjava/classpath/java/awt/event/KeyListener.java77
-rw-r--r--libjava/classpath/java/awt/event/MouseAdapter.java106
-rw-r--r--libjava/classpath/java/awt/event/MouseEvent.java432
-rw-r--r--libjava/classpath/java/awt/event/MouseListener.java94
-rw-r--r--libjava/classpath/java/awt/event/MouseMotionAdapter.java79
-rw-r--r--libjava/classpath/java/awt/event/MouseMotionListener.java72
-rw-r--r--libjava/classpath/java/awt/event/MouseWheelEvent.java232
-rw-r--r--libjava/classpath/java/awt/event/MouseWheelListener.java60
-rw-r--r--libjava/classpath/java/awt/event/PaintEvent.java127
-rw-r--r--libjava/classpath/java/awt/event/TextEvent.java93
-rw-r--r--libjava/classpath/java/awt/event/TextListener.java60
-rw-r--r--libjava/classpath/java/awt/event/WindowAdapter.java156
-rw-r--r--libjava/classpath/java/awt/event/WindowEvent.java312
-rw-r--r--libjava/classpath/java/awt/event/WindowFocusListener.java68
-rw-r--r--libjava/classpath/java/awt/event/WindowListener.java109
-rw-r--r--libjava/classpath/java/awt/event/WindowStateListener.java62
-rw-r--r--libjava/classpath/java/awt/event/package.html46
-rw-r--r--libjava/classpath/java/awt/font/FontRenderContext.java126
-rw-r--r--libjava/classpath/java/awt/font/GlyphJustificationInfo.java77
-rw-r--r--libjava/classpath/java/awt/font/GlyphMetrics.java134
-rw-r--r--libjava/classpath/java/awt/font/GlyphVector.java145
-rw-r--r--libjava/classpath/java/awt/font/GraphicAttribute.java84
-rw-r--r--libjava/classpath/java/awt/font/ImageGraphicAttribute.java109
-rw-r--r--libjava/classpath/java/awt/font/LineBreakMeasurer.java113
-rw-r--r--libjava/classpath/java/awt/font/LineMetrics.java67
-rw-r--r--libjava/classpath/java/awt/font/MultipleMaster.java61
-rw-r--r--libjava/classpath/java/awt/font/NumericShaper.java137
-rw-r--r--libjava/classpath/java/awt/font/OpenType.java111
-rw-r--r--libjava/classpath/java/awt/font/ShapeGraphicAttribute.java105
-rw-r--r--libjava/classpath/java/awt/font/TextAttribute.java309
-rw-r--r--libjava/classpath/java/awt/font/TextHitInfo.java125
-rw-r--r--libjava/classpath/java/awt/font/TextLayout.java332
-rw-r--r--libjava/classpath/java/awt/font/TextMeasurer.java97
-rw-r--r--libjava/classpath/java/awt/font/TransformAttribute.java100
-rw-r--r--libjava/classpath/java/awt/font/package.html46
-rw-r--r--libjava/classpath/java/awt/geom/AffineTransform.java1487
-rw-r--r--libjava/classpath/java/awt/geom/Arc2D.java1399
-rw-r--r--libjava/classpath/java/awt/geom/Area.java3312
-rw-r--r--libjava/classpath/java/awt/geom/CubicCurve2D.java1724
-rw-r--r--libjava/classpath/java/awt/geom/Dimension2D.java118
-rw-r--r--libjava/classpath/java/awt/geom/Ellipse2D.java413
-rw-r--r--libjava/classpath/java/awt/geom/FlatteningPathIterator.java579
-rw-r--r--libjava/classpath/java/awt/geom/GeneralPath.java958
-rw-r--r--libjava/classpath/java/awt/geom/IllegalPathStateException.java71
-rw-r--r--libjava/classpath/java/awt/geom/Line2D.java1182
-rw-r--r--libjava/classpath/java/awt/geom/NoninvertibleTransformException.java65
-rw-r--r--libjava/classpath/java/awt/geom/PathIterator.java189
-rw-r--r--libjava/classpath/java/awt/geom/Point2D.java396
-rw-r--r--libjava/classpath/java/awt/geom/QuadCurve2D.java1467
-rw-r--r--libjava/classpath/java/awt/geom/Rectangle2D.java992
-rw-r--r--libjava/classpath/java/awt/geom/RectangularShape.java385
-rw-r--r--libjava/classpath/java/awt/geom/RoundRectangle2D.java533
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/Area-1.pngbin0 -> 21447 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-1.pngbin0 -> 6280 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-2.pngbin0 -> 5791 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-3.pngbin0 -> 13168 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-4.pngbin0 -> 7839 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-5.pngbin0 -> 5112 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/Ellipse-1.pngbin0 -> 19426 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/FlatteningPathIterator-1.html481
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/GeneralPath-1.pngbin0 -> 13111 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-1.pngbin0 -> 6363 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-2.pngbin0 -> 5872 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-3.pngbin0 -> 12334 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-4.pngbin0 -> 7797 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-5.pngbin0 -> 4757 bytes
-rw-r--r--libjava/classpath/java/awt/geom/package.html46
-rw-r--r--libjava/classpath/java/awt/im/InputContext.java434
-rw-r--r--libjava/classpath/java/awt/im/InputMethodHighlight.java185
-rw-r--r--libjava/classpath/java/awt/im/InputMethodRequests.java153
-rw-r--r--libjava/classpath/java/awt/im/InputSubset.java129
-rw-r--r--libjava/classpath/java/awt/im/package.html46
-rw-r--r--libjava/classpath/java/awt/im/spi/InputMethod.java240
-rw-r--r--libjava/classpath/java/awt/im/spi/InputMethodContext.java123
-rw-r--r--libjava/classpath/java/awt/im/spi/InputMethodDescriptor.java113
-rw-r--r--libjava/classpath/java/awt/im/spi/package.html46
-rw-r--r--libjava/classpath/java/awt/image/AffineTransformOp.java375
-rw-r--r--libjava/classpath/java/awt/image/AreaAveragingScaleFilter.java127
-rw-r--r--libjava/classpath/java/awt/image/BandCombineOp.java168
-rw-r--r--libjava/classpath/java/awt/image/BandedSampleModel.java548
-rw-r--r--libjava/classpath/java/awt/image/BufferStrategy.java124
-rw-r--r--libjava/classpath/java/awt/image/BufferedImage.java693
-rw-r--r--libjava/classpath/java/awt/image/BufferedImageFilter.java110
-rw-r--r--libjava/classpath/java/awt/image/BufferedImageOp.java55
-rw-r--r--libjava/classpath/java/awt/image/ByteLookupTable.java166
-rw-r--r--libjava/classpath/java/awt/image/ColorConvertOp.java319
-rw-r--r--libjava/classpath/java/awt/image/ColorModel.java758
-rw-r--r--libjava/classpath/java/awt/image/ComponentColorModel.java391
-rw-r--r--libjava/classpath/java/awt/image/ComponentSampleModel.java544
-rw-r--r--libjava/classpath/java/awt/image/ConvolveOp.java337
-rw-r--r--libjava/classpath/java/awt/image/CropImageFilter.java180
-rw-r--r--libjava/classpath/java/awt/image/DataBuffer.java436
-rw-r--r--libjava/classpath/java/awt/image/DataBufferByte.java245
-rw-r--r--libjava/classpath/java/awt/image/DataBufferDouble.java288
-rw-r--r--libjava/classpath/java/awt/image/DataBufferFloat.java286
-rw-r--r--libjava/classpath/java/awt/image/DataBufferInt.java244
-rw-r--r--libjava/classpath/java/awt/image/DataBufferShort.java245
-rw-r--r--libjava/classpath/java/awt/image/DataBufferUShort.java246
-rw-r--r--libjava/classpath/java/awt/image/DirectColorModel.java420
-rw-r--r--libjava/classpath/java/awt/image/FilteredImageSource.java125
-rw-r--r--libjava/classpath/java/awt/image/ImageConsumer.java216
-rw-r--r--libjava/classpath/java/awt/image/ImageFilter.java221
-rw-r--r--libjava/classpath/java/awt/image/ImageObserver.java129
-rw-r--r--libjava/classpath/java/awt/image/ImageProducer.java85
-rw-r--r--libjava/classpath/java/awt/image/ImagingOpException.java66
-rw-r--r--libjava/classpath/java/awt/image/IndexColorModel.java697
-rw-r--r--libjava/classpath/java/awt/image/Kernel.java143
-rw-r--r--libjava/classpath/java/awt/image/LookupOp.java252
-rw-r--r--libjava/classpath/java/awt/image/LookupTable.java109
-rw-r--r--libjava/classpath/java/awt/image/MemoryImageSource.java373
-rw-r--r--libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java388
-rw-r--r--libjava/classpath/java/awt/image/PackedColorModel.java192
-rw-r--r--libjava/classpath/java/awt/image/PixelGrabber.java618
-rw-r--r--libjava/classpath/java/awt/image/PixelInterleavedSampleModel.java98
-rw-r--r--libjava/classpath/java/awt/image/RGBImageFilter.java267
-rw-r--r--libjava/classpath/java/awt/image/Raster.java546
-rw-r--r--libjava/classpath/java/awt/image/RasterFormatException.java65
-rw-r--r--libjava/classpath/java/awt/image/RasterOp.java57
-rw-r--r--libjava/classpath/java/awt/image/RenderedImage.java70
-rw-r--r--libjava/classpath/java/awt/image/ReplicateScaleFilter.java244
-rw-r--r--libjava/classpath/java/awt/image/RescaleOp.java218
-rw-r--r--libjava/classpath/java/awt/image/SampleModel.java477
-rw-r--r--libjava/classpath/java/awt/image/ShortLookupTable.java162
-rw-r--r--libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java449
-rw-r--r--libjava/classpath/java/awt/image/TileObserver.java47
-rw-r--r--libjava/classpath/java/awt/image/VolatileImage.java253
-rw-r--r--libjava/classpath/java/awt/image/WritableRaster.java265
-rw-r--r--libjava/classpath/java/awt/image/WritableRenderedImage.java56
-rw-r--r--libjava/classpath/java/awt/image/package.html46
-rw-r--r--libjava/classpath/java/awt/image/renderable/ContextualRenderedImageFactory.java56
-rw-r--r--libjava/classpath/java/awt/image/renderable/ParameterBlock.java308
-rw-r--r--libjava/classpath/java/awt/image/renderable/RenderContext.java141
-rw-r--r--libjava/classpath/java/awt/image/renderable/RenderableImage.java62
-rw-r--r--libjava/classpath/java/awt/image/renderable/RenderableImageOp.java157
-rw-r--r--libjava/classpath/java/awt/image/renderable/RenderableImageProducer.java79
-rw-r--r--libjava/classpath/java/awt/image/renderable/RenderedImageFactory.java47
-rw-r--r--libjava/classpath/java/awt/image/renderable/package.html46
-rw-r--r--libjava/classpath/java/awt/package.html46
-rw-r--r--libjava/classpath/java/awt/peer/ButtonPeer.java46
-rw-r--r--libjava/classpath/java/awt/peer/CanvasPeer.java45
-rw-r--r--libjava/classpath/java/awt/peer/CheckboxMenuItemPeer.java46
-rw-r--r--libjava/classpath/java/awt/peer/CheckboxPeer.java52
-rw-r--r--libjava/classpath/java/awt/peer/ChoicePeer.java54
-rw-r--r--libjava/classpath/java/awt/peer/ComponentPeer.java187
-rw-r--r--libjava/classpath/java/awt/peer/ContainerPeer.java59
-rw-r--r--libjava/classpath/java/awt/peer/DialogPeer.java48
-rw-r--r--libjava/classpath/java/awt/peer/FileDialogPeer.java52
-rw-r--r--libjava/classpath/java/awt/peer/FontPeer.java45
-rw-r--r--libjava/classpath/java/awt/peer/FramePeer.java55
-rw-r--r--libjava/classpath/java/awt/peer/LabelPeer.java46
-rw-r--r--libjava/classpath/java/awt/peer/LightweightPeer.java45
-rw-r--r--libjava/classpath/java/awt/peer/ListPeer.java61
-rw-r--r--libjava/classpath/java/awt/peer/MenuBarPeer.java48
-rw-r--r--libjava/classpath/java/awt/peer/MenuComponentPeer.java45
-rw-r--r--libjava/classpath/java/awt/peer/MenuItemPeer.java48
-rw-r--r--libjava/classpath/java/awt/peer/MenuPeer.java48
-rw-r--r--libjava/classpath/java/awt/peer/PanelPeer.java45
-rw-r--r--libjava/classpath/java/awt/peer/PopupMenuPeer.java53
-rw-r--r--libjava/classpath/java/awt/peer/RobotPeer.java54
-rw-r--r--libjava/classpath/java/awt/peer/ScrollPanePeer.java52
-rw-r--r--libjava/classpath/java/awt/peer/ScrollbarPeer.java47
-rw-r--r--libjava/classpath/java/awt/peer/TextAreaPeer.java53
-rw-r--r--libjava/classpath/java/awt/peer/TextComponentPeer.java57
-rw-r--r--libjava/classpath/java/awt/peer/TextFieldPeer.java52
-rw-r--r--libjava/classpath/java/awt/peer/WindowPeer.java46
-rw-r--r--libjava/classpath/java/awt/peer/package.html46
-rw-r--r--libjava/classpath/java/awt/print/Book.java159
-rw-r--r--libjava/classpath/java/awt/print/PageFormat.java292
-rw-r--r--libjava/classpath/java/awt/print/Pageable.java113
-rw-r--r--libjava/classpath/java/awt/print/Paper.java236
-rw-r--r--libjava/classpath/java/awt/print/Printable.java80
-rw-r--r--libjava/classpath/java/awt/print/PrinterAbortException.java71
-rw-r--r--libjava/classpath/java/awt/print/PrinterException.java71
-rw-r--r--libjava/classpath/java/awt/print/PrinterGraphics.java61
-rw-r--r--libjava/classpath/java/awt/print/PrinterIOException.java98
-rw-r--r--libjava/classpath/java/awt/print/PrinterJob.java299
-rw-r--r--libjava/classpath/java/awt/print/package.html46
352 files changed, 98340 insertions, 0 deletions
diff --git a/libjava/classpath/java/awt/AWTError.java b/libjava/classpath/java/awt/AWTError.java
new file mode 100644
index 0000000..80356ee
--- /dev/null
+++ b/libjava/classpath/java/awt/AWTError.java
@@ -0,0 +1,64 @@
+/* AWTError.java -- A serious AWT error occurred.
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This error is thrown when a critical Abstract Window Toolkit (AWT) error
+ * occurs.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @status updated to 1.4
+ */
+public class AWTError extends Error
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -1819846354050686206L;
+
+ /**
+ * Create a new instance with the specified descriptive error message.
+ *
+ * @param message the descriptive error message
+ */
+ public AWTError(String message)
+ {
+ super(message);
+ }
+} // class AWTError
diff --git a/libjava/classpath/java/awt/AWTEvent.java b/libjava/classpath/java/awt/AWTEvent.java
new file mode 100644
index 0000000..ad9533f
--- /dev/null
+++ b/libjava/classpath/java/awt/AWTEvent.java
@@ -0,0 +1,278 @@
+
+/* AWTEvent.java -- the root event in AWT
+ Copyright (C) 1999, 2000, 2002, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.util.EventObject;
+
+/**
+ * AWTEvent is the root event class for all AWT events in the JDK 1.1 event
+ * model. It supersedes the Event class from JDK 1.0. Subclasses outside of
+ * the java.awt package should have IDs greater than RESERVED_ID_MAX.
+ *
+ * <p>Event masks defined here are used by components in
+ * <code>enableEvents</code> to select event types not selected by registered
+ * listeners. Event masks are appropriately set when registering on
+ * components.
+ *
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class AWTEvent extends EventObject
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -1825314779160409405L;
+
+ /**
+ * The ID of the event.
+ *
+ * @see #getID()
+ * @see #AWTEvent(Object, int)
+ * @serial the identifier number of this event
+ */
+ protected int id;
+
+ /**
+ * Indicates if the event has been consumed. False mean it is passed to
+ * the peer, true means it has already been processed. Semantic events
+ * generated by low-level events always have the value true.
+ *
+ * @see #consume()
+ * @see #isConsumed()
+ * @serial whether the event has been consumed
+ */
+ protected boolean consumed;
+
+ /**
+ * Who knows? It's in the serial version.
+ *
+ * @serial No idea what this is for.
+ */
+ byte[] bdata;
+
+ /** Mask for selecting component events. */
+ public static final long COMPONENT_EVENT_MASK = 0x00001;
+
+ /** Mask for selecting container events. */
+ public static final long CONTAINER_EVENT_MASK = 0x00002;
+
+ /** Mask for selecting component focus events. */
+ public static final long FOCUS_EVENT_MASK = 0x00004;
+
+ /** Mask for selecting keyboard events. */
+ public static final long KEY_EVENT_MASK = 0x00008;
+
+ /** Mask for mouse button events. */
+ public static final long MOUSE_EVENT_MASK = 0x00010;
+
+ /** Mask for mouse motion events. */
+ public static final long MOUSE_MOTION_EVENT_MASK = 0x00020;
+
+ /** Mask for window events. */
+ public static final long WINDOW_EVENT_MASK = 0x00040;
+
+ /** Mask for action events. */
+ public static final long ACTION_EVENT_MASK = 0x00080;
+
+ /** Mask for adjustment events. */
+ public static final long ADJUSTMENT_EVENT_MASK = 0x00100;
+
+ /** Mask for item events. */
+ public static final long ITEM_EVENT_MASK = 0x00200;
+
+ /** Mask for text events. */
+ public static final long TEXT_EVENT_MASK = 0x00400;
+
+ /**
+ * Mask for input method events.
+ * @since 1.3
+ */
+ public static final long INPUT_METHOD_EVENT_MASK = 0x00800;
+
+ /**
+ * Mask if input methods are enabled. Package visible only.
+ */
+ static final long INPUT_ENABLED_EVENT_MASK = 0x01000;
+
+ /**
+ * Mask for paint events.
+ * @since 1.3
+ */
+ public static final long PAINT_EVENT_MASK = 0x02000;
+
+ /**
+ * Mask for invocation events.
+ * @since 1.3
+ */
+ public static final long INVOCATION_EVENT_MASK = 0x04000;
+
+ /**
+ * Mask for hierarchy events.
+ * @since 1.3
+ */
+ public static final long HIERARCHY_EVENT_MASK = 0x08000;
+
+ /**
+ * Mask for hierarchy bounds events.
+ * @since 1.3
+ */
+ public static final long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000;
+
+ /**
+ * Mask for mouse wheel events.
+ * @since 1.4
+ */
+ public static final long MOUSE_WHEEL_EVENT_MASK = 0x20000;
+
+ /**
+ * Mask for window state events.
+ * @since 1.4
+ */
+ public static final long WINDOW_STATE_EVENT_MASK = 0x40000;
+
+ /**
+ * Mask for window focus events.
+ * @since 1.4
+ */
+ public static final long WINDOW_FOCUS_EVENT_MASK = 0x80000;
+
+ /**
+ * This is the highest number for event ids that are reserved for use by
+ * the AWT system itself. Subclasses outside of java.awt should use higher
+ * ids.
+ */
+ public static final int RESERVED_ID_MAX = 1999;
+
+
+ /**
+ * Initializes a new AWTEvent from the old Java 1.0 event object.
+ *
+ * @param event the old-style event
+ * @throws NullPointerException if event is null
+ */
+ public AWTEvent(Event event)
+ {
+ this(event.target, event.id);
+ consumed = event.consumed;
+ }
+
+ /**
+ * Create an event on the specified source object and id.
+ *
+ * @param source the object that caused the event
+ * @param id the event id
+ * @throws IllegalArgumentException if source is null
+ */
+ public AWTEvent(Object source, int id)
+ {
+ super(source);
+ this.id = id;
+ }
+
+ /**
+ * Retarget the event, such as converting a heavyweight component to a
+ * lightweight child of the original. This is not for general use, but
+ * is for event targeting systems like KeyboardFocusManager.
+ *
+ * @param source the new source
+ */
+ public void setSource(Object source)
+ {
+ this.source = source;
+ }
+
+ /**
+ * Returns the event type id.
+ *
+ * @return the id number of this event
+ */
+ public int getID()
+ {
+ return id;
+ }
+
+ /**
+ * Create a string that represents this event in the format
+ * <code>classname[eventstring] on sourcecomponentname</code>.
+ *
+ * @return a string representing this event
+ */
+ public String toString ()
+ {
+ String string = getClass ().getName () + "[" + paramString () + "] on "
+ + source;
+
+ return string;
+ }
+
+ /**
+ * Returns a string representation of the state of this event. It may be
+ * empty, but must not be null; it is implementation defined.
+ *
+ * @return a string representation of this event
+ */
+ public String paramString()
+ {
+ return "";
+ }
+
+ /**
+ * Consumes this event so that it will not be processed in the default
+ * manner.
+ */
+ protected void consume()
+ {
+ consumed = true;
+ }
+
+ /**
+ * Tests whether not not this event has been consumed. A consumed event
+ * is not processed in the default manner.
+ *
+ * @return true if this event has been consumed
+ */
+ protected boolean isConsumed()
+ {
+ return consumed;
+ }
+} // class AWTEvent
diff --git a/libjava/classpath/java/awt/AWTEventMulticaster.java b/libjava/classpath/java/awt/AWTEventMulticaster.java
new file mode 100644
index 0000000..f7b9163
--- /dev/null
+++ b/libjava/classpath/java/awt/AWTEventMulticaster.java
@@ -0,0 +1,1209 @@
+/* AWTEventMulticaster.java -- allows multicast chaining of listeners
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.ContainerEvent;
+import java.awt.event.ContainerListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.HierarchyBoundsListener;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InputMethodListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.event.TextEvent;
+import java.awt.event.TextListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowFocusListener;
+import java.awt.event.WindowListener;
+import java.awt.event.WindowStateListener;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.EventListener;
+
+/**
+ * This class is used to implement a chain of event handlers. Dispatching
+ * using this class is thread safe. Here is a quick example of how to
+ * add and delete listeners using this class. For this example, we will
+ * assume are firing <code>AdjustmentEvent</code>'s. However, this
+ * same approach is useful for all events in the <code>java.awt.event</code>
+ * package, and more if this class is subclassed.
+ *
+ * <p><code>
+ * AdjustmentListener al;
+ * public void addAdjustmentListener(AdjustmentListener listener)
+ * {
+ * al = AWTEventMulticaster.add(al, listener);
+ * }
+ * public void removeAdjustmentListener(AdjustmentListener listener)
+ * {
+ * al = AWTEventMulticaster.remove(al, listener);
+ * }
+ * </code>
+ *
+ * <p>When it come time to process an event, simply call <code>al</code>,
+ * assuming it is not <code>null</code>, and all listeners in the chain will
+ * be fired.
+ *
+ * <p>The first time <code>add</code> is called it is passed
+ * <code>null</code> and <code>listener</code> as its arguments. This
+ * starts building the chain. This class returns <code>listener</code>
+ * which becomes the new <code>al</code>. The next time, <code>add</code>
+ * is called with <code>al</code> and <code>listener</code> and the
+ * new listener is then chained to the old.
+ *
+ * @author Bryce McKinlay
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class AWTEventMulticaster
+ implements ComponentListener, ContainerListener, FocusListener, KeyListener,
+ MouseListener, MouseMotionListener, WindowListener,
+ WindowFocusListener, WindowStateListener, ActionListener,
+ ItemListener, AdjustmentListener, TextListener,
+ InputMethodListener, HierarchyListener, HierarchyBoundsListener,
+ MouseWheelListener
+{
+ /**
+ * A variable in the event chain.
+ */
+ protected final EventListener a;
+
+ /**
+ * A variable in the event chain.
+ */
+ protected final EventListener b;
+
+ /**
+ * Initializes a new instance of <code>AWTEventMulticaster</code> with
+ * the specified event listener parameters. The parameters should not be
+ * null, although it is not required to enforce this with a
+ * NullPointerException.
+ *
+ * @param a the "a" listener object
+ * @param b the "b" listener object
+ */
+ protected AWTEventMulticaster(EventListener a, EventListener b)
+ {
+ this.a = a;
+ this.b = b;
+ }
+
+ /**
+ * Removes one instance of the specified listener from this multicaster
+ * chain. This descends recursively if either child is a multicaster, and
+ * returns a multicaster chain with the old listener removed.
+ *
+ * @param oldl the object to remove from this multicaster
+ * @return the resulting multicaster with the specified listener removed
+ */
+ protected EventListener remove(EventListener oldl)
+ {
+ // If oldl is an immediate child, return the other child.
+ if (a == oldl)
+ return b;
+ if (b == oldl)
+ return a;
+ // If a and/or b are Multicaster's, search them recursively.
+ if (a instanceof AWTEventMulticaster)
+ {
+ EventListener newa = ((AWTEventMulticaster) a).remove(oldl);
+ if (newa != a)
+ return new AWTEventMulticaster(newa, b);
+ }
+ if (b instanceof AWTEventMulticaster)
+ {
+ EventListener newb = ((AWTEventMulticaster) b).remove(oldl);
+ if (newb != b)
+ return new AWTEventMulticaster(a, newb);
+ }
+ // oldl was not found.
+ return this;
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void componentResized(ComponentEvent e)
+ {
+ ((ComponentListener) a).componentResized(e);
+ ((ComponentListener) b).componentResized(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void componentMoved(ComponentEvent e)
+ {
+ ((ComponentListener) a).componentMoved(e);
+ ((ComponentListener) b).componentMoved(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void componentShown(ComponentEvent e)
+ {
+ ((ComponentListener) a).componentShown(e);
+ ((ComponentListener) b).componentShown(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void componentHidden(ComponentEvent e)
+ {
+ ((ComponentListener) a).componentHidden(e);
+ ((ComponentListener) b).componentHidden(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void componentAdded(ContainerEvent e)
+ {
+ ((ContainerListener) a).componentAdded(e);
+ ((ContainerListener) b).componentAdded(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void componentRemoved(ContainerEvent e)
+ {
+ ((ContainerListener) a).componentRemoved(e);
+ ((ContainerListener) b).componentRemoved(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void focusGained(FocusEvent e)
+ {
+ ((FocusListener) a).focusGained(e);
+ ((FocusListener) b).focusGained(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void focusLost(FocusEvent e)
+ {
+ ((FocusListener) a).focusLost(e);
+ ((FocusListener) b).focusLost(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void keyTyped(KeyEvent e)
+ {
+ ((KeyListener) a).keyTyped(e);
+ ((KeyListener) b).keyTyped(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void keyPressed(KeyEvent e)
+ {
+ ((KeyListener) a).keyPressed(e);
+ ((KeyListener) b).keyPressed(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void keyReleased(KeyEvent e)
+ {
+ ((KeyListener) a).keyReleased(e);
+ ((KeyListener) b).keyReleased(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void mouseClicked(MouseEvent e)
+ {
+ ((MouseListener) a).mouseClicked(e);
+ ((MouseListener) b).mouseClicked(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void mousePressed(MouseEvent e)
+ {
+ ((MouseListener) a).mousePressed(e);
+ ((MouseListener) b).mousePressed(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void mouseReleased(MouseEvent e)
+ {
+ ((MouseListener) a).mouseReleased(e);
+ ((MouseListener) b).mouseReleased(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void mouseEntered(MouseEvent e)
+ {
+ ((MouseListener) a).mouseEntered(e);
+ ((MouseListener) b).mouseEntered(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void mouseExited(MouseEvent e)
+ {
+ ((MouseListener) a).mouseExited(e);
+ ((MouseListener) b).mouseExited(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void mouseDragged(MouseEvent e)
+ {
+ ((MouseMotionListener) a).mouseDragged(e);
+ ((MouseMotionListener) b).mouseDragged(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void mouseMoved(MouseEvent e)
+ {
+ ((MouseMotionListener) a).mouseMoved(e);
+ ((MouseMotionListener) b).mouseMoved(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void windowOpened(WindowEvent e)
+ {
+ ((WindowListener) a).windowOpened(e);
+ ((WindowListener) b).windowOpened(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void windowClosing(WindowEvent e)
+ {
+ ((WindowListener) a).windowClosing(e);
+ ((WindowListener) b).windowClosing(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void windowClosed(WindowEvent e)
+ {
+ ((WindowListener) a).windowClosed(e);
+ ((WindowListener) b).windowClosed(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void windowIconified(WindowEvent e)
+ {
+ ((WindowListener) a).windowIconified(e);
+ ((WindowListener) b).windowIconified(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void windowDeiconified(WindowEvent e)
+ {
+ ((WindowListener) a).windowDeiconified(e);
+ ((WindowListener) b).windowDeiconified(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void windowActivated(WindowEvent e)
+ {
+ ((WindowListener) a).windowActivated(e);
+ ((WindowListener) b).windowActivated(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void windowDeactivated(WindowEvent e)
+ {
+ ((WindowListener) a).windowDeactivated(e);
+ ((WindowListener) b).windowDeactivated(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.4
+ */
+ public void windowStateChanged(WindowEvent e)
+ {
+ ((WindowStateListener) a).windowStateChanged(e);
+ ((WindowStateListener) b).windowStateChanged(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.4
+ */
+ public void windowGainedFocus(WindowEvent e)
+ {
+ ((WindowFocusListener) a).windowGainedFocus(e);
+ ((WindowFocusListener) b).windowGainedFocus(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.4
+ */
+ public void windowLostFocus(WindowEvent e)
+ {
+ ((WindowFocusListener) a).windowLostFocus(e);
+ ((WindowFocusListener) b).windowLostFocus(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ ((ActionListener) a).actionPerformed(e);
+ ((ActionListener) b).actionPerformed(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void itemStateChanged(ItemEvent e)
+ {
+ ((ItemListener) a).itemStateChanged(e);
+ ((ItemListener) b).itemStateChanged(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void adjustmentValueChanged(AdjustmentEvent e)
+ {
+ ((AdjustmentListener) a).adjustmentValueChanged(e);
+ ((AdjustmentListener) b).adjustmentValueChanged(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ */
+ public void textValueChanged(TextEvent e)
+ {
+ ((TextListener) a).textValueChanged(e);
+ ((TextListener) b).textValueChanged(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.2
+ */
+ public void inputMethodTextChanged(InputMethodEvent e)
+ {
+ ((InputMethodListener) a).inputMethodTextChanged(e);
+ ((InputMethodListener) b).inputMethodTextChanged(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.2
+ */
+ public void caretPositionChanged(InputMethodEvent e)
+ {
+ ((InputMethodListener) a).caretPositionChanged(e);
+ ((InputMethodListener) b).caretPositionChanged(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.3
+ */
+ public void hierarchyChanged(HierarchyEvent e)
+ {
+ ((HierarchyListener) a).hierarchyChanged(e);
+ ((HierarchyListener) b).hierarchyChanged(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.3
+ */
+ public void ancestorMoved(HierarchyEvent e)
+ {
+ ((HierarchyBoundsListener) a).ancestorMoved(e);
+ ((HierarchyBoundsListener) b).ancestorMoved(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.3
+ */
+ public void ancestorResized(HierarchyEvent e)
+ {
+ ((HierarchyBoundsListener) a).ancestorResized(e);
+ ((HierarchyBoundsListener) b).ancestorResized(e);
+ }
+
+ /**
+ * Handles this event by dispatching it to the "a" and "b" listener
+ * instances.
+ *
+ * @param e the event to handle
+ * @since 1.4
+ */
+ public void mouseWheelMoved(MouseWheelEvent e)
+ {
+ ((MouseWheelListener) a).mouseWheelMoved(e);
+ ((MouseWheelListener) b).mouseWheelMoved(e);
+ }
+
+ /**
+ * Chain <code>ComponentListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static ComponentListener add(ComponentListener a, ComponentListener b)
+ {
+ return (ComponentListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>ContainerListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static ContainerListener add(ContainerListener a, ContainerListener b)
+ {
+ return (ContainerListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>FocusListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static FocusListener add(FocusListener a, FocusListener b)
+ {
+ return (FocusListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>KeyListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static KeyListener add(KeyListener a, KeyListener b)
+ {
+ return (KeyListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>MouseListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static MouseListener add(MouseListener a, MouseListener b)
+ {
+ return (MouseListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>MouseMotionListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static MouseMotionListener add(MouseMotionListener a,
+ MouseMotionListener b)
+ {
+ return (MouseMotionListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>WindowListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static WindowListener add(WindowListener a, WindowListener b)
+ {
+ return (WindowListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>WindowStateListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ * @since 1.4
+ */
+ public static WindowStateListener add(WindowStateListener a,
+ WindowStateListener b)
+ {
+ return (WindowStateListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>WindowFocusListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ * @since 1.4
+ */
+ public static WindowFocusListener add(WindowFocusListener a,
+ WindowFocusListener b)
+ {
+ return (WindowFocusListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>ActionListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static ActionListener add(ActionListener a, ActionListener b)
+ {
+ return (ActionListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>ItemListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static ItemListener add(ItemListener a, ItemListener b)
+ {
+ return (ItemListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>AdjustmentListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static AdjustmentListener add(AdjustmentListener a,
+ AdjustmentListener b)
+ {
+ return (AdjustmentListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>AdjustmentListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ public static TextListener add(TextListener a, TextListener b)
+ {
+ return (TextListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>InputMethodListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ * @since 1.2
+ */
+ public static InputMethodListener add(InputMethodListener a,
+ InputMethodListener b)
+ {
+ return (InputMethodListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>HierarchyListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ * @since 1.3
+ */
+ public static HierarchyListener add(HierarchyListener a, HierarchyListener b)
+ {
+ return (HierarchyListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>HierarchyBoundsListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ * @since 1.3
+ */
+ public static HierarchyBoundsListener add(HierarchyBoundsListener a,
+ HierarchyBoundsListener b)
+ {
+ return (HierarchyBoundsListener) addInternal(a, b);
+ }
+
+ /**
+ * Chain <code>MouseWheelListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ * @since 1.4
+ */
+ public static MouseWheelListener add(MouseWheelListener a,
+ MouseWheelListener b)
+ {
+ return (MouseWheelListener) addInternal(a, b);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static ComponentListener remove(ComponentListener l,
+ ComponentListener oldl)
+ {
+ return (ComponentListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static ContainerListener remove(ContainerListener l,
+ ContainerListener oldl)
+ {
+ return (ContainerListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static FocusListener remove(FocusListener l, FocusListener oldl)
+ {
+ return (FocusListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static KeyListener remove(KeyListener l, KeyListener oldl)
+ {
+ return (KeyListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static MouseListener remove(MouseListener l, MouseListener oldl)
+ {
+ return (MouseListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static MouseMotionListener remove(MouseMotionListener l,
+ MouseMotionListener oldl)
+ {
+ return (MouseMotionListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static WindowListener remove(WindowListener l, WindowListener oldl)
+ {
+ return (WindowListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ * @since 1.4
+ */
+ public static WindowStateListener remove(WindowStateListener l,
+ WindowStateListener oldl)
+ {
+ return (WindowStateListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ * @since 1.4
+ */
+ public static WindowFocusListener remove(WindowFocusListener l,
+ WindowFocusListener oldl)
+ {
+ return (WindowFocusListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static ActionListener remove(ActionListener l, ActionListener oldl)
+ {
+ return (ActionListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static ItemListener remove(ItemListener l, ItemListener oldl)
+ {
+ return (ItemListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static AdjustmentListener remove(AdjustmentListener l,
+ AdjustmentListener oldl)
+ {
+ return (AdjustmentListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ public static TextListener remove(TextListener l, TextListener oldl)
+ {
+ return (TextListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ * @since 1.2
+ */
+ public static InputMethodListener remove(InputMethodListener l,
+ InputMethodListener oldl)
+ {
+ return (InputMethodListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ * @since 1.3
+ */
+ public static HierarchyListener remove(HierarchyListener l,
+ HierarchyListener oldl)
+ {
+ return (HierarchyListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ * @since 1.3
+ */
+ public static HierarchyBoundsListener remove(HierarchyBoundsListener l,
+ HierarchyBoundsListener oldl)
+ {
+ return (HierarchyBoundsListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ * @since 1.4
+ */
+ public static MouseWheelListener remove(MouseWheelListener l,
+ MouseWheelListener oldl)
+ {
+ return (MouseWheelListener) removeInternal(l, oldl);
+ }
+
+ /**
+ * Chain <code>EventListener</code> a and b.
+ *
+ * @param a the "a" listener, may be null
+ * @param b the "b" listener, may be null
+ * @return latest entry in the chain
+ */
+ protected static EventListener addInternal(EventListener a, EventListener b)
+ {
+ if (a == null)
+ return b;
+ if (b == null)
+ return a;
+ return new AWTEventMulticaster(a, b);
+ }
+
+ /**
+ * Removes the listener <code>oldl</code> from the listener <code>l</code>.
+ *
+ * @param l the listener chain to reduce
+ * @param oldl the listener to remove
+ * @return the resulting listener chain
+ */
+ protected static EventListener removeInternal(EventListener l,
+ EventListener oldl)
+ {
+ if (l == oldl)
+ return null;
+ if (l instanceof AWTEventMulticaster)
+ return ((AWTEventMulticaster) l).remove(oldl);
+ return l;
+ }
+
+ /**
+ * Saves all Serializable listeners to a serialization stream.
+ *
+ * @param s the stream to save to
+ * @param k a prefix stream put before each serializable listener
+ * @throws IOException if serialization fails
+ */
+ protected void saveInternal(ObjectOutputStream s, String k)
+ throws IOException
+ {
+ // This is not documented by Sun, but I think it is correct.
+ if (a instanceof AWTEventMulticaster)
+ ((AWTEventMulticaster) a).saveInternal(s, k);
+ else if (a instanceof Serializable)
+ {
+ s.writeObject(k);
+ s.writeObject(a);
+ }
+ if (b instanceof AWTEventMulticaster)
+ ((AWTEventMulticaster) b).saveInternal(s, k);
+ else if (b instanceof Serializable)
+ {
+ s.writeObject(k);
+ s.writeObject(b);
+ }
+ }
+
+ /**
+ * Saves a Serializable listener chain to a serialization stream.
+ *
+ * @param s the stream to save to
+ * @param k a prefix stream put before each serializable listener
+ * @param l the listener chain to save
+ * @throws IOException if serialization fails
+ */
+ protected static void save(ObjectOutputStream s, String k, EventListener l)
+ throws IOException
+ {
+ // This is not documented by Sun, but I think it is correct.
+ if (l instanceof AWTEventMulticaster)
+ ((AWTEventMulticaster) l).saveInternal(s, k);
+ else if (l instanceof Serializable)
+ {
+ s.writeObject(k);
+ s.writeObject(l);
+ }
+ }
+
+ /**
+ * Returns an array of all chained listeners of the specified type in the
+ * given chain. A null listener returns an empty array, and a listener
+ * which is not an AWTEventMulticaster returns an array of one element. If
+ * no listeners in the chain are of the specified type, an empty array is
+ * returned.
+ *
+ * @param l the listener chain to convert to an array
+ * @param type the type of listeners to collect
+ * @return an array of the listeners of that type in the chain
+ * @throws ClassCastException if type is not assignable from EventListener
+ * @throws NullPointerException if type is null
+ * @throws IllegalArgumentException if type is Void.TYPE
+ * @since 1.4
+ */
+ public static EventListener[] getListeners(EventListener l, Class type)
+ {
+ ArrayList list = new ArrayList();
+ if (l instanceof AWTEventMulticaster)
+ ((AWTEventMulticaster) l).getListeners(list, type);
+ else if (type.isInstance(l))
+ list.add(l);
+ EventListener[] r = (EventListener[]) Array.newInstance(type, list.size());
+ list.toArray(r);
+ return r;
+ }
+
+ /**
+ * Collects all instances of the given type in the chain into the list.
+ *
+ * @param l the list to collect into
+ * @param type the type of listeners to collect
+ * @throws NullPointerException if type is null
+ * @see #getListeners(EventListener, Class)
+ */
+ private void getListeners(ArrayList l, Class type)
+ {
+ if (a instanceof AWTEventMulticaster)
+ ((AWTEventMulticaster) a).getListeners(l, type);
+ else if (type.isInstance(a))
+ l.add(a);
+ if (b instanceof AWTEventMulticaster)
+ ((AWTEventMulticaster) b).getListeners(l, type);
+ else if (type.isInstance(b))
+ l.add(b);
+ }
+} // class AWTEventMulticaster
diff --git a/libjava/classpath/java/awt/AWTException.java b/libjava/classpath/java/awt/AWTException.java
new file mode 100644
index 0000000..2df3dd8
--- /dev/null
+++ b/libjava/classpath/java/awt/AWTException.java
@@ -0,0 +1,64 @@
+/* AWTException.java -- Generic AWT exception
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This is a generic exception that indicates an exception occurred in the
+ * Abstract Window Toolkit (AWT) system.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @status updated to 1.4
+ */
+public class AWTException extends Exception
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -1900414231151323879L;
+
+ /**
+ * Create a new instance with the specified detailed error message.
+ *
+ * @param message the detailed error message
+ */
+ public AWTException(String message)
+ {
+ super(message);
+ }
+} // class AWTException
diff --git a/libjava/classpath/java/awt/AWTKeyStroke.java b/libjava/classpath/java/awt/AWTKeyStroke.java
new file mode 100644
index 0000000..c10d53e
--- /dev/null
+++ b/libjava/classpath/java/awt/AWTKeyStroke.java
@@ -0,0 +1,660 @@
+/* AWTKeyStroke.java -- an immutable key stroke
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * This class mirrors KeyEvents, representing both low-level key presses and
+ * key releases, and high level key typed inputs. However, this class forms
+ * immutable strokes, and can be efficiently reused via the factory methods
+ * for creating them.
+ *
+ * <p>For backwards compatibility with Swing, this supports a way to build
+ * instances of a subclass, using reflection, provided the subclass has a
+ * no-arg constructor (of any accessibility).
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see #getAWTKeyStroke(char)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public class AWTKeyStroke implements Serializable
+{
+ /**
+ * Compatible with JDK 1.4+.
+ */
+ private static final long serialVersionUID = -6430539691155161871L;
+
+ /** The mask for modifiers. */
+ private static final int MODIFIERS_MASK = 0x3fef;
+
+ /**
+ * The cache of recently created keystrokes. This maps KeyStrokes to
+ * KeyStrokes in a cache which removes the least recently accessed entry,
+ * under the assumption that garbage collection of a new keystroke is
+ * easy when we find the old one that it matches in the cache.
+ */
+ private static final LinkedHashMap cache = new LinkedHashMap(11, 0.75f, true)
+ {
+ /** The largest the keystroke cache can grow. */
+ private static final int MAX_CACHE_SIZE = 2048;
+
+ /** Prune stale entries. */
+ protected boolean removeEldestEntry(Map.Entry eldest)
+ { // XXX - FIXME Use Map.Entry, not just Entry as gcj 3.1 workaround.
+ return size() > MAX_CACHE_SIZE;
+ }
+ };
+
+ /** The most recently generated keystroke, or null. */
+ private static AWTKeyStroke recent;
+
+ /**
+ * The no-arg constructor of a subclass, or null to use AWTKeyStroke. Note
+ * that this will be left accessible, to get around private access; but
+ * it should not be a security risk as it is highly unlikely that creating
+ * protected instances of the subclass via reflection will do much damage.
+ */
+ private static Constructor ctor;
+
+ /**
+ * A table of keyCode names to values. This is package-private to
+ * avoid an accessor method.
+ *
+ * @see #getAWTKeyStroke(String)
+ */
+ static final HashMap vktable = new HashMap();
+ static
+ {
+ // Using reflection saves the hassle of keeping this in sync with KeyEvent,
+ // at the price of an expensive initialization.
+ AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ Field[] fields = KeyEvent.class.getFields();
+ int i = fields.length;
+ try
+ {
+ while (--i >= 0)
+ {
+ Field f = fields[i];
+ String name = f.getName();
+ if (name.startsWith("VK_"))
+ vktable.put(name.substring(3), f.get(null));
+ }
+ }
+ catch (Exception e)
+ {
+ throw (Error) new InternalError().initCause(e);
+ }
+ return null;
+ }
+ });
+ }
+
+ /**
+ * The typed character, or CHAR_UNDEFINED for key presses and releases.
+ *
+ * @serial the keyChar
+ */
+ private char keyChar;
+
+ /**
+ * The virtual key code, or VK_UNDEFINED for key typed. Package visible for
+ * use by Component.
+ *
+ * @serial the keyCode
+ */
+ int keyCode;
+
+ /**
+ * The modifiers in effect. To match Sun, this stores the old style masks
+ * for shift, control, alt, meta, and alt-graph (but not button1); as well
+ * as the new style of extended modifiers for all modifiers.
+ *
+ * @serial bitwise or of the *_DOWN_MASK modifiers
+ */
+ private int modifiers;
+
+ /**
+ * True if this is a key release; should only be true if keyChar is
+ * CHAR_UNDEFINED.
+ *
+ * @serial true to distinguish key pressed from key released
+ */
+ private boolean onKeyRelease;
+
+ /**
+ * Construct a keystroke with default values: it will be interpreted as a
+ * key typed event with an invalid character and no modifiers. Client code
+ * should use the factory methods instead.
+ *
+ * @see #getAWTKeyStroke(char)
+ * @see #getAWTKeyStroke(Character, int)
+ * @see #getAWTKeyStroke(int, int, boolean)
+ * @see #getAWTKeyStroke(int, int)
+ * @see #getAWTKeyStrokeForEvent(KeyEvent)
+ * @see #getAWTKeyStroke(String)
+ */
+ protected AWTKeyStroke()
+ {
+ keyChar = KeyEvent.CHAR_UNDEFINED;
+ }
+
+ /**
+ * Construct a keystroke with the given values. Client code should use the
+ * factory methods instead.
+ *
+ * @param keyChar the character entered, if this is a key typed
+ * @param keyCode the key pressed or released, or VK_UNDEFINED for key typed
+ * @param modifiers the modifier keys for the keystroke, in old or new style
+ * @param onKeyRelease true if this is a key release instead of a press
+ * @see #getAWTKeyStroke(char)
+ * @see #getAWTKeyStroke(Character, int)
+ * @see #getAWTKeyStroke(int, int, boolean)
+ * @see #getAWTKeyStroke(int, int)
+ * @see #getAWTKeyStrokeForEvent(KeyEvent)
+ * @see #getAWTKeyStroke(String)
+ */
+ protected AWTKeyStroke(char keyChar, int keyCode, int modifiers,
+ boolean onKeyRelease)
+ {
+ this.keyChar = keyChar;
+ this.keyCode = keyCode;
+ // No need to call extend(), as only trusted code calls this constructor.
+ this.modifiers = modifiers;
+ this.onKeyRelease = onKeyRelease;
+ }
+
+ /**
+ * Registers a new subclass as being the type of keystrokes to generate in
+ * the factory methods. This operation flushes the cache of stored keystrokes
+ * if the class differs from the current one. The new class must be
+ * AWTKeyStroke or a subclass, and must have a no-arg constructor (which may
+ * be private).
+ *
+ * @param subclass the new runtime type of generated keystrokes
+ * @throws IllegalArgumentException subclass doesn't have no-arg constructor
+ * @throws ClassCastException subclass doesn't extend AWTKeyStroke
+ */
+ protected static void registerSubclass(final Class subclass)
+ {
+ if (subclass == null)
+ throw new IllegalArgumentException();
+ if (subclass.equals(ctor == null ? AWTKeyStroke.class
+ : ctor.getDeclaringClass()))
+ return;
+ if (subclass.equals(AWTKeyStroke.class))
+ {
+ cache.clear();
+ recent = null;
+ ctor = null;
+ return;
+ }
+ try
+ {
+ ctor = (Constructor) AccessController.doPrivileged
+ (new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws NoSuchMethodException, InstantiationException,
+ IllegalAccessException, InvocationTargetException
+ {
+ Constructor c = subclass.getDeclaredConstructor(null);
+ c.setAccessible(true);
+ // Create a new instance, to make sure that we can, and
+ // to cause any ClassCastException.
+ AWTKeyStroke dummy = (AWTKeyStroke) c.newInstance(null);
+ return c;
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ // e.getCause() will not ever be ClassCastException; that should
+ // escape on its own.
+ throw (RuntimeException)
+ new IllegalArgumentException().initCause(e.getCause());
+ }
+ cache.clear();
+ recent = null;
+ }
+
+ /**
+ * Returns a keystroke representing a typed character.
+ *
+ * @param keyChar the typed character
+ * @return the specified keystroke
+ */
+ public static AWTKeyStroke getAWTKeyStroke(char keyChar)
+ {
+ return getAWTKeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
+ }
+
+ /**
+ * Returns a keystroke representing a typed character with the given
+ * modifiers. Note that keyChar is a <code>Character</code> instead of a
+ * <code>char</code> to avoid accidental ambiguity with
+ * <code>getAWTKeyStroke(int, int)</code>. The modifiers are the bitwise
+ * or of the masks found in {@link InputEvent}; the new style (*_DOWN_MASK)
+ * is preferred, but the old style will work.
+ *
+ * @param keyChar the typed character
+ * @param modifiers the modifiers, or 0
+ * @return the specified keystroke
+ * @throws IllegalArgumentException if keyChar is null
+ */
+ public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers)
+ {
+ if (keyChar == null)
+ throw new IllegalArgumentException();
+ return getAWTKeyStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED,
+ extend(modifiers), false);
+ }
+
+ /**
+ * Returns a keystroke representing a pressed or released key event, with
+ * the given modifiers. The "virtual key" should be one of the VK_*
+ * constants in {@link KeyEvent}. The modifiers are the bitwise or of the
+ * masks found in {@link InputEvent}; the new style (*_DOWN_MASK) is
+ * preferred, but the old style will work.
+ *
+ * @param keyCode the virtual key
+ * @param modifiers the modifiers, or 0
+ * @param release true if this is a key release instead of a key press
+ * @return the specified keystroke
+ */
+ public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers,
+ boolean release)
+ {
+ return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode,
+ extend(modifiers), release);
+ }
+
+ /**
+ * Returns a keystroke representing a pressed key event, with the given
+ * modifiers. The "virtual key" should be one of the VK_* constants in
+ * {@link KeyEvent}. The modifiers are the bitwise or of the masks found
+ * in {@link InputEvent}; the new style (*_DOWN_MASK) is preferred, but the
+ * old style will work.
+ *
+ * @param keyCode the virtual key
+ * @param modifiers the modifiers, or 0
+ * @return the specified keystroke
+ */
+ public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers)
+ {
+ return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode,
+ extend(modifiers), false);
+ }
+
+ /**
+ * Returns a keystroke representing what caused the key event.
+ *
+ * @param event the key event to convert
+ * @return the specified keystroke, or null if the event is invalid
+ * @throws NullPointerException if event is null
+ */
+ public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent event)
+ {
+ switch (event.id)
+ {
+ case KeyEvent.KEY_TYPED:
+ return getAWTKeyStroke(event.getKeyChar(), KeyEvent.VK_UNDEFINED,
+ extend(event.getModifiersEx()), false);
+ case KeyEvent.KEY_PRESSED:
+ return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, event.getKeyCode(),
+ extend(event.getModifiersEx()), false);
+ case KeyEvent.KEY_RELEASED:
+ return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, event.getKeyCode(),
+ extend(event.getModifiersEx()), true);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Parses a string and returns the keystroke that it represents. The syntax
+ * for keystrokes is listed below, with tokens separated by an arbitrary
+ * number of spaces:
+ * <pre>
+ * keyStroke := &lt;modifiers&gt;* ( &lt;typedID&gt; | &lt;codeID&gt; )
+ * modifiers := ( shift | control | ctrl | meta | alt
+ * | button1 | button2 | button3 )
+ * typedID := typed &lt;single Unicode character&gt;
+ * codeID := ( pressed | released )? &lt;name&gt;
+ * name := &lt;the KeyEvent field name less the leading "VK_"&gt;
+ * </pre>
+ *
+ * <p>Note that the grammar is rather weak, and not all valid keystrokes
+ * can be generated in this manner (for example, a typed space, or anything
+ * with the alt-graph modifier!). The output of AWTKeyStroke.toString()
+ * will not meet the grammar. If pressed or released is not specified,
+ * pressed is assumed. Examples:<br>
+ * <code>
+ * "INSERT" =&gt; getAWTKeyStroke(KeyEvent.VK_INSERT, 0);<br>
+ * "control DELETE" =&gt;
+ * getAWTKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);<br>
+ * "alt shift X" =&gt; getAWTKeyStroke(KeyEvent.VK_X,
+ * InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);<br>
+ * "alt shift released X" =&gt; getAWTKeyStroke(KeyEvent.VK_X,
+ * InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);<br>
+ * "typed a" =&gt; getAWTKeyStroke('a');
+ * </code>
+ *
+ * @param s the string to parse
+ * @throws IllegalArgumentException if s is null or cannot be parsed
+ * @return the specified keystroke
+ */
+ public static AWTKeyStroke getAWTKeyStroke(String s)
+ {
+ if (s == null)
+ throw new IllegalArgumentException("null argument");
+ StringTokenizer t = new StringTokenizer(s, " ");
+ if (! t.hasMoreTokens())
+ throw new IllegalArgumentException("no tokens '" + s + "'");
+ int modifiers = 0;
+ boolean released = false;
+ String token = null;
+ do
+ {
+ token = t.nextToken();
+ if ("shift".equals(token))
+ modifiers |= KeyEvent.SHIFT_DOWN_MASK;
+ else if ("ctrl".equals(token) || "control".equals(token))
+ modifiers |= KeyEvent.CTRL_DOWN_MASK;
+ else if ("meta".equals(token))
+ modifiers |= KeyEvent.META_DOWN_MASK;
+ else if ("alt".equals(token))
+ modifiers |= KeyEvent.ALT_DOWN_MASK;
+ else if ("button1".equals(token))
+ modifiers |= KeyEvent.BUTTON1_DOWN_MASK;
+ else if ("button2".equals(token))
+ modifiers |= KeyEvent.BUTTON2_DOWN_MASK;
+ else if ("button3".equals(token))
+ modifiers |= KeyEvent.BUTTON3_DOWN_MASK;
+ else if ("typed".equals(token))
+ {
+ if (t.hasMoreTokens())
+ {
+ token = t.nextToken();
+ if (! t.hasMoreTokens() && token.length() == 1)
+ return getAWTKeyStroke(token.charAt(0),
+ KeyEvent.VK_UNDEFINED, modifiers,
+ false);
+ }
+ throw new IllegalArgumentException("Invalid 'typed' argument '"
+ + s + "'");
+ }
+ else if ("pressed".equals(token))
+ {
+ if (t.hasMoreTokens())
+ token = t.nextToken();
+ break;
+ }
+ else if ("released".equals(token))
+ {
+ released = true;
+ if (t.hasMoreTokens())
+ token = t.nextToken();
+ break;
+ }
+ else
+ break;
+ }
+ while (t.hasMoreTokens());
+ // Now token contains the VK name we must parse.
+ Integer code = (Integer) vktable.get(token);
+ if (code == null)
+ throw new IllegalArgumentException("Unknown token '" + token
+ + "' in '" + s + "'");
+ if (t.hasMoreTokens())
+ throw new IllegalArgumentException("Too many tokens: " + s);
+ return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, code.intValue(),
+ modifiers, released);
+ }
+
+ /**
+ * Returns the character of this keystroke, if it was typed.
+ *
+ * @return the character value, or CHAR_UNDEFINED
+ * @see #getAWTKeyStroke(char)
+ */
+ public final char getKeyChar()
+ {
+ return keyChar;
+ }
+
+ /**
+ * Returns the virtual key code of this keystroke, if it was pressed or
+ * released. This will be a VK_* constant from KeyEvent.
+ *
+ * @return the virtual key code value, or VK_UNDEFINED
+ * @see #getAWTKeyStroke(int, int)
+ */
+ public final int getKeyCode()
+ {
+ return keyCode;
+ }
+
+ /**
+ * Returns the modifiers for this keystroke. This will be a bitwise or of
+ * constants from InputEvent; it includes the old style masks for shift,
+ * control, alt, meta, and alt-graph (but not button1); as well as the new
+ * style of extended modifiers for all modifiers.
+ *
+ * @return the modifiers
+ * @see #getAWTKeyStroke(Character, int)
+ * @see #getAWTKeyStroke(int, int)
+ */
+ public final int getModifiers()
+ {
+ return modifiers;
+ }
+
+ /**
+ * Tests if this keystroke is a key release.
+ *
+ * @return true if this is a key release
+ * @see #getAWTKeyStroke(int, int, boolean)
+ */
+ public final boolean isOnKeyRelease()
+ {
+ return onKeyRelease;
+ }
+
+ /**
+ * Returns the AWT event type of this keystroke. This is one of
+ * {@link KeyEvent#KEY_TYPED}, {@link KeyEvent#KEY_PRESSED}, or
+ * {@link KeyEvent#KEY_RELEASED}.
+ *
+ * @return the key event type
+ */
+ public final int getKeyEventType()
+ {
+ return keyCode == KeyEvent.VK_UNDEFINED ? KeyEvent.KEY_TYPED
+ : onKeyRelease ? KeyEvent.KEY_RELEASED : KeyEvent.KEY_PRESSED;
+ }
+
+ /**
+ * Returns a hashcode for this key event. It is not documented, but appears
+ * to be: <code>(getKeyChar() + 1) * (getKeyCode() + 1)
+ * * (getModifiers() + 1) * 2 + (isOnKeyRelease() ? 1 : 2)</code>.
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ return (keyChar + 1) * (keyCode + 1) * (modifiers + 1) * 2
+ + (onKeyRelease ? 1 : 2);
+ }
+
+ /**
+ * Tests two keystrokes for equality.
+ *
+ * @param o the object to test
+ * @return true if it is equal
+ */
+ public final boolean equals(Object o)
+ {
+ if (! (o instanceof AWTKeyStroke))
+ return false;
+ AWTKeyStroke s = (AWTKeyStroke) o;
+ return this == o || (keyChar == s.keyChar && keyCode == s.keyCode
+ && modifiers == s.modifiers
+ && onKeyRelease == s.onKeyRelease);
+ }
+
+ /**
+ * Returns a string representation of this keystroke. For typed keystrokes,
+ * this is <code>"keyChar " + KeyEvent.getKeyModifiersText(getModifiers())
+ + getKeyChar()</code>; for pressed and released keystrokes, this is
+ * <code>"keyCode " + KeyEvent.getKeyModifiersText(getModifiers())
+ * + KeyEvent.getKeyText(getKeyCode())
+ * + (isOnKeyRelease() ? "-R" : "-P")</code>.
+ *
+ * @return a string representation
+ */
+ public String toString()
+ {
+ if (keyCode == KeyEvent.VK_UNDEFINED)
+ return "keyChar " + KeyEvent.getKeyModifiersText(modifiers) + keyChar;
+ return "keyCode " + KeyEvent.getKeyModifiersText(modifiers)
+ + KeyEvent.getKeyText(keyCode) + (onKeyRelease ? "-R" : "-P");
+ }
+
+ /**
+ * Returns a cached version of the deserialized keystroke, if available.
+ *
+ * @return a cached replacement
+ * @throws ObjectStreamException if something goes wrong
+ */
+ protected Object readResolve() throws ObjectStreamException
+ {
+ AWTKeyStroke s = (AWTKeyStroke) cache.get(this);
+ if (s != null)
+ return s;
+ cache.put(this, this);
+ return this;
+ }
+
+ /**
+ * Gets the appropriate keystroke, creating one if necessary.
+ *
+ * @param keyChar the keyChar
+ * @param keyCode the keyCode
+ * @param modifiers the modifiers
+ * @param release true for key release
+ * @return the specified keystroke
+ */
+ private static AWTKeyStroke getAWTKeyStroke(char keyChar, int keyCode,
+ int modifiers, boolean release)
+ {
+ // Check level 0 cache.
+ AWTKeyStroke stroke = recent; // Avoid thread races.
+ if (stroke != null && stroke.keyChar == keyChar
+ && stroke.keyCode == keyCode && stroke.modifiers == modifiers
+ && stroke.onKeyRelease == release)
+ return stroke;
+ // Create a new object, on the assumption that if it has a match in the
+ // cache, the VM can easily garbage collect it as it is temporary.
+ Constructor c = ctor; // Avoid thread races.
+ if (c == null)
+ stroke = new AWTKeyStroke(keyChar, keyCode, modifiers, release);
+ else
+ try
+ {
+ stroke = (AWTKeyStroke) c.newInstance(null);
+ stroke.keyChar = keyChar;
+ stroke.keyCode = keyCode;
+ stroke.modifiers = modifiers;
+ stroke.onKeyRelease = release;
+ }
+ catch (Exception e)
+ {
+ throw (Error) new InternalError().initCause(e);
+ }
+ // Check level 1 cache.
+ AWTKeyStroke cached = (AWTKeyStroke) cache.get(stroke);
+ if (cached == null)
+ cache.put(stroke, stroke);
+ else
+ stroke = cached;
+ return recent = stroke;
+ }
+
+ /**
+ * Converts the modifiers to the appropriate format.
+ *
+ * @param mod the modifiers to convert
+ * @return the adjusted modifiers
+ */
+ private static int extend(int mod)
+ {
+ if ((mod & (KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK)) != 0)
+ mod |= KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK;
+ if ((mod & (KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK)) != 0)
+ mod |= KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK;
+ if ((mod & (KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK)) != 0)
+ mod |= KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK;
+ if ((mod & (KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK)) != 0)
+ mod |= KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK;
+ if ((mod & (KeyEvent.ALT_GRAPH_MASK | KeyEvent.ALT_GRAPH_DOWN_MASK)) != 0)
+ mod |= KeyEvent.ALT_GRAPH_MASK | KeyEvent.ALT_GRAPH_DOWN_MASK;
+ if ((mod & KeyEvent.BUTTON1_MASK) != 0)
+ mod |= KeyEvent.BUTTON1_DOWN_MASK;
+ return mod & MODIFIERS_MASK;
+ }
+} // class AWTKeyStroke
diff --git a/libjava/classpath/java/awt/AWTPermission.java b/libjava/classpath/java/awt/AWTPermission.java
new file mode 100644
index 0000000..3e50c05
--- /dev/null
+++ b/libjava/classpath/java/awt/AWTPermission.java
@@ -0,0 +1,121 @@
+/* AWTPermission.java -- AWT related permissions
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.security.BasicPermission;
+
+/**
+ * This class implements permissions for AWT. This is a named
+ * permission. No actions are defined.
+ *
+ * <p>The following table provides a list of all the possible AWTPermission
+ * permission names with a description of what that permission allows.<br>
+ * <table border=1>
+ * <tr><th>Permission Name</th><th>Permission Allows</th><th>Risks</th</tr>
+ * <tr>
+ * <td><code>accessClipboard</code></td>
+ * <td>posting and reading the AWT clipboard</td>
+ * <td>the clipboard may contain sensitive data</td></tr>
+ * <tr>
+ * <td><code>accessEventQueue</code></td>
+ * <td>access to the AWT event queue</td>
+ * <td>malicious code could remove real events and replace them with bogus
+ * ones, including simulating the user granting permission</td></tr>
+ * <tr>
+ * <td><code>listenToAllAWTEvents</code></td>
+ * <td>listen to system-wide AWT events</td>
+ * <td>malicious code can read passwords entered in an AWT event, and in
+ * combination with accessEventQueue, could fake system events</td></tr>
+ * <tr>
+ * <td><code>showWindowWithoutWarningBanner</code></td>
+ * <td>display a window without a banner notification of insecurity</td>
+ * <td>malicious code could install a Trojan horse applet that looks like
+ * a normal window, and thus steal data like passwords</td></tr>
+ * <tr>
+ * <td><code>readDisplayPixels</code></td>
+ * <td>read back pixels from the display screen</td>
+ * <td>malicious code could snoop on the user's actions</td></tr>
+ * <tr>
+ * <td><code>createRobot</code></td>
+ * <td>create an instance of java.awt.Robot</td>
+ * <td>these objects can generate events as though they were the user; so
+ * malicious code could control the system</td></tr>
+ * <tr>
+ * <td><code>fullScreenExclusive</code></td>
+ * <td>enter full-screen exclusive mode</td>
+ * <td>malicious code could masquerade as a trusted program</td></tr>
+ * </table>
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public final class AWTPermission extends BasicPermission
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 8890392402588814465L;
+
+ /**
+ * Construct a AWTPermission with the given name.
+ *
+ * @param name the permission name
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if name is invalid
+ */
+ public AWTPermission(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Create a new permission with the specified name. The actions argument
+ * is ignored, as AWT permissions have no actions.
+ *
+ * @param name the permission name
+ * @param actions ignored
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if name is invalid
+ */
+ public AWTPermission(String name, String actions)
+ {
+ super(name);
+ }
+} // class AWTPermission
diff --git a/libjava/classpath/java/awt/ActiveEvent.java b/libjava/classpath/java/awt/ActiveEvent.java
new file mode 100644
index 0000000..e42959f
--- /dev/null
+++ b/libjava/classpath/java/awt/ActiveEvent.java
@@ -0,0 +1,61 @@
+/* ActiveEvent.java -- a self-dispatching event
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * An interface for events which can dispatch themselves in another thread.
+ * This has two uses: first, if your code is in a critical section, calling a
+ * synchronized method might deadlock. But by using an ActiveEvent to call
+ * the second section, it will not obtain the lock until you have left the
+ * critical section, avoiding deadlock. The second use is for calling
+ * untrusted code. For example, system code should use an ActiveEvent to
+ * invoke user code securely.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface ActiveEvent
+{
+ /**
+ * Dispatch the event, according to what the event needs done. Invoked
+ * automatically if this is placed on the <code>EventDispatchQueue</code>.
+ */
+ void dispatch();
+} // interface ActiveEvent
diff --git a/libjava/classpath/java/awt/Adjustable.java b/libjava/classpath/java/awt/Adjustable.java
new file mode 100644
index 0000000..8f633e9
--- /dev/null
+++ b/libjava/classpath/java/awt/Adjustable.java
@@ -0,0 +1,171 @@
+/* Adjustable.java -- Objects with a numeric adjustment scale
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.AdjustmentListener;
+
+/**
+ * This interface is for objects that take a numeric value that can be
+ * adjusted within a bounded range. For example, a scroll bar.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public interface Adjustable
+{
+ /** Constant for an adjustable object with horizontal orientation. */
+ int HORIZONTAL = 0;
+
+ /** Constant for an adjustable object with vertical orientation. */
+ int VERTICAL = 1;
+
+ /** Constant for an adjustable object with no orientation. */
+ int NO_ORIENTATION = 2;
+
+ /**
+ * Returns a constant representing the orientation of the object.
+ *
+ * @return the orientation of this object
+ * @see #HORIZONTAL
+ * @see #VERTICAL
+ * @see #NO_ORIENTATION
+ */
+ int getOrientation();
+
+ /**
+ * Sets the minimum value this object can have.
+ *
+ * @param minimum the new minimum value
+ */
+ void setMinimum(int minimum);
+
+ /**
+ * Returns the minimum value this object can have.
+ *
+ * @return the minimum value
+ */
+ int getMinimum();
+
+ /**
+ * Sets the maximum value this object can have.
+ *
+ * @param maximum the new maximum value
+ */
+ void setMaximum(int maximum);
+
+ /**
+ * Returns the maximum value this object can have.
+ *
+ * @return the maximum value
+ */
+ int getMaximum();
+
+ /**
+ * Sets the increment value for incrementing the value by units.
+ *
+ * @param increment the unit increment value
+ */
+ void setUnitIncrement(int increment);
+
+ /**
+ * Returns the increment value for incrementing the value by units.
+ *
+ * @return the unit increment value
+ */
+ int getUnitIncrement();
+
+ /**
+ * Sets the increment value for incrementing the value by blocks.
+ *
+ * @param increment the block increment value
+ */
+ void setBlockIncrement(int increment);
+
+ /**
+ * Returns the increment value for incrementing the value by blocks.
+ *
+ * @return the block increment value
+ */
+ int getBlockIncrement();
+
+ /**
+ * Sets the length of the indicator for this object to the specified value.
+ *
+ * @param length the indicator length
+ */
+ void setVisibleAmount(int length);
+
+ /**
+ * Returns the length of the indicator for this object.
+ *
+ * @return the indicator length
+ */
+ int getVisibleAmount();
+
+ /**
+ * Sets the current value of the object.
+ *
+ * @param value the new value
+ */
+ void setValue(int value);
+
+ /**
+ * Returns the current value of the object.
+ *
+ * @return the current value
+ */
+ int getValue();
+
+ /**
+ * Adds a listener that will receive adjustment events for this object.
+ *
+ * @param listener the adjustment listener to add
+ * @see java.awt.event.AdjustmentEvent
+ */
+ void addAdjustmentListener(AdjustmentListener listener);
+
+ /**
+ * Removes an adjustment listener from this object.
+ *
+ * @param listener the adjustment listener to remove
+ * @see java.awt.event.AdjustmentEvent
+ */
+ void removeAdjustmentListener(AdjustmentListener listener);
+} // interface Adjustable
diff --git a/libjava/classpath/java/awt/AlphaComposite.java b/libjava/classpath/java/awt/AlphaComposite.java
new file mode 100644
index 0000000..435cfd0
--- /dev/null
+++ b/libjava/classpath/java/awt/AlphaComposite.java
@@ -0,0 +1,167 @@
+/* AlphaComposite.java -- provides a context for performing alpha compositing
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.ColorModel;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Composite
+ * @see CompositeContext
+ * @since 1.3
+ * @status updated to 1.4 except for createContext, needs documentation
+ */
+public final class AlphaComposite implements Composite
+{
+ /** Map Long to AlphaComposites. See getInstance for details. */
+ private static final LinkedHashMap cache = new LinkedHashMap(11, 0.75f, true)
+ {
+ /** The largest the alpha composite cache can grow. */
+ private static final int MAX_CACHE_SIZE = 2048;
+
+ /** Prune stale entries. */
+ protected boolean removeEldestEntry(Map.Entry eldest)
+ { // XXX - FIXME Use Map.Entry, not just Entry as gcj 3.1 workaround.
+ return size() > MAX_CACHE_SIZE;
+ }
+ };
+
+ public static final int CLEAR = 1;
+ public static final int SRC = 2;
+ public static final int DST = 9;
+ public static final int SRC_OVER = 3;
+ public static final int DST_OVER = 4;
+ public static final int SRC_IN = 5;
+ public static final int DST_IN = 6;
+ public static final int SRC_OUT = 7;
+ public static final int DST_OUT = 8;
+ public static final int SRC_ATOP = 10;
+ public static final int DST_ATOP = 11;
+ public static final int XOR = 12;
+ public static final AlphaComposite Clear = getInstance(CLEAR);
+ public static final AlphaComposite Src = getInstance(SRC);
+ public static final AlphaComposite Dst = getInstance(DST);
+ public static final AlphaComposite SrcOver = getInstance(SRC_OVER);
+ public static final AlphaComposite DstOver = getInstance(DST_OVER);
+ public static final AlphaComposite SrcIn = getInstance(SRC_IN);
+ public static final AlphaComposite DstIn = getInstance(DST_IN);
+ public static final AlphaComposite SrcOut = getInstance(SRC_OUT);
+ public static final AlphaComposite DstOut = getInstance(DST_OUT);
+ public static final AlphaComposite SrcAtop = getInstance(SRC_ATOP);
+ public static final AlphaComposite DstAtop = getInstance(DST_ATOP);
+ public static final AlphaComposite Xor = getInstance(XOR);
+
+ private final int rule;
+ private final float alpha;
+ private AlphaComposite(int rule, float alpha)
+ {
+ this.rule = rule;
+ this.alpha = alpha;
+ }
+
+ /**
+ * Creates an AlphaComposite object with the specified rule.
+ *
+ * @param rule The compositing rule.
+ *
+ * @exception IllegalArgumentException If rule is not one of the following:
+ * CLEAR, SRC, DST, SRC_OVER, DST_OVER, SRC_IN, DST_IN, SRC_OUT, DST_OUT,
+ * SRC_ATOP, DST_ATOP, or XOR.
+ */
+ public static AlphaComposite getInstance(int rule)
+ {
+ return getInstance(rule, 1);
+ }
+
+ /**
+ * Creates an AlphaComposite object with the specified rule and the constant
+ * alpha to multiply with the alpha of the source. The source is multiplied
+ * with the specified alpha before being composited with the destination.
+ *
+ * @param rule The compositing rule.
+ *
+ * @exception IllegalArgumentException If rule is not one of the following:
+ * CLEAR, SRC, DST, SRC_OVER, DST_OVER, SRC_IN, DST_IN, SRC_OUT, DST_OUT,
+ * SRC_ATOP, DST_ATOP, or XOR.
+ */
+ public static AlphaComposite getInstance(int rule, float alpha)
+ {
+ if (rule < CLEAR || rule > XOR || ! (alpha >= 0 && alpha <= 1))
+ throw new IllegalArgumentException();
+ // This long is guaranteed unique for all valid alpha composites.
+ Long l = new Long(rule + Double.doubleToLongBits(alpha));
+ AlphaComposite a = (AlphaComposite) cache.get(l);
+ if (a == null)
+ {
+ a = new AlphaComposite(rule, alpha);
+ cache.put(l, a);
+ }
+ return a;
+ }
+ public CompositeContext createContext(ColorModel srcColorModel,
+ ColorModel dstColorModel,
+ RenderingHints hints)
+ {
+ // XXX Implement. Sun uses undocumented implementation class
+ // sun.java2d.SunCompositeContext.
+ throw new Error("not implemented");
+ }
+ public float getAlpha()
+ {
+ return alpha;
+ }
+ public int getRule()
+ {
+ return rule;
+ }
+ public int hashCode()
+ {
+ return 31 * Float.floatToIntBits(alpha) + rule;
+ }
+ public boolean equals(Object o)
+ {
+ if (! (o instanceof AlphaComposite))
+ return false;
+ AlphaComposite a = (AlphaComposite) o;
+ return rule == a.rule && alpha == a.alpha;
+ }
+} // class AlphaComposite
diff --git a/libjava/classpath/java/awt/AttributeValue.java b/libjava/classpath/java/awt/AttributeValue.java
new file mode 100644
index 0000000..080e92e
--- /dev/null
+++ b/libjava/classpath/java/awt/AttributeValue.java
@@ -0,0 +1,98 @@
+/* AttributeValue.java -- parent of type-safe enums of attributes
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This class is undocumented by Sun, but it is the parent of several other
+ * classes, all of which are type-safe enumerations. This takes care of
+ * <code>equals</code>, <code>toString</code>, and <code>hashCode</code>, so
+ * that you don't have to (although hashCode is commonly overridden).
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+class AttributeValue
+{
+ /** The value of the enumeration. Package visible for speed. */
+ final int value;
+
+ /** The list of enumeration names for the given subclass. */
+ private final String[] names;
+
+ /**
+ * Construct a type-safe enumeration element. For example,<br>
+ * <pre>
+ * class Foo extends AttributeValue
+ * {
+ * private static final String[] names = { "one", "two" }
+ * public static final Foo ONE = new Foo(0);
+ * public static final Foo TWO = new Foo(1);
+ * private Foo(int value) { super(value, names); }
+ * }
+ * </pre>
+ *
+ * @param value the position of this enumeration element, consecutive from 0
+ * @param names the constant list of enumeration names for the subclass
+ */
+ AttributeValue(int value, String[] names)
+ {
+ this.value = value;
+ this.names = names;
+ }
+
+ /**
+ * Returns the hashcode of this element. This is the index of the element
+ * in the enumeration. Note that equals defaults to the == relation.
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ return value;
+ }
+
+ /**
+ * Returns the name of this enumeration element.
+ *
+ * @return the element name
+ */
+ public String toString()
+ {
+ return names[value];
+ }
+} // class AttributeValue
diff --git a/libjava/classpath/java/awt/BasicStroke.java b/libjava/classpath/java/awt/BasicStroke.java
new file mode 100644
index 0000000..bb008e4
--- /dev/null
+++ b/libjava/classpath/java/awt/BasicStroke.java
@@ -0,0 +1,248 @@
+/* BasicStroke.java --
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.util.Arrays;
+
+/**
+ * STUB CLASS ONLY
+ */
+public class BasicStroke implements Stroke
+{
+ public static final int JOIN_MITER = 0;
+ public static final int JOIN_ROUND = 1;
+ public static final int JOIN_BEVEL = 2;
+
+ public static final int CAP_BUTT = 0;
+ public static final int CAP_ROUND = 1;
+ public static final int CAP_SQUARE = 2;
+
+ private final float width;
+ private final int cap;
+ private final int join;
+ private final float limit;
+ private final float[] dash;
+ private final float phase;
+
+ /**
+ * Creates a basic stroke.
+ *
+ * @param width May not be negative .
+ * @param cap May be either CAP_BUTT, CAP_ROUND or CAP_SQUARE.
+ * @param join May be either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER.
+ * @param miterlimit the limit to trim the miter join. The miterlimit must be
+ * greater than or equal to 1.0f.
+ * @param dash The array representing the dashing pattern. There must be at
+ * least one non-zero entry.
+ * @param dashPhase is negative and dash is not null.
+ *
+ * @exception IllegalArgumentException If one input parameter doesn't meet
+ * its needs.
+ */
+ public BasicStroke(float width, int cap, int join, float miterlimit,
+ float[] dash, float dashPhase)
+ {
+ if (width < 0.0f )
+ throw new IllegalArgumentException("width " + width + " < 0");
+ else if (cap < CAP_BUTT || cap > CAP_SQUARE)
+ throw new IllegalArgumentException("cap " + cap + " out of range ["
+ + CAP_BUTT + ".." + CAP_SQUARE + "]");
+ else if (miterlimit < 1.0f && join == JOIN_MITER)
+ throw new IllegalArgumentException("miterlimit " + miterlimit
+ + " < 1.0f while join == JOIN_MITER");
+ else if (join < JOIN_MITER || join > JOIN_BEVEL)
+ throw new IllegalArgumentException("join " + join + " out of range ["
+ + JOIN_MITER + ".." + JOIN_BEVEL
+ + "]");
+ else if (dashPhase < 0.0f && dash != null)
+ throw new IllegalArgumentException("dashPhase " + dashPhase
+ + " < 0.0f while dash != null");
+ else if (dash != null)
+ if (dash.length == 0)
+ throw new IllegalArgumentException("dash.length is 0");
+ else
+ {
+ boolean allZero = true;
+
+ for ( int i = 0; i < dash.length; ++i)
+ {
+ if (dash[i] != 0.0f)
+ {
+ allZero = false;
+ break;
+ }
+ }
+
+ if (allZero)
+ throw new IllegalArgumentException("all dashes are 0.0f");
+ }
+
+ this.width = width;
+ this.cap = cap;
+ this.join = join;
+ limit = miterlimit;
+ this.dash = dash == null ? null : (float[]) dash.clone();
+ phase = dashPhase;
+ }
+
+ /**
+ * Creates a basic stroke.
+ *
+ * @param width The width of the BasicStroke. May not be negative .
+ * @param cap May be either CAP_BUTT, CAP_ROUND or CAP_SQUARE.
+ * @param join May be either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER.
+ * @param miterlimit the limit to trim the miter join. The miterlimit must be
+ * greater than or equal to 1.0f.
+ *
+ * @exception IllegalArgumentException If one input parameter doesn't meet
+ * its needs.
+ */
+ public BasicStroke(float width, int cap, int join, float miterlimit)
+ {
+ this(width, cap, join, miterlimit, null, 0);
+ }
+
+ /**
+ * Creates a basic stroke.
+ *
+ * @param width The width of the BasicStroke. May not be nehative.
+ * @param cap May be either CAP_BUTT, CAP_ROUND or CAP_SQUARE.
+ * @param join May be either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER.
+ *
+ * @exception IllegalArgumentException If one input parameter doesn't meet
+ * its needs.
+ * @exception IllegalArgumentException FIXME
+ */
+ public BasicStroke(float width, int cap, int join)
+ {
+ this(width, cap, join, 10, null, 0);
+ }
+
+ /**
+ * Creates a basic stroke.
+ *
+ * @param width The width of the BasicStroke.
+ *
+ * @exception IllegalArgumentException If width is negative.
+ */
+ public BasicStroke(float width)
+ {
+ this(width, CAP_SQUARE, JOIN_MITER, 10, null, 0);
+ }
+
+ /**
+ * Creates a basic stroke.
+ */
+ public BasicStroke()
+ {
+ this(1, CAP_SQUARE, JOIN_MITER, 10, null, 0);
+ }
+
+ public Shape createStrokedShape(Shape s)
+ {
+ throw new Error("not implemented");
+ }
+
+ public float getLineWidth()
+ {
+ return width;
+ }
+
+ public int getEndCap()
+ {
+ return cap;
+ }
+
+ public int getLineJoin()
+ {
+ return join;
+ }
+
+ public float getMiterLimit()
+ {
+ return limit;
+ }
+
+ public float[] getDashArray()
+ {
+ return dash;
+ }
+
+ public float getDashPhase()
+ {
+ return phase;
+ }
+
+ /**
+ * Returns the hash code for this object. The hash is calculated by
+ * xoring the hash, cap, join, limit, dash array and phase values
+ * (converted to <code>int</code> first with
+ * <code>Float.floatToIntBits()</code> if the value is a
+ * <code>float</code>).
+ */
+ public int hashCode()
+ {
+ int hash = Float.floatToIntBits(width);
+ hash ^= cap;
+ hash ^= join;
+ hash ^= Float.floatToIntBits(limit);
+
+ if (dash != null)
+ for (int i = 0; i < dash.length; i++)
+ hash ^= Float.floatToIntBits(dash[i]);
+
+ hash ^= Float.floatToIntBits(phase);
+
+ return hash;
+ }
+
+ /**
+ * Returns true if the given Object is an instance of BasicStroke
+ * and the width, cap, join, limit, dash array and phase are all
+ * equal.
+ */
+ public boolean equals(Object o)
+ {
+ if (! (o instanceof BasicStroke))
+ return false;
+ BasicStroke s = (BasicStroke) o;
+ return width == s.width && cap == s.cap && join == s.join
+ && limit == s.limit && Arrays.equals(dash, s.dash) && phase == s.phase;
+ }
+} // class BasicStroke
diff --git a/libjava/classpath/java/awt/BorderLayout.java b/libjava/classpath/java/awt/BorderLayout.java
new file mode 100644
index 0000000..c9eb5dd
--- /dev/null
+++ b/libjava/classpath/java/awt/BorderLayout.java
@@ -0,0 +1,731 @@
+/* BorderLayout.java -- A layout manager class
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This class implements a layout manager that positions components
+ * in certain sectors of the parent container.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public class BorderLayout implements LayoutManager2, java.io.Serializable
+{
+
+/*
+ * Static Variables
+ */
+
+/**
+ * Constant indicating the top of the container
+ */
+public static final String NORTH = "North";
+
+/**
+ * Constant indicating the bottom of the container
+ */
+public static final String SOUTH = "South";
+
+/**
+ * Constant indicating the right side of the container
+ */
+public static final String EAST = "East";
+
+/**
+ * Constant indicating the left side of the container
+ */
+public static final String WEST = "West";
+
+/**
+ * Constant indicating the center of the container
+ */
+public static final String CENTER = "Center";
+
+
+ /**
+ * The constant indicating the position before the first line of the
+ * layout. The exact position depends on the writing system: For a
+ * top-to-bottom orientation, it is the same as {@link #NORTH}, for
+ * a bottom-to-top orientation, it is the same as {@link #SOUTH}.
+ *
+ * <p>This constant is an older name for {@link #PAGE_START} which
+ * has exactly the same value.
+ *
+ * @since 1.2
+ */
+ public static final String BEFORE_FIRST_LINE = "First";
+
+
+ /**
+ * The constant indicating the position after the last line of the
+ * layout. The exact position depends on the writing system: For a
+ * top-to-bottom orientation, it is the same as {@link #SOUTH}, for
+ * a bottom-to-top orientation, it is the same as {@link #NORTH}.
+ *
+ * <p>This constant is an older name for {@link #PAGE_END} which
+ * has exactly the same value.
+ *
+ * @since 1.2
+ */
+ public static final String AFTER_LAST_LINE = "Last";
+
+
+ /**
+ * The constant indicating the position before the first item of the
+ * layout. The exact position depends on the writing system: For a
+ * left-to-right orientation, it is the same as {@link #WEST}, for
+ * a right-to-left orientation, it is the same as {@link #EAST}.
+ *
+ * <p>This constant is an older name for {@link #LINE_START} which
+ * has exactly the same value.
+ *
+ * @since 1.2
+ */
+ public static final String BEFORE_LINE_BEGINS = "Before";
+
+
+ /**
+ * The constant indicating the position after the last item of the
+ * layout. The exact position depends on the writing system: For a
+ * left-to-right orientation, it is the same as {@link #EAST}, for
+ * a right-to-left orientation, it is the same as {@link #WEST}.
+ *
+ * <p>This constant is an older name for {@link #LINE_END} which
+ * has exactly the same value.
+ *
+ * @since 1.2
+ */
+ public static final String AFTER_LINE_ENDS = "After";
+
+
+ /**
+ * The constant indicating the position before the first line of the
+ * layout. The exact position depends on the writing system: For a
+ * top-to-bottom orientation, it is the same as {@link #NORTH}, for
+ * a bottom-to-top orientation, it is the same as {@link #SOUTH}.
+ *
+ * @since 1.4
+ */
+ public static final String PAGE_START = BEFORE_FIRST_LINE;
+
+
+ /**
+ * The constant indicating the position after the last line of the
+ * layout. The exact position depends on the writing system: For a
+ * top-to-bottom orientation, it is the same as {@link #SOUTH}, for
+ * a bottom-to-top orientation, it is the same as {@link #NORTH}.
+ *
+ * @since 1.4
+ */
+ public static final String PAGE_END = AFTER_LAST_LINE;
+
+
+ /**
+ * The constant indicating the position before the first item of the
+ * layout. The exact position depends on the writing system: For a
+ * left-to-right orientation, it is the same as {@link #WEST}, for
+ * a right-to-left orientation, it is the same as {@link #EAST}.
+ *
+ * @since 1.4
+ */
+ public static final String LINE_START = BEFORE_LINE_BEGINS;
+
+
+ /**
+ * The constant indicating the position after the last item of the
+ * layout. The exact position depends on the writing system: For a
+ * left-to-right orientation, it is the same as {@link #EAST}, for
+ * a right-to-left orientation, it is the same as {@link #WEST}.
+ *
+ * @since 1.4
+ */
+ public static final String LINE_END = AFTER_LINE_ENDS;
+
+
+
+// Serialization constant
+private static final long serialVersionUID = -8658291919501921765L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial
+ */
+private Component north;
+
+/**
+ * @serial
+ */
+private Component south;
+
+/**
+ * @serial
+ */
+private Component east;
+
+/**
+ * @serial
+ */
+private Component west;
+
+/**
+ * @serial
+ */
+private Component center;
+
+/**
+ * @serial
+ */
+private Component firstLine;
+
+/**
+ * @serial
+ */
+private Component lastLine;
+
+/**
+ * @serial
+ */
+private Component firstItem;
+
+/**
+ * @serial
+ */
+private Component lastItem;
+
+/**
+ * @serial The horizontal gap between components
+ */
+private int hgap;
+
+/**
+ * @serial The vertical gap between components
+ */
+private int vgap;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>BorderLayout</code> with no
+ * horiztonal or vertical gaps between components.
+ */
+public
+BorderLayout()
+{
+ this(0,0);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>BorderLayout</code> with the
+ * specified horiztonal and vertical gaps between components.
+ *
+ * @param hgap The horizontal gap between components.
+ * @param vgap The vertical gap between components.
+ */
+public
+BorderLayout(int hgap, int vgap)
+{
+ this.hgap = hgap;
+ this.vgap = vgap;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Returns the horitzontal gap value.
+ *
+ * @return The horitzontal gap value.
+ */
+public int
+getHgap()
+{
+ return(hgap);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the horizontal gap to the specified value.
+ *
+ * @param hgap The new horizontal gap.
+ */
+public void
+setHgap(int hgap)
+{
+ this.hgap = hgap;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the vertical gap value.
+ *
+ * @return The vertical gap value.
+ */
+public int
+getVgap()
+{
+ return(vgap);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the vertical gap to the specified value.
+ *
+ * @param vgap The new vertical gap value.
+ */
+public void
+setVgap(int vgap)
+{
+ this.vgap = vgap;
+}
+
+/*************************************************************************/
+
+/**
+ * Adds a component to the layout in the specified constraint position,
+ * which must be one of the string constants defined in this class.
+ *
+ * @param component The component to add.
+ * @param constraints The constraint string.
+ *
+ * @exception IllegalArgumentException If the constraint object is not
+ * a string, or is not one of the specified constants in this class.
+ */
+public void
+addLayoutComponent(Component component, Object constraints)
+{
+ if (constraints != null && ! (constraints instanceof String))
+ throw new IllegalArgumentException("Constraint must be a string");
+
+ addLayoutComponent((String) constraints, component);
+}
+
+/*************************************************************************/
+
+/**
+ * Adds a component to the layout in the specified constraint position,
+ * which must be one of the string constants defined in this class.
+ *
+ * @param constraints The constraint string.
+ * @param component The component to add.
+ *
+ * @exception IllegalArgumentException If the constraint object is not
+ * one of the specified constants in this class.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>addLayoutComponent(Component, Object)</code>.
+ */
+public void
+addLayoutComponent(String constraints, Component component)
+{
+ String str = constraints;
+
+ if (str == null || str.equals(CENTER))
+ center = component;
+ else if (str.equals(NORTH))
+ north = component;
+ else if (str.equals(SOUTH))
+ south = component;
+ else if (str.equals(EAST))
+ east = component;
+ else if (str.equals(WEST))
+ west = component;
+ else if (str.equals(BEFORE_FIRST_LINE))
+ firstLine = component;
+ else if (str.equals(AFTER_LAST_LINE))
+ lastLine = component;
+ else if (str.equals(BEFORE_LINE_BEGINS))
+ firstItem = component;
+ else if (str.equals(AFTER_LINE_ENDS))
+ lastItem = component;
+ else
+ throw new IllegalArgumentException("Constraint value not valid: " + str);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified component from the layout.
+ *
+ * @param component The component to remove from the layout.
+ */
+public void
+removeLayoutComponent(Component component)
+{
+ if (north == component)
+ north = null;
+ if (south == component)
+ south = null;
+ if (east == component)
+ east = null;
+ if (west == component)
+ west = null;
+ if (center == component)
+ center = null;
+ if (firstItem == component)
+ firstItem = null;
+ if (lastItem == component)
+ lastItem = null;
+ if (firstLine == component)
+ firstLine = null;
+ if (lastLine == component)
+ lastLine = null;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size of the specified container using this layout.
+ *
+ * @param target The container to calculate the minimum size for.
+ *
+ * @return The minimum size of the container
+ */
+public Dimension
+minimumLayoutSize(Container target)
+{
+ return calcSize(target, MIN);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size of the specified container using this layout.
+ *
+ * @param target The container to calculate the preferred size for.
+ *
+ * @return The preferred size of the container
+ */
+public Dimension
+preferredLayoutSize(Container target)
+{
+ return calcSize(target, PREF);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the maximum size of the specified container using this layout.
+ *
+ * @param target The container to calculate the maximum size for.
+ *
+ * @return The maximum size of the container
+ */
+public Dimension
+maximumLayoutSize(Container target)
+{
+ return calcSize(target, MAX);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the X axis alignment, which is a <code>float</code> indicating
+ * where along the X axis this container wishs to position its layout.
+ * 0 indicates align to the left, 1 indicates align to the right, and 0.5
+ * indicates align to the center.
+ *
+ * @param parent The parent container.
+ *
+ * @return The X alignment value.
+ */
+public float
+getLayoutAlignmentX(Container parent)
+{
+ return(parent.getAlignmentX());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the Y axis alignment, which is a <code>float</code> indicating
+ * where along the Y axis this container wishs to position its layout.
+ * 0 indicates align to the top, 1 indicates align to the bottom, and 0.5
+ * indicates align to the center.
+ *
+ * @param parent The parent container.
+ *
+ * @return The Y alignment value.
+ */
+public float
+getLayoutAlignmentY(Container parent)
+{
+ return(parent.getAlignmentY());
+}
+
+/*************************************************************************/
+
+/**
+ * Instructs this object to discard any layout information it might
+ * have cached.
+ *
+ * @param parent The parent container.
+ */
+public void
+invalidateLayout(Container parent)
+{
+}
+
+/*************************************************************************/
+
+/**
+ * Lays out the specified container according to the constraints
+ * in this object.
+ *
+ * @param target The container to lay out.
+ */
+public void
+layoutContainer(Container target)
+{
+ synchronized (target.getTreeLock ())
+ {
+ Insets i = target.getInsets();
+
+ ComponentOrientation orient = target.getComponentOrientation ();
+ boolean left_to_right = orient.isLeftToRight ();
+
+ Component my_north = north;
+ Component my_east = east;
+ Component my_south = south;
+ Component my_west = west;
+
+ // Note that we currently don't handle vertical layouts. Neither
+ // does JDK 1.3.
+ if (firstLine != null)
+ my_north = firstLine;
+ if (lastLine != null)
+ my_south = lastLine;
+ if (firstItem != null)
+ {
+ if (left_to_right)
+ my_west = firstItem;
+ else
+ my_east = firstItem;
+ }
+ if (lastItem != null)
+ {
+ if (left_to_right)
+ my_east = lastItem;
+ else
+ my_west = lastItem;
+ }
+
+ Dimension c = calcCompSize(center, PREF);
+ Dimension n = calcCompSize(my_north, PREF);
+ Dimension s = calcCompSize(my_south, PREF);
+ Dimension e = calcCompSize(my_east, PREF);
+ Dimension w = calcCompSize(my_west, PREF);
+ Dimension t = target.getSize();
+
+ /*
+ <-> hgap <-> hgap
+ +----------------------------+ }
+ |t | } i.top
+ | +----------------------+ | --- y1 }
+ | |n | |
+ | +----------------------+ | } vgap
+ | +---+ +----------+ +---+ | --- y2 } }
+ | |w | |c | |e | | } hh
+ | +---+ +----------+ +---+ | } vgap }
+ | +----------------------+ | --- y3 }
+ | |s | |
+ | +----------------------+ | }
+ | | } i.bottom
+ +----------------------------+ }
+ |x1 |x2 |x3
+ <---------------------->
+ <--> ww <-->
+ i.left i.right
+ */
+
+ int x1 = i.left;
+ int x2 = x1 + w.width + hgap;
+ int x3;
+ if (t.width <= i.right + e.width)
+ x3 = x2 + w.width + hgap;
+ else
+ x3 = t.width - i.right - e.width;
+ int ww = t.width - i.right - i.left;
+
+ int y1 = i.top;
+ int y2 = y1 + n.height + vgap;
+ int midh = Math.max(e.height, Math.max(w.height, c.height));
+ int y3;
+ if (t.height <= i.bottom + s.height)
+ y3 = y2 + midh + vgap;
+ else
+ y3 = t.height - i.bottom - s.height;
+ int hh = y3-y2-vgap;
+
+ setBounds(center, x2, y2, x3-x2-hgap, hh);
+ setBounds(my_north, x1, y1, ww, n.height);
+ setBounds(my_south, x1, y3, ww, s.height);
+ setBounds(my_west, x1, y2, w.width, hh);
+ setBounds(my_east, x3, y2, e.width, hh);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a string representation of this layout manager.
+ *
+ * @return A string representation of this object.
+ */
+public String
+toString()
+{
+ return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
+}
+
+private void
+setBounds(Component comp, int x, int y, int w, int h)
+{
+ if (comp == null)
+ return;
+ comp.setBounds(x, y, w, h);
+}
+
+// Some constants for use with calcSize().
+private static final int MIN = 0;
+private static final int MAX = 1;
+private static final int PREF = 2;
+
+private Dimension
+calcCompSize(Component comp, int what)
+{
+ if (comp == null || !comp.isVisible())
+ return new Dimension(0, 0);
+ if (what == MIN)
+ return comp.getMinimumSize();
+ else if (what == MAX)
+ return comp.getMaximumSize();
+ return comp.getPreferredSize();
+}
+
+// This is a helper function used to compute the various sizes for
+// this layout.
+private Dimension
+calcSize(Container target, int what)
+{
+ synchronized (target.getTreeLock ())
+ {
+ Insets ins = target.getInsets();
+
+ ComponentOrientation orient = target.getComponentOrientation ();
+ boolean left_to_right = orient.isLeftToRight ();
+
+ Component my_north = north;
+ Component my_east = east;
+ Component my_south = south;
+ Component my_west = west;
+
+ // Note that we currently don't handle vertical layouts. Neither
+ // does JDK 1.3.
+ if (firstLine != null)
+ my_north = firstLine;
+ if (lastLine != null)
+ my_south = lastLine;
+ if (firstItem != null)
+ {
+ if (left_to_right)
+ my_west = firstItem;
+ else
+ my_east = firstItem;
+ }
+ if (lastItem != null)
+ {
+ if (left_to_right)
+ my_east = lastItem;
+ else
+ my_west = lastItem;
+ }
+
+ Dimension ndim = calcCompSize(my_north, what);
+ Dimension sdim = calcCompSize(my_south, what);
+ Dimension edim = calcCompSize(my_east, what);
+ Dimension wdim = calcCompSize(my_west, what);
+ Dimension cdim = calcCompSize(center, what);
+
+ int width = edim.width + cdim.width + wdim.width + (hgap * 2);
+ // check for overflow
+ if (width < edim.width || width < cdim.width || width < cdim.width)
+ width = Integer.MAX_VALUE;
+
+ if (ndim.width > width)
+ width = ndim.width;
+ if (sdim.width > width)
+ width = sdim.width;
+
+ width += (ins.left + ins.right);
+
+ int height = edim.height;
+ if (cdim.height > height)
+ height = cdim.height;
+ if (wdim.height > height)
+ height = wdim.height;
+
+ int addedHeight = height + (ndim.height + sdim.height + (vgap * 2)
+ + ins.top + ins.bottom);
+ // check for overflow
+ if (addedHeight < height)
+ height = Integer.MAX_VALUE;
+ else
+ height = addedHeight;
+
+ return(new Dimension(width, height));
+ }
+}
+} // class BorderLayout
diff --git a/libjava/classpath/java/awt/BufferCapabilities.java b/libjava/classpath/java/awt/BufferCapabilities.java
new file mode 100644
index 0000000..bba83dc
--- /dev/null
+++ b/libjava/classpath/java/awt/BufferCapabilities.java
@@ -0,0 +1,253 @@
+/* BufferCapabilities.java -- double-buffering capabilities descriptor
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.BufferStrategy;
+
+/**
+ * A double-buffering capability descriptor. This class exposes
+ * details about the double-buffering algorithms used by image
+ * buffers.
+ *
+ * BufferCapabilities represents algorithms that involve at least two
+ * buffers but it can also specify so-called "multi-buffer" schemes
+ * involving more than two buffers. This class describes the
+ * capabilities of the front and back buffers as well as the results
+ * of "flipping" -- that is, what happens when an image is transferred
+ * from the back buffer to the front buffer.
+ *
+ * Flipping may or may not be supported or may be supported only in
+ * fullscreen mode. If it is not supported then "blitting" is implied
+ * -- that is, the contents of the back buffer are copied using a fast
+ * block transfer operation from the back buffer to the front buffer.
+ *
+ * The front buffer is the one that is displayed.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ *
+ * @see BufferStrategy#getCapabilities()
+ * @see GraphicsConfiguration#getBufferCapabilities()
+ *
+ * @since 1.4
+ */
+public class BufferCapabilities implements Cloneable
+{
+ /**
+ * A type-safe enumeration of buffer flipping results.
+ *
+ * @see AttributeValue
+ */
+ public static final class FlipContents extends AttributeValue
+ {
+ /**
+ * The names of the different flipping results.
+ */
+ private static final String[] NAMES
+ = { "undefined", "background", "prior", "copied" };
+
+ /**
+ * The contents of the back buffer are undefined after flipping.
+ */
+ public static final FlipContents UNDEFINED = new FlipContents(0);
+
+ /**
+ * The back buffer is cleared with the background color after
+ * flipping.
+ */
+ public static final FlipContents BACKGROUND = new FlipContents(1);
+
+ /**
+ * The back buffer contains the pre-flipping contents of the front
+ * buffer after flipping. In other words a true "flip" has been
+ * performed.
+ */
+ public static final FlipContents PRIOR = new FlipContents(2);
+
+ /**
+ * The back buffer has the same contents as the front buffer after
+ * flipping.
+ */
+ public static final FlipContents COPIED = new FlipContents(3);
+
+ /**
+ * Create a new flipping result descriptor.
+ *
+ * @param value the enumeration value
+ */
+ private FlipContents(int value)
+ {
+ super(value, NAMES);
+ }
+ }
+
+ /**
+ * Front buffer capabilities descriptor.
+ */
+ private final ImageCapabilities front;
+
+ /**
+ * Back buffer capabilities descriptor.
+ */
+ private final ImageCapabilities back;
+
+ /**
+ * Describes the results of a "flip" operation.
+ */
+ private final FlipContents flip;
+
+ /**
+ * Creates a buffer capabilities object.
+ *
+ * @param frontCaps front buffer capabilities descriptor
+ * @param backCaps back buffer capabilities descriptor
+ * @param flip the results of a flip operation or null if
+ * flipping is not supported
+ *
+ * @exception IllegalArgumentException if frontCaps or backCaps is
+ * null
+ */
+ public BufferCapabilities(ImageCapabilities frontCaps,
+ ImageCapabilities backCaps,
+ FlipContents flip)
+ {
+ if (frontCaps == null || backCaps == null)
+ throw new IllegalArgumentException();
+ this.front = frontCaps;
+ this.back = backCaps;
+ this.flip = flip;
+ }
+
+ /**
+ * Retrieve the front buffer's image capabilities.
+ *
+ * @return the front buffer's image capabilities
+ */
+ public ImageCapabilities getFrontBufferCapabilities()
+ {
+ return front;
+ }
+
+ /**
+ * Retrieve the back buffer's image capabilities.
+ *
+ * @return the back buffer's image capabilities
+ */
+ public ImageCapabilities getBackBufferCapabilities()
+ {
+ return back;
+ }
+
+ /**
+ * Return whether or not flipping is supported.
+ *
+ * @return true if flipping is supported, false otherwise
+ */
+ public boolean isPageFlipping()
+ {
+ return flip != null;
+ }
+
+ /**
+ * Retrieve the result of a flipping operation. If this method
+ * returns null then flipping is not supported. This implies that
+ * "blitting", a fast block transfer, is used to copy the contents
+ * of the back buffer to the front buffer. Other possible return
+ * values are:
+ * <ul>
+ * <li><code>FlipContents.UNDEFINED</code> the contents of the
+ * back buffer are undefined after flipping.</li>
+ * <li><code>FlipContents.BACKGROUND</code> the contents of the
+ * back buffer are cleared to the background color after
+ * flipping.</li>
+ * <li><code>FlipContents.PRIOR</code> the back buffer contains
+ * the pre-flipping contents of the front * buffer after
+ * flipping.</li>
+ * <li><code>FlipContents.COPIED</code> the back buffer has the
+ * same contents as the front buffer after flipping.</li>
+ * </ul>
+ *
+ * @return the result of a flipping operation or null if flipping is
+ * not supported
+ */
+ public FlipContents getFlipContents()
+ {
+ return flip;
+ }
+
+ /**
+ * Returns true if flipping is only supported in fullscreen mode.
+ *
+ * @return true if flipping is only supported in fullscreen mode,
+ * false otherwise
+ */
+ public boolean isFullScreenRequired()
+ {
+ return true;
+ }
+
+ /**
+ * Returns true if flipping can involve more than two buffers. One
+ * or more intermediate buffers may be available in addition to the
+ * front and back buffers.
+ *
+ * @return true if there are more than two buffers available for
+ * flipping, false otherwise
+ */
+ public boolean isMultiBufferAvailable()
+ {
+ return false;
+ }
+
+ /**
+ * Clone this buffering capability descriptor.
+ *
+ * @return a clone of this buffer capability descriptor
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e);
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/Button.java b/libjava/classpath/java/awt/Button.java
new file mode 100644
index 0000000..90be1e5
--- /dev/null
+++ b/libjava/classpath/java/awt/Button.java
@@ -0,0 +1,466 @@
+/* Button.java -- AWT button widget
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.peer.ButtonPeer;
+import java.lang.reflect.Array;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleValue;
+
+/**
+ * This class provides a button widget for the AWT.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ */
+public class Button extends Component
+ implements java.io.Serializable, Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+// FIXME: Need readObject/writeObject for serialization
+
+// Serialization version constant
+private static final long serialVersionUID = -8774683716313001058L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The action command name for this button.
+ * This is package-private to avoid an accessor method.
+ */
+String actionCommand;
+
+/**
+ * @serial The label for this button.
+ * This is package-private to avoid an accessor method.
+ */
+String label;
+
+// List of ActionListeners for this class.
+private transient ActionListener action_listeners;
+
+ /*
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_button_number;
+
+ protected class AccessibleAWTButton extends AccessibleAWTComponent
+ implements AccessibleAction, AccessibleValue
+ {
+ protected AccessibleAWTButton()
+ {
+ // Do nothing here.
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
+ */
+ public int getAccessibleActionCount()
+ {
+ // Only 1 action possible
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ // JDK 1.4.2 returns the string "click" for action 0. However, the API
+ // docs don't say what the string to be returned is, beyond being a
+ // description of the action. So we return the same thing for
+ // compatibility with 1.4.2.
+ if (i == 0)
+ return "click";
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ if (i != 0)
+ return false;
+ processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
+ return true;
+ }
+
+ public String getAccessibleName()
+ {
+ return label;
+ }
+
+ public AccessibleAction getAccessibleAction()
+ {
+ return this;
+ }
+
+ public AccessibleValue getAccessibleValue()
+ {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
+ */
+ public Number getCurrentAccessibleValue()
+ {
+ // Docs say return 1 if selected, but buttons can't be selected, right?
+ return new Integer(0);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
+ */
+ public boolean setCurrentAccessibleValue(Number number)
+ {
+ // Since there's no selection with buttons, we're ignoring this.
+ // TODO someone who knows shoulw check this.
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
+ */
+ public Number getMinimumAccessibleValue()
+ {
+ return new Integer(0);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
+ */
+ public Number getMaximumAccessibleValue()
+ {
+ return new Integer(0);
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.PUSH_BUTTON;
+ }
+ }
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>Button</code> with no label.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true
+ */
+public
+Button()
+{
+ this("");
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Button</code> with the specified
+ * label. The action command name is also initialized to this value.
+ *
+ * @param label The label to display on the button.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true
+ */
+public
+Button(String label)
+{
+ this.label = label;
+ actionCommand = label;
+
+ if (GraphicsEnvironment.isHeadless ())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Returns the label for this button.
+ *
+ * @return The label for this button.
+ */
+public String
+getLabel()
+{
+ return(label);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the label for this button to the specified value.
+ *
+ * @param label The new label for this button.
+ */
+public synchronized void
+setLabel(String label)
+{
+ this.label = label;
+ actionCommand = label;
+ if (peer != null)
+ {
+ ButtonPeer bp = (ButtonPeer) peer;
+ bp.setLabel (label);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the action command name for this button.
+ *
+ * @return The action command name for this button.
+ */
+public String
+getActionCommand()
+{
+ return(actionCommand);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the action command name for this button to the specified value.
+ *
+ * @param actionCommand The new action command name.
+ */
+public void
+setActionCommand(String actionCommand)
+{
+ this.actionCommand = actionCommand == null ? label : actionCommand;
+}
+
+/*************************************************************************/
+
+/**
+ * Adds a new entry to the list of listeners that will receive
+ * action events from this button.
+ *
+ * @param listener The listener to add.
+ */
+public synchronized void
+addActionListener(ActionListener listener)
+{
+ action_listeners = AWTEventMulticaster.add(action_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified listener from the list of listeners that will
+ * receive action events from this button.
+ *
+ * @param listener The listener to remove.
+ */
+public synchronized void
+removeActionListener(ActionListener listener)
+{
+ action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
+}
+
+ /**
+ * Returns all added <code>ActionListener</code> objects.
+ *
+ * @return an array of listeners
+ *
+ * @since 1.4
+ */
+ public synchronized ActionListener[] getActionListeners()
+ {
+ return (ActionListener[])
+ AWTEventMulticaster.getListeners(action_listeners,
+ ActionListener.class);
+ }
+
+/**
+ * Returns all registered EventListers of the given listenerType.
+ * listenerType must be a subclass of EventListener, or a
+ * ClassClassException is thrown.
+ *
+ * @param listenerType the listener type to return
+ *
+ * @return an array of listeners
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements @see java.util.EventListener.
+ *
+ * @since 1.3
+ */
+ public EventListener[] getListeners(Class listenerType)
+ {
+ if (listenerType == ActionListener.class)
+ return getActionListeners();
+ return (EventListener[]) Array.newInstance(listenerType, 0);
+ }
+
+/*************************************************************************/
+
+/**
+ * Notifies this button that it should create its native peer object.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createButton (this);
+ super.addNotify();
+}
+
+/*************************************************************************/
+
+/**
+ * Processes an event for this button. If the specified event is an
+ * instance of <code>ActionEvent</code>, then the
+ * <code>processActionEvent()</code> method is called to dispatch it
+ * to any registered listeners. Otherwise, the superclass method
+ * will be invoked. Note that this method will not be called at all
+ * unless <code>ActionEvent</code>'s are enabled. This will be done
+ * implicitly if any listeners are added.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ if (event instanceof ActionEvent)
+ processActionEvent((ActionEvent)event);
+ else
+ super.processEvent(event);
+}
+
+/*************************************************************************/
+
+/**
+ * This method dispatches an action event for this button to any
+ * registered listeners.
+ *
+ * @param event The event to process.
+ */
+protected void
+processActionEvent(ActionEvent event)
+{
+ if (action_listeners != null)
+ action_listeners.actionPerformed(event);
+}
+
+void
+dispatchEventImpl(AWTEvent e)
+{
+ if (e.id <= ActionEvent.ACTION_LAST
+ && e.id >= ActionEvent.ACTION_FIRST
+ && (action_listeners != null
+ || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this button.
+ *
+ * @return A debugging string for this button.
+ */
+protected String
+paramString()
+{
+ return getName () + "," + getX () + "," + getY () + ","
+ + getWidth () + "x" + getHeight () + ",label=" + getLabel ();
+}
+
+/**
+ * Gets the AccessibleContext associated with this <code>Button</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+public AccessibleContext getAccessibleContext()
+{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTButton();
+ return accessibleContext;
+}
+
+ /**
+ * Generate a unique name for this button.
+ *
+ * @return A unique name for this button.
+ */
+ String generateName ()
+ {
+ return "button" + getUniqueLong ();
+ }
+
+ private static synchronized long getUniqueLong ()
+ {
+ return next_button_number++;
+ }
+
+} // class Button
+
diff --git a/libjava/classpath/java/awt/Canvas.java b/libjava/classpath/java/awt/Canvas.java
new file mode 100644
index 0000000..fe2f854
--- /dev/null
+++ b/libjava/classpath/java/awt/Canvas.java
@@ -0,0 +1,354 @@
+/* Canvas.java --
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.BufferStrategy;
+import java.awt.peer.ComponentPeer;
+import java.io.Serializable;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * The <code>Canvas</code> component provides a blank rectangular
+ * area, which the client application can use for drawing and for
+ * capturing events. By overriding the <code>paint()</code> method,
+ * the canvas can be used for anything from simple line drawings to
+ * full-scale custom components.
+ *
+ * @author Original author unknown
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.0
+ */
+
+public class Canvas
+ extends Component
+ implements Serializable, Accessible
+{
+
+ /**
+ * Compatible with Sun's JDK.
+ */
+ private static final long serialVersionUID = -2284879212465893870L;
+
+ /**
+ * The graphics configuration associated with the canvas.
+ */
+ transient GraphicsConfiguration graphicsConfiguration;
+
+ /**
+ * The buffer strategy associated with this canvas.
+ */
+ transient BufferStrategy bufferStrategy;
+
+ /**
+ * Initializes a new instance of <code>Canvas</code>.
+ */
+ public Canvas()
+ {
+ }
+
+ /**
+ * Initializes a new instance of <code>Canvas</code>
+ * with the supplied graphics configuration.
+ *
+ * @param graphicsConfiguration the graphics configuration to use
+ * for this particular canvas.
+ */
+ public Canvas(GraphicsConfiguration graphicsConfiguration)
+ {
+ this.graphicsConfiguration = graphicsConfiguration;
+ }
+
+ GraphicsConfiguration getGraphicsConfigurationImpl()
+ {
+ if (graphicsConfiguration != null)
+ return graphicsConfiguration;
+ return super.getGraphicsConfigurationImpl();
+ }
+
+ /**
+ * Creates the native peer for this object.
+ */
+ public void addNotify()
+ {
+ if (peer == null)
+ peer = (ComponentPeer) getToolkit().createCanvas(this);
+ super.addNotify();
+ }
+
+ /**
+ * Repaints the canvas window. This method should be overridden by
+ * a subclass to do something useful, as this method simply paints
+ * the window with the background color.
+ *
+ * @param gfx the <code>Graphics</code> to use for painting
+ */
+ public void paint(Graphics gfx)
+ {
+ /* This implementation doesn't make much sense since the filling
+ of background color is guaranteed for heavyweight components
+ such as this. But there's no need to worry, since paint() is
+ usually overridden anyway. */
+ gfx.setColor(getBackground());
+ Dimension size = getSize();
+ gfx.fillRect(0, 0, size.width, size.height);
+ }
+
+ /**
+ * This class provides accessibility support for the canvas.
+ */
+ protected class AccessibleAWTCanvas
+ extends AccessibleAWTComponent
+ {
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = -6325592262103146699L;
+
+ /**
+ * Constructor for the accessible canvas.
+ */
+ protected AccessibleAWTCanvas()
+ {
+ }
+
+ /**
+ * Returns the accessible role for the canvas.
+ *
+ * @return an instance of <code>AccessibleRole</code>, describing
+ * the role of the canvas.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.CANVAS;
+ }
+
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>Canvas</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTCanvas();
+ return accessibleContext;
+ }
+
+ /**
+ * A BltBufferStrategy for canvases.
+ */
+ private class CanvasBltBufferStrategy extends BltBufferStrategy
+ {
+ /**
+ * Creates a block transfer strategy for this canvas.
+ *
+ * @param numBuffers the number of buffers in this strategy
+ * @param accelerated true if the buffer should be accelerated,
+ * false otherwise
+ */
+ CanvasBltBufferStrategy(int numBuffers, boolean accelerated)
+ {
+ super(numBuffers,
+ new BufferCapabilities(new ImageCapabilities(accelerated),
+ new ImageCapabilities(accelerated),
+ BufferCapabilities.FlipContents.COPIED));
+ }
+ }
+
+ /**
+ * A FlipBufferStrategy for canvases.
+ */
+ private class CanvasFlipBufferStrategy extends FlipBufferStrategy
+ {
+ /**
+ * Creates a flip buffer strategy for this canvas.
+ *
+ * @param numBuffers the number of buffers in this strategy
+ *
+ * @throws AWTException if the requested number of buffers is not
+ * supported
+ */
+ CanvasFlipBufferStrategy(int numBuffers)
+ throws AWTException
+ {
+ super(numBuffers,
+ new BufferCapabilities(new ImageCapabilities(true),
+ new ImageCapabilities(true),
+ BufferCapabilities.FlipContents.COPIED));
+ }
+ }
+
+ /**
+ * Creates a buffering strategy that manages how this canvas is
+ * repainted. This method attempts to create the optimum strategy
+ * based on the desired number of buffers. Hardware or software
+ * acceleration may be used.
+ *
+ * createBufferStrategy attempts different levels of optimization,
+ * but guarantees that some strategy with the requested number of
+ * buffers will be created even if it is not optimal. First it
+ * attempts to create a page flipping strategy, then an accelerated
+ * blitting strategy, then an unaccelerated blitting strategy.
+ *
+ * Calling this method causes any existing buffer strategy to be
+ * destroyed.
+ *
+ * @param numBuffers the number of buffers in this strategy
+ *
+ * @throws IllegalArgumentException if requested number of buffers
+ * is less than one
+ * @throws IllegalStateException if this canvas is not displayable
+ *
+ * @since 1.4
+ */
+ public void createBufferStrategy(int numBuffers)
+ {
+ if (numBuffers < 1)
+ throw new IllegalArgumentException("Canvas.createBufferStrategy: number"
+ + " of buffers is less than one");
+
+ if (!isDisplayable())
+ throw new IllegalStateException("Canvas.createBufferStrategy: canvas is"
+ + " not displayable");
+
+ BufferStrategy newStrategy = null;
+
+ // try a flipping strategy
+ try
+ {
+ newStrategy = new CanvasFlipBufferStrategy(numBuffers);
+ }
+ catch (AWTException e)
+ {
+ }
+
+ // fall back to an accelerated blitting strategy
+ if (newStrategy == null)
+ newStrategy = new CanvasBltBufferStrategy(numBuffers, true);
+
+ bufferStrategy = newStrategy;
+ }
+
+ /**
+ * Creates a buffering strategy that manages how this canvas is
+ * repainted. This method attempts to create a strategy based on
+ * the specified capabilities and throws an exception if the
+ * requested strategy is not supported.
+ *
+ * Calling this method causes any existing buffer strategy to be
+ * destroyed.
+ *
+ * @param numBuffers the number of buffers in this strategy
+ * @param caps the requested buffering capabilities
+ *
+ * @throws AWTException if the requested capabilities are not
+ * supported
+ * @throws IllegalArgumentException if requested number of buffers
+ * is less than one or if caps is null
+ *
+ * @since 1.4
+ */
+ public void createBufferStrategy(int numBuffers,
+ BufferCapabilities caps)
+ {
+ if (numBuffers < 1)
+ throw new IllegalArgumentException("Canvas.createBufferStrategy: number"
+ + " of buffers is less than one");
+
+ if (caps == null)
+ throw new IllegalArgumentException("Canvas.createBufferStrategy:"
+ + " capabilities object is null");
+
+ // a flipping strategy was requested
+ if (caps.isPageFlipping())
+ {
+ try
+ {
+ bufferStrategy = new CanvasFlipBufferStrategy(numBuffers);
+ }
+ catch (AWTException e)
+ {
+ }
+ }
+ else
+ bufferStrategy = new CanvasBltBufferStrategy(numBuffers, true);
+ }
+
+ /**
+ * Returns the buffer strategy used by the canvas.
+ *
+ * @return the buffer strategy.
+ * @since 1.4
+ */
+ public BufferStrategy getBufferStrategy()
+ {
+ return bufferStrategy;
+ }
+
+ /**
+ * Updates the canvas in response to a request to
+ * <code>repaint()</code> it. The canvas is cleared
+ * with the current background colour, before <code>paint()</code>
+ * is called to add the new contents. Subclasses
+ * which override this method should either call this
+ * method via <code>super.update(graphics)</code> or re-implement
+ * this behaviour, so as to ensure that the canvas is
+ * clear before painting takes place.
+ *
+ * @param graphics the graphics context.
+ */
+ public void update(Graphics graphics)
+ {
+ Dimension size;
+
+ /* Clear the canvas */
+ size = getSize();
+ graphics.clearRect(0, 0, size.width, size.height);
+ /* Call the paint method */
+ paint(graphics);
+ }
+}
diff --git a/libjava/classpath/java/awt/CardLayout.java b/libjava/classpath/java/awt/CardLayout.java
new file mode 100644
index 0000000..8582c5f0
--- /dev/null
+++ b/libjava/classpath/java/awt/CardLayout.java
@@ -0,0 +1,483 @@
+/* CardLayout.java -- Card-based layout engine
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * This class implements a card-based layout scheme. Each included
+ * component is treated as a card. Only one card can be shown at a
+ * time. This class includes methods for changing which card is
+ * shown.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class CardLayout implements LayoutManager2, Serializable
+{
+ private static final long serialVersionUID = -4328196481005934313L;
+
+ /**
+ * Initializes a new instance of <code>CardLayout</code> with horizontal
+ * and vertical gaps of 0.
+ */
+ public CardLayout ()
+ {
+ this (0, 0);
+ }
+
+ /**
+ * Create a new <code>CardLayout</code> object with the specified
+ * horizontal and vertical gaps.
+ *
+ * @param hgap The horizontal gap
+ * @param vgap The vertical gap
+ */
+ public CardLayout (int hgap, int vgap)
+ {
+ this.hgap = hgap;
+ this.vgap = vgap;
+ this.tab = new Hashtable ();
+ }
+
+ /**
+ * Add a new component to the layout. The constraint must be a
+ * string which is used to name the component. This string can
+ * later be used to refer to the particular component.
+ *
+ * @param comp The component to add
+ * @param constraints The name by which the component can later be called
+ *
+ * @exception IllegalArgumentException If `constraints' is not a
+ * <code>String</code>
+ */
+ public void addLayoutComponent (Component comp, Object constraints)
+ {
+ if (! (constraints instanceof String))
+ throw new IllegalArgumentException ("Object " + constraints
+ + " is not a string");
+ addLayoutComponent ((String) constraints, comp);
+ }
+
+ /**
+ * Add a new component to the layout. The name can be used later
+ * to refer to the component.
+ *
+ * @param name The name by which the component can later be called
+ * @param comp The component to add
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>addLayoutComponent(Component, Object)</code>.
+ */
+ public void addLayoutComponent (String name, Component comp)
+ {
+ tab.put (name, comp);
+ // First component added is the default component.
+ comp.setVisible(tab.size() == 1);
+ }
+
+ /**
+ * Cause the first component in the container to be displayed.
+ *
+ * @param parent The parent container
+ */
+ public void first (Container parent)
+ {
+ gotoComponent (parent, FIRST);
+ }
+
+ /**
+ * Return this layout manager's horizontal gap.
+ *
+ * @return the horizontal gap
+ */
+ public int getHgap ()
+ {
+ return hgap;
+ }
+
+ /**
+ * Return this layout manager's x alignment. This method always
+ * returns Component.CENTER_ALIGNMENT.
+ *
+ * @param parent Container using this layout manager instance
+ *
+ * @return the x-axis alignment
+ */
+ public float getLayoutAlignmentX (Container parent)
+ {
+ return Component.CENTER_ALIGNMENT;
+ }
+
+ /**
+ * Returns this layout manager's y alignment. This method always
+ * returns Component.CENTER_ALIGNMENT.
+ *
+ * @param parent Container using this layout manager instance
+ *
+ * @return the y-axis alignment
+ */
+ public float getLayoutAlignmentY (Container parent)
+ {
+ return Component.CENTER_ALIGNMENT;
+ }
+
+ /**
+ * Return this layout manager's vertical gap.
+ *
+ * @return the vertical gap
+ */
+ public int getVgap ()
+ {
+ return vgap;
+ }
+
+ /**
+ * Invalidate this layout manager's state.
+ */
+ public void invalidateLayout (Container target)
+ {
+ // Do nothing.
+ }
+
+ /**
+ * Cause the last component in the container to be displayed.
+ *
+ * @param parent The parent container
+ */
+ public void last (Container parent)
+ {
+ gotoComponent (parent, LAST);
+ }
+
+ /**
+ * Lays out the container. This is done by resizing the child components
+ * to be the same size as the parent, less insets and gaps.
+ *
+ * @param parent The parent container.
+ */
+ public void layoutContainer (Container parent)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int width = parent.width;
+ int height = parent.height;
+
+ Insets ins = parent.getInsets ();
+
+ int num = parent.ncomponents;
+ Component[] comps = parent.component;
+
+ int x = ins.left + hgap;
+ int y = ins.top + vgap;
+ width = width - 2 * hgap - ins.left - ins.right;
+ height = height - 2 * vgap - ins.top - ins.bottom;
+
+ for (int i = 0; i < num; ++i)
+ comps[i].setBounds (x, y, width, height);
+ }
+ }
+
+ /**
+ * Get the maximum layout size of the container.
+ *
+ * @param target The parent container
+ *
+ * @return the maximum layout size
+ */
+ public Dimension maximumLayoutSize (Container target)
+ {
+ // The JCL says that this returns Integer.MAX_VALUE for both
+ // dimensions. But that just seems wrong to me.
+ return getSize (target, MAX);
+ }
+
+ /**
+ * Get the minimum layout size of the container.
+ *
+ * @param target The parent container
+ *
+ * @return the minimum layout size
+ */
+ public Dimension minimumLayoutSize (Container target)
+ {
+ return getSize (target, MIN);
+ }
+
+ /**
+ * Cause the next component in the container to be displayed. If
+ * this current card is the last one in the deck, the first
+ * component is displayed.
+ *
+ * @param parent The parent container
+ */
+ public void next (Container parent)
+ {
+ gotoComponent (parent, NEXT);
+ }
+
+ /**
+ * Get the preferred layout size of the container.
+ *
+ * @param parent The parent container
+ *
+ * @return the preferred layout size
+ */
+ public Dimension preferredLayoutSize (Container parent)
+ {
+ return getSize (parent, PREF);
+ }
+
+ /**
+ * Cause the previous component in the container to be displayed.
+ * If this current card is the first one in the deck, the last
+ * component is displayed.
+ *
+ * @param parent The parent container
+ */
+ public void previous (Container parent)
+ {
+ gotoComponent (parent, PREV);
+ }
+
+ /**
+ * Remove the indicated component from this layout manager.
+ *
+ * @param comp The component to remove
+ */
+ public void removeLayoutComponent (Component comp)
+ {
+ Enumeration e = tab.keys ();
+ while (e.hasMoreElements ())
+ {
+ Object key = e.nextElement ();
+ if (tab.get (key) == comp)
+ {
+ tab.remove (key);
+ Container parent = comp.getParent();
+ next(parent);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Set this layout manager's horizontal gap.
+ *
+ * @param hgap The new gap
+ */
+ public void setHgap (int hgap)
+ {
+ this.hgap = hgap;
+ }
+
+ /**
+ * Set this layout manager's vertical gap.
+ *
+ * @param vgap The new gap
+ */
+ public void setVgap (int vgap)
+ {
+ this.vgap = vgap;
+ }
+
+ /**
+ * Cause the named component to be shown. If the component name is
+ * unknown, this method does nothing.
+ *
+ * @param parent The parent container
+ * @param name The name of the component to show
+ */
+ public void show (Container parent, String name)
+ {
+ Object target = tab.get (name);
+ if (target != null)
+ {
+ int num = parent.ncomponents;
+ // This is more efficient than calling getComponents().
+ Component[] comps = parent.component;
+ for (int i = 0; i < num; ++i)
+ {
+ if (comps[i].isVisible())
+ {
+ if (target == comps[i])
+ return;
+ comps[i].setVisible (false);
+ }
+ }
+ ((Component) target).setVisible (true);
+ }
+ }
+
+ /**
+ * Returns a string representation of this layout manager.
+ *
+ * @return A string representation of this object.
+ */
+ public String toString ()
+ {
+ return getClass ().getName () + "[" + hgap + "," + vgap + "]";
+ }
+
+ /**
+ * This implements first(), last(), next(), and previous().
+ *
+ * @param parent The parent container
+ * @param what The type of goto: FIRST, LAST, NEXT or PREV
+ */
+ private void gotoComponent (Container parent, int what)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int num = parent.ncomponents;
+ // This is more efficient than calling getComponents().
+ Component[] comps = parent.component;
+
+ if (num == 1)
+ {
+ comps[0].setVisible(true);
+ return;
+ }
+
+ int choice = -1;
+
+ if (what == FIRST)
+ choice = 0;
+ else if (what == LAST)
+ choice = num - 1;
+
+ for (int i = 0; i < num; ++i)
+ {
+ if (comps[i].isVisible ())
+ {
+ if (what == NEXT)
+ {
+ choice = i + 1;
+ if (choice == num)
+ choice = 0;
+ }
+ else if (what == PREV)
+ {
+ choice = i - 1;
+ if (choice < 0)
+ choice = num - 1;
+ }
+ else if (choice == i)
+ {
+ // Do nothing if we're already looking at the right
+ // component.
+ return;
+ }
+ comps[i].setVisible (false);
+
+ if (choice >= 0)
+ break;
+ }
+ }
+
+ if (choice >= 0 && choice < num)
+ comps[choice].setVisible (true);
+ }
+ }
+
+ // Compute the size according to WHAT.
+ private Dimension getSize (Container parent, int what)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int w = 0, h = 0, num = parent.ncomponents;
+ Component[] comps = parent.component;
+
+ for (int i = 0; i < num; ++i)
+ {
+ Dimension d;
+
+ if (what == MIN)
+ d = comps[i].getMinimumSize ();
+ else if (what == MAX)
+ d = comps[i].getMaximumSize ();
+ else
+ d = comps[i].getPreferredSize ();
+
+ w = Math.max (d.width, w);
+ h = Math.max (d.height, h);
+ }
+
+ Insets i = parent.getInsets ();
+ w += 2 * hgap + i.right + i.left;
+ h += 2 * vgap + i.bottom + i.top;
+
+ // Handle overflow.
+ if (w < 0)
+ w = Integer.MAX_VALUE;
+ if (h < 0)
+ h = Integer.MAX_VALUE;
+
+ return new Dimension (w, h);
+ }
+ }
+
+ /**
+ * @serial Horizontal gap value.
+ */
+ private int hgap;
+
+ /**
+ * @serial Vertical gap value.
+ */
+ private int vgap;
+
+ /**
+ * @serial Table of named components.
+ */
+ private Hashtable tab;
+
+ // These constants are used by the private gotoComponent method.
+ private static final int FIRST = 0;
+ private static final int LAST = 1;
+ private static final int NEXT = 2;
+ private static final int PREV = 3;
+
+ // These constants are used by the private getSize method.
+ private static final int MIN = 0;
+ private static final int MAX = 1;
+ private static final int PREF = 2;
+}
diff --git a/libjava/classpath/java/awt/Checkbox.java b/libjava/classpath/java/awt/Checkbox.java
new file mode 100644
index 0000000..cd39ad4
--- /dev/null
+++ b/libjava/classpath/java/awt/Checkbox.java
@@ -0,0 +1,649 @@
+/* Checkbox.java -- An AWT checkbox widget
+ Copyright (C) 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.peer.CheckboxPeer;
+import java.io.Serializable;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleValue;
+
+/**
+ * This class implements a component which has an on/off state. Two
+ * or more Checkboxes can be grouped by a CheckboxGroup.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@redhat.com)
+ */
+public class Checkbox extends Component
+ implements ItemSelectable, Accessible, Serializable
+{
+
+// FIXME: Need readObject/writeObject for this.
+
+/*
+ * Static Variables
+ */
+
+// Serialization Constant
+private static final long serialVersionUID = 7270714317450821763L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The checkbox group for this checkbox.
+ */
+private CheckboxGroup group;
+
+/**
+ * @serial The label on this checkbox.
+ */
+private String label;
+
+/**
+ * @serial The state of this checkbox.
+ * This is package-private to avoid an accessor method.
+ */
+boolean state;
+
+// The list of listeners for this object.
+private transient ItemListener item_listeners;
+
+ /*
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_checkbox_number;
+
+/**
+ * This class provides accessibility support for the
+ * checkbox.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+protected class AccessibleAWTCheckbox
+ extends AccessibleAWTComponent
+ implements ItemListener, AccessibleAction, AccessibleValue
+{
+ /**
+ * Serialization constant to match JDK 1.5
+ */
+ private static final long serialVersionUID = 7881579233144754107L;
+
+ /**
+ * Default constructor which simply calls the
+ * super class for generic component accessibility
+ * handling.
+ */
+ public AccessibleAWTCheckbox()
+ {
+ super();
+ }
+
+ /**
+ * Captures changes to the state of the checkbox and
+ * fires appropriate accessible property change events.
+ *
+ * @param event the event fired.
+ * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
+ */
+ public void itemStateChanged(ItemEvent event)
+ {
+ firePropertyChange(ACCESSIBLE_STATE_PROPERTY,
+ state ? null : AccessibleState.CHECKED,
+ state ? AccessibleState.CHECKED : null);
+ }
+
+ /**
+ * Returns an implementation of the <code>AccessibleAction</code>
+ * interface for this accessible object. In this case, the
+ * current instance is simply returned (with a more appropriate
+ * type), as it also implements the accessible action as well as
+ * the context.
+ *
+ * @return the accessible action associated with this context.
+ * @see javax.accessibility.AccessibleAction
+ */
+ public AccessibleAction getAccessibleAction()
+ {
+ return this;
+ }
+
+ /**
+ * Returns an implementation of the <code>AccessibleValue</code>
+ * interface for this accessible object. In this case, the
+ * current instance is simply returned (with a more appropriate
+ * type), as it also implements the accessible value as well as
+ * the context.
+ *
+ * @return the accessible value associated with this context.
+ * @see javax.accessibility.AccessibleValue
+ */
+ public AccessibleValue getAccessibleValue()
+ {
+ return this;
+ }
+
+ /*
+ * The following methods are implemented in the JDK (up to
+ * 1.5) as stubs. We do likewise here.
+ */
+
+ /**
+ * Returns the number of actions associated with this accessible
+ * object. This default implementation returns 0.
+ *
+ * @return the number of accessible actions available.
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
+ */
+ public int getAccessibleActionCount()
+ {
+ // 1.4.1 and 1.5 do this
+ return 0;
+ }
+
+ /**
+ * Returns a description of the action with the supplied id.
+ * This default implementation always returns null.
+ *
+ * @param i the id of the action whose description should be
+ * retrieved.
+ * @return a <code>String</code> describing the action.
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ // 1.5 does this
+ return null;
+ }
+
+ /**
+ * Executes the action with the specified id. This
+ * default implementation simply returns false.
+ *
+ * @param i the id of the action to perform.
+ * @return true if the action was performed.
+ * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ // 1.5 does this
+ return false;
+ }
+
+ /**
+ * Returns the current value of this accessible object.
+ * If no value has been set, null is returned. This
+ * default implementation always returns null, regardless.
+ *
+ * @return the numeric value of this object, or null if
+ * no value has been set.
+ * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
+ */
+ public Number getCurrentAccessibleValue()
+ {
+ // 1.5 does this
+ return null;
+ }
+
+ /**
+ * Sets the current value of this accessible object
+ * to that supplied. In this default implementation,
+ * the value is never set and the method always returns
+ * false.
+ *
+ * @param number the new accessible value.
+ * @return true if the value was set.
+ * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
+ */
+ public boolean setCurrentAccessibleValue(Number number)
+ {
+ // 1.5 does this
+ return false;
+ }
+
+ /**
+ * Returns the minimum acceptable accessible value used
+ * by this object, or null if no minimum value exists.
+ * This default implementation always returns null.
+ *
+ * @return the minimum acceptable accessible value, or null
+ * if there is no minimum.
+ * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
+ */
+ public Number getMinimumAccessibleValue()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the maximum acceptable accessible value used
+ * by this object, or null if no maximum value exists.
+ * This default implementation always returns null.
+ *
+ * @return the maximum acceptable accessible value, or null
+ * if there is no maximum.
+ * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
+ */
+ public Number getMaximumAccessibleValue()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the role of this accessible object.
+ *
+ * @return the instance of <code>AccessibleRole</code>,
+ * which describes this object.
+ * @see javax.accessibility.AccessibleRole
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.CHECK_BOX;
+ }
+
+ /**
+ * Returns the state set of this accessible object.
+ *
+ * @return a set of <code>AccessibleState</code>s
+ * which represent the current state of the
+ * accessible object.
+ * @see javax.accessibility.AccessibleState
+ * @see javax.accessibility.AccessibleStateSet
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet set = super.getAccessibleStateSet();
+ if (state)
+ set.add(AccessibleState.CHECKED);
+ return set;
+ }
+
+}
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>Checkbox</code> with no label,
+ * an initial state of off, and that is not part of any checkbox group.
+ */
+public
+Checkbox()
+{
+ this("", false, null);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Checkbox</code> with the specified
+ * label, an initial state of off, and that is not part of any checkbox
+ * group.
+ *
+ * @param label The label for this checkbox.
+ */
+public
+Checkbox(String label)
+{
+ this(label, false, null);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Checkbox</code> with the specified
+ * label and initial state, and that is not part of any checkbox
+ * group.
+ *
+ * @param label The label for this checkbox.
+ * @param state The initial state of the checkbox, <code>true</code> for
+ * on, <code>false</code> for off.
+ */
+public
+Checkbox(String label, boolean state)
+{
+ this(label, state, null);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Checkbox</code> with the specified
+ * label, initial state, and checkbox group.
+ *
+ * @param label The label for this checkbox.
+ * @param group The checkbox group for this box, or <code>null</code>
+ * if there is no checkbox group.
+ * @param state The initial state of the checkbox, <code>true</code> for
+ * on, <code>false</code> for off.
+ */
+public
+Checkbox(String label, CheckboxGroup group, boolean state)
+{
+ this(label, state, group);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Checkbox</code> with the specified
+ * label, initial state, and checkbox group.
+ *
+ * @param label The label for this checkbox.
+ * @param state The initial state of the checkbox, <code>true</code> for
+ * on, <code>false</code> for off.
+ * @param group The checkbox group for this box, or <code>null</code>
+ * if there is no checkbox group.
+ */
+public
+Checkbox(String label, boolean state, CheckboxGroup group)
+{
+ this.label = label;
+ this.state = state;
+ this.group = group;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Returns the label for this checkbox.
+ *
+ * @return The label for this checkbox.
+ */
+public String
+getLabel()
+{
+ return(label);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the label for this checkbox to the specified value.
+ *
+ * @param label The new checkbox label.
+ */
+public synchronized void
+setLabel(String label)
+{
+ this.label = label;
+ if (peer != null)
+ {
+ CheckboxPeer cp = (CheckboxPeer) peer;
+ cp.setLabel(label);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the state of this checkbox.
+ *
+ * @return The state of this checkbox, which will be <code>true</code> for
+ * on and <code>false</code> for off.
+ */
+public boolean
+getState()
+{
+ return(state);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the state of this checkbox to the specified value.
+ *
+ * @param state The new state of the checkbox, which will be <code>true</code>
+ * for on or <code>false</code> for off.
+ */
+public synchronized void
+setState(boolean state)
+{
+ this.state = state;
+ if (peer != null)
+ {
+ CheckboxPeer cp = (CheckboxPeer) peer;
+ cp.setState (state);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns an array of length one containing the checkbox label if this
+ * checkbox is selected. Otherwise <code>null</code> is returned.
+ *
+ * @return The selection state of this checkbox.
+ */
+public Object[]
+getSelectedObjects()
+{
+ if (state == false)
+ return(null);
+
+ Object[] objs = new Object[1];
+ objs[0] = label;
+
+ return(objs);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the checkbox group this object is a member of, if any.
+ *
+ * @return This object's checkbox group, of <code>null</code> if it is
+ * not a member of any group.
+ */
+public CheckboxGroup
+getCheckboxGroup()
+{
+ return(group);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets this object's checkbox group to the specified group.
+ *
+ * @param group The new checkbox group, or <code>null</code> to make this
+ * object part of no checkbox group.
+ */
+public synchronized void
+setCheckboxGroup(CheckboxGroup group)
+{
+ this.group = group;
+ if (peer != null)
+ {
+ CheckboxPeer cp = (CheckboxPeer) peer;
+ cp.setCheckboxGroup (group);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Creates this object's native peer.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createCheckbox (this);
+ super.addNotify ();
+}
+
+ public ItemListener[] getItemListeners ()
+ {
+ return (ItemListener[])
+ AWTEventMulticaster.getListeners (item_listeners, ItemListener.class);
+ }
+
+/**
+ * Adds a new listeners to the list of registered listeners for this object.
+ *
+ * @param listener The new listener to add.
+ */
+public synchronized void
+addItemListener(ItemListener listener)
+{
+ item_listeners = AWTEventMulticaster.add(item_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes a listener from the list of registered listeners for this object.
+ *
+ * @param listener The listener to remove.
+ */
+public synchronized void
+removeItemListener(ItemListener listener)
+{
+ item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes this event by calling <code>processItemEvent()</code> if it
+ * is any instance of <code>ItemEvent</code>. Otherwise it is passed to
+ * the superclass for processing.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ if (event instanceof ItemEvent)
+ processItemEvent((ItemEvent)event);
+ else
+ super.processEvent(event);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes this event by dispatching it to any registered listeners.
+ *
+ * @param event The <code>ItemEvent</code> to process.
+ */
+protected void
+processItemEvent(ItemEvent event)
+{
+ if (item_listeners != null)
+ item_listeners.itemStateChanged(event);
+}
+
+void
+dispatchEventImpl(AWTEvent e)
+{
+ if (e.id <= ItemEvent.ITEM_LAST
+ && e.id >= ItemEvent.ITEM_FIRST
+ && (item_listeners != null
+ || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this object.
+ */
+protected String
+paramString()
+{
+ return ("label=" + label + ",state=" + state + ",group=" + group
+ + "," + super.paramString());
+}
+
+/**
+ * Gets the AccessibleContext associated with this <code>Checkbox</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+public AccessibleContext getAccessibleContext()
+{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ {
+ AccessibleAWTCheckbox ac = new AccessibleAWTCheckbox();
+ accessibleContext = ac;
+ addItemListener(ac);
+ }
+ return accessibleContext;
+}
+
+ /**
+ * Generate a unique name for this checkbox.
+ *
+ * @return A unique name for this checkbox.
+ */
+ String generateName()
+ {
+ return "checkbox" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_checkbox_number++;
+ }
+}
diff --git a/libjava/classpath/java/awt/CheckboxGroup.java b/libjava/classpath/java/awt/CheckboxGroup.java
new file mode 100644
index 0000000..31b573e
--- /dev/null
+++ b/libjava/classpath/java/awt/CheckboxGroup.java
@@ -0,0 +1,173 @@
+/* CheckboxGroup.java -- A grouping class for checkboxes.
+ Copyright (C) 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This class if for combining checkboxes into groups so that only
+ * one checkbox in the group can be selected at any one time.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@redhat.com)
+ */
+public class CheckboxGroup implements java.io.Serializable
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization constant
+private static final long serialVersionUID = 3729780091441768983L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The currently selected checkbox.
+ */
+private Checkbox selectedCheckbox;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>CheckboxGroup</code>.
+ */
+public
+CheckboxGroup()
+{
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the currently selected checkbox, or <code>null</code> if none
+ * of the checkboxes in this group are selected.
+ *
+ * @return The selected checkbox.
+ */
+public Checkbox
+getSelectedCheckbox()
+{
+ return getCurrent ();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the currently selected checkbox, or <code>null</code> if none
+ * of the checkboxes in this group are selected.
+ *
+ * @return The selected checkbox.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getSelectedCheckbox()</code>.
+ */
+public Checkbox
+getCurrent()
+{
+ return(selectedCheckbox);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the specified checkbox to be the selected on in this
+ * group, and unsets all others.
+ *
+ * @param selectedCheckbox The new selected checkbox.
+ */
+public void
+setSelectedCheckbox(Checkbox selectedCheckbox)
+{
+ setCurrent (selectedCheckbox);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the specified checkbox to be the selected on in this
+ * group, and unsets all others.
+ *
+ * @param selectedCheckbox The new selected checkbox.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>setSelectedCheckbox()</code>.
+ */
+public void
+setCurrent(Checkbox selectedCheckbox)
+{
+ if (this.selectedCheckbox != null)
+ {
+ if (this.selectedCheckbox.getCheckboxGroup() != this)
+ return;
+
+ this.selectedCheckbox.setState(false);
+ }
+
+ this.selectedCheckbox = selectedCheckbox;
+ if (selectedCheckbox != null)
+ selectedCheckbox.setState(true);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a string representation of this checkbox group.
+ *
+ * @return A string representation of this checkbox group.
+ */
+public String
+toString()
+{
+ return(getClass().getName() + "[selectedCheckbox=" + selectedCheckbox + "]");
+}
+
+} // class CheckboxGroup
+
diff --git a/libjava/classpath/java/awt/CheckboxMenuItem.java b/libjava/classpath/java/awt/CheckboxMenuItem.java
new file mode 100644
index 0000000..5e446b8
--- /dev/null
+++ b/libjava/classpath/java/awt/CheckboxMenuItem.java
@@ -0,0 +1,355 @@
+/* CheckboxMenuItem.java -- A menu option with a checkbox on it.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.peer.CheckboxMenuItemPeer;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleValue;
+
+/**
+ * This class implements a menu item that has a checkbox on it indicating
+ * the selected state of some option.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@redhat.com)
+ */
+public class CheckboxMenuItem extends MenuItem
+ implements ItemSelectable, Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization constant
+private static final long serialVersionUID = 6190621106981774043L;
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The state of the checkbox, with <code>true</code> being on and
+ * <code>false</code> being off.
+ */
+private boolean state;
+
+// List of registered ItemListeners
+private transient ItemListener item_listeners;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>CheckboxMenuItem</code> with no
+ * label and an initial state of off.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+public
+CheckboxMenuItem()
+{
+ this("", false);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>CheckboxMenuItem</code> with the
+ * specified label and an initial state of off.
+ *
+ * @param label The label of the menu item.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+public
+CheckboxMenuItem(String label)
+{
+ this(label, false);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>CheckboxMenuItem</code> with the
+ * specified label and initial state.
+ *
+ * @param label The label of the menu item.
+ * @param state The initial state of the menu item, where <code>true</code>
+ * is on, and <code>false</code> is off.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+public
+CheckboxMenuItem(String label, boolean state)
+{
+ super(label);
+ this.state = state;
+
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the state of this menu item.
+ *
+ * @return The state of this menu item.
+ */
+public boolean
+getState()
+{
+ return(state);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the state of this menu item.
+ *
+ * @param state The initial state of the menu item, where <code>true</code>
+ * is on, and <code>false</code> is off.
+ */
+public synchronized void
+setState(boolean state)
+{
+ this.state = state;
+ if (peer != null)
+ {
+ CheckboxMenuItemPeer cp = (CheckboxMenuItemPeer) peer;
+ cp.setState (state);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns an array of length 1 with the menu item label for this object
+ * if the state is on. Otherwise <code>null</code> is returned.
+ *
+ * @return An array with this menu item's label if it has a state of on,
+ * or <code>null</code> otherwise.
+ */
+public Object[]
+getSelectedObjects()
+{
+ if (state == false)
+ return(null);
+
+ Object[] obj = new Object[1];
+ obj[0] = getLabel();
+
+ return(obj);
+}
+
+/*************************************************************************/
+
+/**
+ * Create's this object's native peer
+ */
+public synchronized void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit().createCheckboxMenuItem(this);
+
+ super.addNotify ();
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified listener to the list of registered item listeners
+ * for this object.
+ *
+ * @param listener The listener to add.
+ */
+public synchronized void
+addItemListener(ItemListener listener)
+{
+ item_listeners = AWTEventMulticaster.add(item_listeners, listener);
+
+ enableEvents(AWTEvent.ITEM_EVENT_MASK);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified listener from the list of registered item
+ * listeners for this object.
+ *
+ * @param listener The listener to remove.
+ */
+public synchronized void
+removeItemListener(ItemListener listener)
+{
+ item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes the specified event by calling <code>processItemEvent()</code>
+ * if it is an instance of <code>ItemEvent</code> or calling the superclass
+ * method otherwise.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ if (event instanceof ItemEvent)
+ processItemEvent((ItemEvent)event);
+ else
+ super.processEvent(event);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes the specified event by dispatching it to any registered listeners.
+ *
+ * @param event The event to process.
+ */
+protected void
+processItemEvent(ItemEvent event)
+{
+ if (item_listeners != null)
+ item_listeners.itemStateChanged(event);
+}
+
+void
+dispatchEventImpl(AWTEvent e)
+{
+ if (e instanceof ItemEvent)
+ {
+ synchronized (this)
+ {
+ state = (((ItemEvent) e).getStateChange() == ItemEvent.SELECTED);
+ }
+ }
+
+ if (e.id <= ItemEvent.ITEM_LAST
+ && e.id >= ItemEvent.ITEM_FIRST
+ && (item_listeners != null
+ || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this object.
+ *
+ * @return A debugging string for this object.
+ */
+public String
+paramString()
+{
+ return ("label=" + getLabel() + ",state=" + state
+ + "," + super.paramString());
+}
+
+ /**
+ * Returns an array of all the objects currently registered as FooListeners
+ * upon this <code>CheckboxMenuItem</code>. FooListeners are registered using
+ * the addFooListener method.
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements java.util.EventListener.
+ */
+ public EventListener[] getListeners (Class listenerType)
+ {
+ if (listenerType == ItemListener.class)
+ return AWTEventMulticaster.getListeners (item_listeners, listenerType);
+
+ return super.getListeners (listenerType);
+ }
+
+ /**
+ * Returns an aray of all item listeners currently registered to this
+ * <code>CheckBoxMenuItem</code>.
+ */
+ public ItemListener[] getItemListeners ()
+ {
+ return (ItemListener[]) getListeners (ItemListener.class);
+ }
+
+
+ protected class AccessibleAWTCheckboxMenuItem extends AccessibleAWTMenuItem
+ implements AccessibleAction, AccessibleValue
+ {
+ // I think the base class provides the necessary implementation
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>CheckboxMenuItem</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTCheckboxMenuItem();
+ return accessibleContext;
+ }
+
+} // class CheckboxMenuItem
+
diff --git a/libjava/classpath/java/awt/Choice.java b/libjava/classpath/java/awt/Choice.java
new file mode 100644
index 0000000..5075ea9
--- /dev/null
+++ b/libjava/classpath/java/awt/Choice.java
@@ -0,0 +1,638 @@
+/* Choice.java -- Java choice button widget.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.peer.ChoicePeer;
+import java.io.Serializable;
+import java.util.EventListener;
+import java.util.Vector;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * This class implements a drop down choice list.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class Choice extends Component
+ implements ItemSelectable, Serializable, Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization constant
+private static final long serialVersionUID = -4075310674757313071L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial A list of items for the choice box, which can be <code>null</code>.
+ * This is package-private to avoid an accessor method.
+ */
+Vector pItems = new Vector();
+
+/**
+ * @serial The index of the selected item in the choice box.
+ */
+private int selectedIndex = -1;
+
+// Listener chain
+private ItemListener item_listeners;
+
+/**
+ * This class provides accessibility support for the
+ * combo box.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ protected class AccessibleAWTChoice
+ extends AccessibleAWTComponent
+ implements AccessibleAction
+ {
+
+ /**
+ * Serialization constant to match JDK 1.5
+ */
+ private static final long serialVersionUID = 7175603582428509322L;
+
+ /**
+ * Default constructor which simply calls the
+ * super class for generic component accessibility
+ * handling.
+ */
+ public AccessibleAWTChoice()
+ {
+ super();
+ }
+
+ /**
+ * Returns an implementation of the <code>AccessibleAction</code>
+ * interface for this accessible object. In this case, the
+ * current instance is simply returned (with a more appropriate
+ * type), as it also implements the accessible action as well as
+ * the context.
+ *
+ * @return the accessible action associated with this context.
+ * @see javax.accessibility.AccessibleAction
+ */
+ public AccessibleAction getAccessibleAction()
+ {
+ return this;
+ }
+
+ /**
+ * Returns the role of this accessible object.
+ *
+ * @return the instance of <code>AccessibleRole</code>,
+ * which describes this object.
+ * @see javax.accessibility.AccessibleRole
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.COMBO_BOX;
+ }
+
+ /**
+ * Returns the number of actions associated with this accessible
+ * object. In this case, it is the number of choices available.
+ *
+ * @return the number of choices available.
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
+ */
+ public int getAccessibleActionCount()
+ {
+ return pItems.size();
+ }
+
+ /**
+ * Returns a description of the action with the supplied id.
+ * In this case, it is the text used in displaying the particular
+ * choice on-screen.
+ *
+ * @param i the id of the choice whose description should be
+ * retrieved.
+ * @return the <code>String</code> used to describe the choice.
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ return (String) pItems.get(i);
+ }
+
+ /**
+ * Executes the action with the specified id. In this case,
+ * calling this method provides the same behaviour as would
+ * choosing a choice from the list in a visual manner.
+ *
+ * @param i the id of the choice to select.
+ * @return true if a valid choice was specified.
+ * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ if (i < 0 || i >= pItems.size())
+ return false;
+
+ Choice.this.processItemEvent(new ItemEvent(Choice.this,
+ ItemEvent.ITEM_STATE_CHANGED,
+ this, ItemEvent.SELECTED));
+ return true;
+ }
+ }
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+ /**
+ * Initializes a new instance of <code>Choice</code>.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true
+ */
+ public Choice()
+ {
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+ }
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the number of items in the list.
+ *
+ * @return The number of items in the list.
+ */
+public int
+getItemCount()
+{
+ return countItems ();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the number of items in the list.
+ *
+ * @return The number of items in the list.
+ *
+ * @deprecated This method is deprecated in favor of <code>getItemCount</code>.
+ */
+public int
+countItems()
+{
+ return(pItems.size());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the item at the specified index in the list.
+ *
+ * @param index The index into the list to return the item from.
+ *
+ * @exception ArrayIndexOutOfBoundsException If the index is invalid.
+ */
+public String
+getItem(int index)
+{
+ return((String)pItems.elementAt(index));
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified item to this choice box.
+ *
+ * @param item The item to add.
+ *
+ * @exception NullPointerException If the item's value is null
+ *
+ * @since 1.1
+ */
+public synchronized void
+add(String item)
+{
+ if (item == null)
+ throw new NullPointerException ("item must be non-null");
+
+ pItems.addElement(item);
+
+ int i = pItems.size () - 1;
+ if (peer != null)
+ {
+ ChoicePeer cp = (ChoicePeer) peer;
+ cp.add (item, i);
+ }
+ else if (selectedIndex == -1)
+ select(0);
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified item to this choice box.
+ *
+ * This method is oboslete since Java 2 platform 1.1. Please use @see add
+ * instead.
+ *
+ * @param item The item to add.
+ *
+ * @exception NullPointerException If the item's value is equal to null
+ */
+public synchronized void
+addItem(String item)
+{
+ add(item);
+}
+
+/*************************************************************************/
+
+/** Inserts an item into this Choice. Existing items are shifted
+ * upwards. If the new item is the only item, then it is selected.
+ * If the currently selected item is shifted, then the first item is
+ * selected. If the currently selected item is not shifted, then it
+ * remains selected.
+ *
+ * @param item The item to add.
+ * @param index The index at which the item should be inserted.
+ *
+ * @exception IllegalArgumentException If index is less than 0
+ */
+public synchronized void
+insert(String item, int index)
+{
+ if (index < 0)
+ throw new IllegalArgumentException ("index may not be less then 0");
+
+ if (index > getItemCount ())
+ index = getItemCount ();
+
+ pItems.insertElementAt(item, index);
+
+ if (peer != null)
+ {
+ ChoicePeer cp = (ChoicePeer) peer;
+ cp.add (item, index);
+ }
+ else if (selectedIndex == -1 || selectedIndex >= index)
+ select(0);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified item from the choice box.
+ *
+ * @param item The item to remove.
+ *
+ * @exception IllegalArgumentException If the specified item doesn't exist.
+ */
+public synchronized void
+remove(String item)
+{
+ int index = pItems.indexOf(item);
+ if (index == -1)
+ throw new IllegalArgumentException ("item \""
+ + item + "\" not found in Choice");
+ remove(index);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the item at the specified index from the choice box.
+ *
+ * @param index The index of the item to remove.
+ *
+ * @exception IndexOutOfBoundsException If the index is not valid.
+ */
+public synchronized void
+remove(int index)
+{
+ if ((index < 0) || (index > getItemCount()))
+ throw new IllegalArgumentException("Bad index: " + index);
+
+ pItems.removeElementAt(index);
+
+ if (peer != null)
+ {
+ ChoicePeer cp = (ChoicePeer) peer;
+ cp.remove (index);
+ }
+ else
+ {
+ if (getItemCount() == 0)
+ selectedIndex = -1;
+ else if (index == selectedIndex)
+ select(0);
+ }
+
+ if (selectedIndex > index)
+ --selectedIndex;
+}
+
+/*************************************************************************/
+
+/**
+ * Removes all of the objects from this choice box.
+ */
+public synchronized void
+removeAll()
+{
+ if (getItemCount() <= 0)
+ return;
+
+ pItems.removeAllElements ();
+
+ if (peer != null)
+ {
+ ChoicePeer cp = (ChoicePeer) peer;
+ cp.removeAll ();
+ }
+
+ selectedIndex = -1;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the currently selected item, or null if no item is
+ * selected.
+ *
+ * @return The currently selected item.
+ */
+public synchronized String
+getSelectedItem()
+{
+ return (selectedIndex == -1
+ ? null
+ : ((String)pItems.elementAt(selectedIndex)));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns an array with one row containing the selected item.
+ *
+ * @return An array containing the selected item.
+ */
+public synchronized Object[]
+getSelectedObjects()
+{
+ if (selectedIndex == -1)
+ return null;
+
+ Object[] objs = new Object[1];
+ objs[0] = pItems.elementAt(selectedIndex);
+
+ return(objs);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the index of the selected item.
+ *
+ * @return The index of the selected item.
+ */
+public int
+getSelectedIndex()
+{
+ return(selectedIndex);
+}
+
+/*************************************************************************/
+
+/**
+ * Forces the item at the specified index to be selected.
+ *
+ * @param index The index of the row to make selected.
+ *
+ * @exception IllegalArgumentException If the specified index is invalid.
+ */
+public synchronized void
+select(int index)
+{
+ if ((index < 0) || (index > getItemCount()))
+ throw new IllegalArgumentException("Bad index: " + index);
+
+ this.selectedIndex = index;
+ if (peer != null)
+ {
+ ChoicePeer cp = (ChoicePeer) peer;
+ cp.select (index);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Forces the named item to be selected.
+ *
+ * @param item The item to be selected.
+ *
+ * @exception IllegalArgumentException If the specified item does not exist.
+ */
+public synchronized void
+select(String item)
+{
+ int index = pItems.indexOf(item);
+ if (index >= 0)
+ select(index);
+}
+
+/*************************************************************************/
+
+/**
+ * Creates the native peer for this object.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createChoice (this);
+ super.addNotify ();
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified listener to the list of registered listeners for
+ * this object.
+ *
+ * @param listener The listener to add.
+ */
+public synchronized void
+addItemListener(ItemListener listener)
+{
+ item_listeners = AWTEventMulticaster.add(item_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified listener from the list of registered listeners for
+ * this object.
+ *
+ * @param listener The listener to remove.
+ */
+public synchronized void
+removeItemListener(ItemListener listener)
+{
+ item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes this event by invoking <code>processItemEvent()</code> if the
+ * event is an instance of <code>ItemEvent</code>, otherwise the event
+ * is passed to the superclass.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ if (event instanceof ItemEvent)
+ processItemEvent((ItemEvent)event);
+ else
+ super.processEvent(event);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes item event by dispatching to any registered listeners.
+ *
+ * @param event The event to process.
+ */
+protected void
+processItemEvent(ItemEvent event)
+{
+ if (item_listeners != null)
+ item_listeners.itemStateChanged(event);
+}
+
+void
+dispatchEventImpl(AWTEvent e)
+{
+ if (e.id <= ItemEvent.ITEM_LAST
+ && e.id >= ItemEvent.ITEM_FIRST
+ && (item_listeners != null
+ || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this object.
+ *
+ * @return A debugging string for this object.
+ */
+protected String
+paramString()
+{
+ return ("selectedIndex=" + selectedIndex + "," + super.paramString());
+}
+
+ /**
+ * Returns an array of all the objects currently registered as FooListeners
+ * upon this Choice. FooListeners are registered using the addFooListener
+ * method.
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements java.util.EventListener.
+ *
+ * @since 1.3
+ */
+ public EventListener[] getListeners (Class listenerType)
+ {
+ if (listenerType == ItemListener.class)
+ return AWTEventMulticaster.getListeners (item_listeners, listenerType);
+
+ return super.getListeners (listenerType);
+ }
+
+ /**
+ * Returns all registered item listeners.
+ *
+ * @since 1.4
+ */
+ public ItemListener[] getItemListeners ()
+ {
+ return (ItemListener[]) getListeners (ItemListener.class);
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>Choice</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTChoice();
+ return accessibleContext;
+ }
+} // class Choice
diff --git a/libjava/classpath/java/awt/Color.java b/libjava/classpath/java/awt/Color.java
new file mode 100644
index 0000000..4ad46d0
--- /dev/null
+++ b/libjava/classpath/java/awt/Color.java
@@ -0,0 +1,1008 @@
+/* Color.java -- represents a color in Java
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.io.Serializable;
+
+/**
+ * This class represents a color value in the AWT system. It uses the sRGB
+ * (standard Red-Green-Blue) system, along with an alpha value ranging from
+ * transparent (0.0f or 0) and opaque (1.0f or 255). The color is not
+ * pre-multiplied by the alpha value an any of the accessor methods. Further
+ * information about sRGB can be found at
+ * <a href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
+ * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html</a>.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ColorSpace
+ * @see AlphaComposite
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public class Color implements Paint, Serializable
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 118526816881161077L;
+
+ /** Constant for the color white: R=255, G=255, B=255. */
+ public static final Color white = new Color(0xffffff, false);
+
+ /**
+ * Constant for the color white: R=255, G=255, B=255.
+ *
+ * @since 1.4
+ */
+ public static final Color WHITE = white;
+
+ /** Constant for the color light gray: R=192, G=192, B=192. */
+ public static final Color lightGray = new Color(0xc0c0c0, false);
+
+ /**
+ * Constant for the color light gray: R=192, G=192, B=192.
+ *
+ * @since 1.4
+ */
+ public static final Color LIGHT_GRAY = lightGray;
+
+ /** Constant for the color gray: R=128, G=128, B=128. */
+ public static final Color gray = new Color(0x808080, false);
+
+ /**
+ * Constant for the color gray: R=128, G=128, B=128.
+ *
+ * @since 1.4
+ */
+ public static final Color GRAY = gray;
+
+ /** Constant for the color dark gray: R=64, G=64, B=64. */
+ public static final Color darkGray = new Color(0x404040, false);
+
+ /**
+ * Constant for the color dark gray: R=64, G=64, B=64.
+ *
+ * @since 1.4
+ */
+ public static final Color DARK_GRAY = darkGray;
+
+ /** Constant for the color black: R=0, G=0, B=0. */
+ public static final Color black = new Color(0x000000, false);
+
+ /**
+ * Constant for the color black: R=0, G=0, B=0.
+ *
+ * @since 1.4
+ */
+ public static final Color BLACK = black;
+
+ /** Constant for the color red: R=255, G=0, B=0. */
+ public static final Color red = new Color(0xff0000, false);
+
+ /**
+ * Constant for the color red: R=255, G=0, B=0.
+ *
+ * @since 1.4
+ */
+ public static final Color RED = red;
+
+ /** Constant for the color pink: R=255, G=175, B=175. */
+ public static final Color pink = new Color(0xffafaf, false);
+
+ /**
+ * Constant for the color pink: R=255, G=175, B=175.
+ *
+ * @since 1.4
+ */
+ public static final Color PINK = pink;
+
+ /** Constant for the color orange: R=255, G=200, B=0. */
+ public static final Color orange = new Color(0xffc800, false);
+
+ /**
+ * Constant for the color orange: R=255, G=200, B=0.
+ *
+ * @since 1.4
+ */
+ public static final Color ORANGE = orange;
+
+ /** Constant for the color yellow: R=255, G=255, B=0. */
+ public static final Color yellow = new Color(0xffff00, false);
+
+ /**
+ * Constant for the color yellow: R=255, G=255, B=0.
+ *
+ * @since 1.4
+ */
+ public static final Color YELLOW = yellow;
+
+ /** Constant for the color green: R=0, G=255, B=0. */
+ public static final Color green = new Color(0x00ff00, false);
+
+ /**
+ * Constant for the color green: R=0, G=255, B=0.
+ *
+ * @since 1.4
+ */
+ public static final Color GREEN = green;
+
+ /** Constant for the color magenta: R=255, G=0, B=255. */
+ public static final Color magenta = new Color(0xff00ff, false);
+
+ /**
+ * Constant for the color magenta: R=255, G=0, B=255.
+ *
+ * @since 1.4
+ */
+ public static final Color MAGENTA = magenta;
+
+ /** Constant for the color cyan: R=0, G=255, B=255. */
+ public static final Color cyan = new Color(0x00ffff, false);
+
+ /**
+ * Constant for the color cyan: R=0, G=255, B=255.
+ *
+ * @since 1.4
+ */
+ public static final Color CYAN = cyan;
+
+ /** Constant for the color blue: R=0, G=0, B=255. */
+ public static final Color blue = new Color(0x0000ff, false);
+
+ /**
+ * Constant for the color blue: R=0, G=0, B=255.
+ *
+ * @since 1.4
+ */
+ public static final Color BLUE = blue;
+
+ /** Internal mask for red. */
+ private static final int RED_MASK = 255 << 16;
+
+ /** Internal mask for green. */
+ private static final int GREEN_MASK = 255 << 8;
+
+ /** Internal mask for blue. */
+ private static final int BLUE_MASK = 255;
+
+ /** Internal mask for alpha. Package visible for use in subclass. */
+ static final int ALPHA_MASK = 255 << 24;
+
+ /** Amount to scale a color by when brightening or darkening. */
+ private static final float BRIGHT_SCALE = 0.7f;
+
+ /**
+ * The color value, in sRGB. Note that the actual color may be more
+ * precise if frgbvalue or fvalue is non-null. This class stores alpha, red,
+ * green, and blue, each 0-255, packed in an int. However, the subclass
+ * SystemColor stores an index into an array. Therefore, for serial
+ * compatibility (and because of poor design on Sun's part), this value
+ * cannot be used directly; instead you must use <code>getRGB()</code>.
+ *
+ * @see #getRGB()
+ * @serial the value of the color, whether an RGB literal or array index
+ */
+ final int value;
+
+ /**
+ * The color value, in sRGB. This may be null if the color was constructed
+ * with ints; and it does not include alpha. This stores red, green, and
+ * blue, in the range 0.0f - 1.0f.
+ *
+ * @see #getRGBColorComponents(float[])
+ * @see #getRGBComponents(float[])
+ * @serial the rgb components of the value
+ * @since 1.2
+ */
+ private float[] frgbvalue;
+
+ /**
+ * The color value, in the native ColorSpace components. This may be null
+ * if the color was constructed with ints or in the sRGB color space; and
+ * it does not include alpha.
+ *
+ * @see #getRGBColorComponents(float[])
+ * @see #getRGBComponents(float[])
+ * @serial the original color space components of the color
+ * @since 1.2
+ */
+ private float[] fvalue;
+
+ /**
+ * The alpha value. This is in the range 0.0f - 1.0f, but is invalid if
+ * deserialized as 0.0 when frgbvalue is null.
+ *
+ * @see #getRGBComponents(float[])
+ * @see #getComponents(float[])
+ * @serial the alpha component of this color
+ * @since 1.2
+ */
+ private final float falpha;
+
+ /**
+ * The ColorSpace. Null means the default sRGB space.
+ *
+ * @see #getColor(String)
+ * @see #getColorSpace()
+ * @see #getColorComponents(float[])
+ * @serial the color space for this color
+ * @since 1.2
+ */
+ private final ColorSpace cs;
+
+ /**
+ * The paint context for this solid color. Package visible for use in
+ * subclass.
+ */
+ transient ColorPaintContext context;
+
+ /**
+ * Initializes a new instance of <code>Color</code> using the specified
+ * red, green, and blue values, which must be given as integers in the
+ * range of 0-255. Alpha will default to 255 (opaque). When drawing to
+ * screen, the actual color may be adjusted to the best match of hardware
+ * capabilities.
+ *
+ * @param red the red component of the RGB value
+ * @param green the green component of the RGB value
+ * @param blue the blue component of the RGB value
+ * @throws IllegalArgumentException if the values are out of range 0-255
+ * @see #getRed()
+ * @see #getGreen()
+ * @see #getBlue()
+ * @see #getRGB()
+ * @see #Color(int, int, int, int)
+ */
+ public Color(int red, int green, int blue)
+ {
+ this(red, green, blue, 255);
+ }
+
+ /**
+ * Initializes a new instance of <code>Color</code> using the specified
+ * red, green, blue, and alpha values, which must be given as integers in
+ * the range of 0-255. When drawing to screen, the actual color may be
+ * adjusted to the best match of hardware capabilities.
+ *
+ * @param red the red component of the RGB value
+ * @param green the green component of the RGB value
+ * @param blue the blue component of the RGB value
+ * @param alpha the alpha value of the color
+ * @throws IllegalArgumentException if the values are out of range 0-255
+ * @see #getRed()
+ * @see #getGreen()
+ * @see #getBlue()
+ * @see #getAlpha()
+ * @see #getRGB()
+ */
+ public Color(int red, int green, int blue, int alpha)
+ {
+ if ((red & 255) != red || (green & 255) != green || (blue & 255) != blue
+ || (alpha & 255) != alpha)
+ throw new IllegalArgumentException("Bad RGB values"
+ +" red=0x"+Integer.toHexString(red)
+ +" green=0x"+Integer.toHexString(green)
+ +" blue=0x"+Integer.toHexString(blue)
+ +" alpha=0x"+Integer.toHexString(alpha) );
+
+ value = (alpha << 24) | (red << 16) | (green << 8) | blue;
+ falpha = 1;
+ cs = null;
+ }
+
+ /**
+ * Initializes a new instance of <code>Color</code> using the specified
+ * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
+ * red in bits 16-23. The other bits are ignored. The alpha value is set
+ * to 255 (opaque). When drawing to screen, the actual color may be
+ * adjusted to the best match of hardware capabilities.
+ *
+ * @param value the RGB value
+ * @see ColorModel#getRGBdefault()
+ * @see #getRed()
+ * @see #getGreen()
+ * @see #getBlue()
+ * @see #getRGB()
+ * @see #Color(int, boolean)
+ */
+ public Color(int value)
+ {
+ this(value, false);
+ }
+
+ /**
+ * Initializes a new instance of <code>Color</code> using the specified
+ * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
+ * red in bits 16-23. The alpha value is in bits 24-31, unless hasalpha
+ * is false, in which case alpha is set to 255. When drawing to screen, the
+ * actual color may be adjusted to the best match of hardware capabilities.
+ *
+ * @param value the RGB value
+ * @param hasalpha true if value includes the alpha
+ * @see ColorModel#getRGBdefault()
+ * @see #getRed()
+ * @see #getGreen()
+ * @see #getBlue()
+ * @see #getAlpha()
+ * @see #getRGB()
+ */
+ public Color(int value, boolean hasalpha)
+ {
+ // Note: SystemColor calls this constructor, setting falpha to 0; but
+ // code in getRGBComponents correctly reports falpha as 1.0 to the user
+ // for all instances of SystemColor since frgbvalue is left null here.
+ if (hasalpha)
+ falpha = ((value & ALPHA_MASK) >> 24) / 255f;
+ else
+ {
+ value |= ALPHA_MASK;
+ falpha = 1;
+ }
+ this.value = value;
+ cs = null;
+ }
+
+ /**
+ * Initializes a new instance of <code>Color</code> using the specified
+ * RGB values. These must be in the range of 0.0-1.0. Alpha is assigned
+ * the value of 1.0 (opaque). When drawing to screen, the actual color may
+ * be adjusted to the best match of hardware capabilities.
+ *
+ * @param red the red component of the RGB value
+ * @param green the green component of the RGB value
+ * @param blue the blue component of the RGB value
+ * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
+ * @see #getRed()
+ * @see #getGreen()
+ * @see #getBlue()
+ * @see #getRGB()
+ * @see #Color(float, float, float, float)
+ */
+ public Color(float red, float green, float blue)
+ {
+ this(red, green, blue, 1.0f);
+ }
+
+ /**
+ * Initializes a new instance of <code>Color</code> using the specified
+ * RGB and alpha values. These must be in the range of 0.0-1.0. When drawing
+ * to screen, the actual color may be adjusted to the best match of
+ * hardware capabilities.
+ *
+ * @param red the red component of the RGB value
+ * @param green the green component of the RGB value
+ * @param blue the blue component of the RGB value
+ * @param alpha the alpha value of the color
+ * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
+ * @see #getRed()
+ * @see #getGreen()
+ * @see #getBlue()
+ * @see #getAlpha()
+ * @see #getRGB()
+ */
+ public Color(float red, float green, float blue, float alpha)
+ {
+ value = convert(red, green, blue, alpha);
+ frgbvalue = new float[] {red, green, blue};
+ falpha = alpha;
+ cs = null;
+ }
+
+ /**
+ * Creates a color in the given ColorSpace with the specified alpha. The
+ * array must be non-null and have enough elements for the color space
+ * (for example, RGB requires 3 elements, CMYK requires 4). When drawing
+ * to screen, the actual color may be adjusted to the best match of
+ * hardware capabilities.
+ *
+ * @param space the color space of components
+ * @param components the color components, except alpha
+ * @param alpha the alpha value of the color
+ * @throws NullPointerException if cpsace or components is null
+ * @throws ArrayIndexOutOfBoundsException if components is too small
+ * @throws IllegalArgumentException if alpha or any component is out of range
+ * @see #getComponents(float[])
+ * @see #getColorComponents(float[])
+ */
+ public Color(ColorSpace space, float[] components, float alpha)
+ {
+ frgbvalue = space.toRGB(components);
+ fvalue = components;
+ falpha = alpha;
+ cs = space;
+ value = convert(frgbvalue[0], frgbvalue[1], frgbvalue[2], alpha);
+ }
+
+ /**
+ * Returns the red value for this color, as an integer in the range 0-255
+ * in the sRGB color space.
+ *
+ * @return the red value for this color
+ * @see #getRGB()
+ */
+ public int getRed()
+ {
+ // Do not inline getRGB() to value, because of SystemColor.
+ return (getRGB() & RED_MASK) >> 16;
+ }
+
+ /**
+ * Returns the green value for this color, as an integer in the range 0-255
+ * in the sRGB color space.
+ *
+ * @return the green value for this color
+ * @see #getRGB()
+ */
+ public int getGreen()
+ {
+ // Do not inline getRGB() to value, because of SystemColor.
+ return (getRGB() & GREEN_MASK) >> 8;
+ }
+
+ /**
+ * Returns the blue value for this color, as an integer in the range 0-255
+ * in the sRGB color space.
+ *
+ * @return the blue value for this color
+ * @see #getRGB()
+ */
+ public int getBlue()
+ {
+ // Do not inline getRGB() to value, because of SystemColor.
+ return getRGB() & BLUE_MASK;
+ }
+
+ /**
+ * Returns the alpha value for this color, as an integer in the range 0-255.
+ *
+ * @return the alpha value for this color
+ * @see #getRGB()
+ */
+ public int getAlpha()
+ {
+ // Do not inline getRGB() to value, because of SystemColor.
+ return (getRGB() & ALPHA_MASK) >>> 24;
+ }
+
+ /**
+ * Returns the RGB value for this color, in the sRGB color space. The blue
+ * value will be in bits 0-7, green in 8-15, red in 16-23, and alpha value in
+ * 24-31.
+ *
+ * @return the RGB value for this color
+ * @see ColorModel#getRGBdefault()
+ * @see #getRed()
+ * @see #getGreen()
+ * @see #getBlue()
+ * @see #getAlpha()
+ */
+ public int getRGB()
+ {
+ return value;
+ }
+
+ /**
+ * Returns a brighter version of this color. This is done by increasing the
+ * RGB values by an arbitrary scale factor. The new color is opaque (an
+ * alpha of 255). Note that this method and the <code>darker()</code>
+ * method are not necessarily inverses.
+ *
+ * @return a brighter version of this color
+ * @see #darker()
+ */
+ public Color brighter()
+ {
+ // Do not inline getRGB() to this.value, because of SystemColor.
+ int value = getRGB();
+ int red = (value & RED_MASK) >> 16;
+ int green = (value & GREEN_MASK) >> 8;
+ int blue = value & BLUE_MASK;
+ // We have to special case 0-2 because they won't scale by division.
+ red = red < 3 ? 3 : (int) Math.min(255, red / BRIGHT_SCALE);
+ green = green < 3 ? 3 : (int) Math.min(255, green / BRIGHT_SCALE);
+ blue = blue < 3 ? 3 : (int) Math.min(255, blue / BRIGHT_SCALE);
+ return new Color(red, green, blue, 255);
+ }
+
+ /**
+ * Returns a darker version of this color. This is done by decreasing the
+ * RGB values by an arbitrary scale factor. The new color is opaque (an
+ * alpha of 255). Note that this method and the <code>brighter()</code>
+ * method are not necessarily inverses.
+ *
+ * @return a darker version of this color
+ * @see #brighter()
+ */
+ public Color darker()
+ {
+ // Do not inline getRGB() to this.value, because of SystemColor.
+ int value = getRGB();
+ return new Color((int) (((value & RED_MASK) >> 16) * BRIGHT_SCALE),
+ (int) (((value & GREEN_MASK) >> 8) * BRIGHT_SCALE),
+ (int) ((value & BLUE_MASK) * BRIGHT_SCALE), 255);
+ }
+
+ /**
+ * Returns a hash value for this color. This is simply the color in 8-bit
+ * precision, in the format 0xAARRGGBB (alpha, red, green, blue).
+ *
+ * @return a hash value for this color
+ */
+ public int hashCode()
+ {
+ return value;
+ }
+
+ /**
+ * Tests this object for equality against the specified object. This will
+ * be true if and only if the specified object is an instance of
+ * <code>Color</code> and has the same 8-bit integer red, green, and blue
+ * values as this object. Note that two colors may be slightly different
+ * as float values, but round to the same integer values. Also note that
+ * this does not accurately compare SystemColors, since that class does
+ * not store its internal data in RGB format like regular colors.
+ *
+ * @param obj the object to compare to
+ * @return true if the specified object is semantically equal to this one
+ */
+ public boolean equals(Object obj)
+ {
+ return obj instanceof Color && ((Color) obj).value == value;
+ }
+
+ /**
+ * Returns a string representation of this object. Subclasses may return
+ * any desired format, except for null, but this implementation returns
+ * <code>getClass().getName() + "[r=" + getRed() + ",g=" + getGreen()
+ * + ",b=" + getBlue() + ']'</code>.
+ *
+ * @return a string representation of this object
+ */
+ public String toString()
+ {
+ return getClass().getName() + "[r=" + ((value & RED_MASK) >> 16)
+ + ",g=" + ((value & GREEN_MASK) >> 8) + ",b=" + (value & BLUE_MASK)
+ + ']';
+ }
+
+ /**
+ * Converts the specified string to a number, using Integer.decode, and
+ * creates a new instance of <code>Color</code> from the value. The alpha
+ * value will be 255 (opaque).
+ *
+ * @param str the numeric color string
+ * @return a new instance of <code>Color</code> for the string
+ * @throws NumberFormatException if the string cannot be parsed
+ * @throws NullPointerException if the string is null
+ * @see Integer#decode(String)
+ * @see #Color(int)
+ * @since 1.1
+ */
+ public static Color decode(String str)
+ {
+ return new Color(Integer.decode(str).intValue(), false);
+ }
+
+ /**
+ * Returns a new instance of <code>Color</code> from the value of the
+ * system property named by the specified string. If the property does not
+ * exist, or cannot be parsed, then <code>null</code> will be returned.
+ *
+ * @param prop the system property to retrieve
+ * @throws SecurityException if getting the property is denied
+ * @see #getColor(String, Color)
+ * @see Integer#getInteger(String)
+ */
+ public static Color getColor(String prop)
+ {
+ return getColor(prop, null);
+ }
+
+ /**
+ * Returns a new instance of <code>Color</code> from the value of the
+ * system property named by the specified string. If the property does
+ * not exist, or cannot be parsed, then the default color value will be
+ * returned.
+ *
+ * @param prop the system property to retrieve
+ * @param defcolor the default color
+ * @throws SecurityException if getting the property is denied
+ * @see Integer#getInteger(String)
+ */
+ public static Color getColor(String prop, Color defcolor)
+ {
+ Integer val = Integer.getInteger(prop, null);
+ return val == null ? defcolor
+ : new Color(val.intValue(), false);
+ }
+
+ /**
+ * Returns a new instance of <code>Color</code> from the value of the
+ * system property named by the specified string. If the property does
+ * not exist, or cannot be parsed, then the default RGB value will be
+ * used to create a return value.
+ *
+ * @param prop the system property to retrieve
+ * @param defrgb the default RGB value
+ * @throws SecurityException if getting the property is denied
+ * @see #getColor(String, Color)
+ * @see Integer#getInteger(String, int)
+ */
+ public static Color getColor(String prop, int defrgb)
+ {
+ Color c = getColor(prop, null);
+ return c == null ? new Color(defrgb, false) : c;
+ }
+
+ /**
+ * Converts from the HSB (hue, saturation, brightness) color model to the
+ * RGB (red, green, blue) color model. The hue may be any floating point;
+ * it's fractional portion is used to select the angle in the HSB model.
+ * The saturation and brightness must be between 0 and 1. The result is
+ * suitable for creating an RGB color with the one-argument constructor.
+ *
+ * @param hue the hue of the HSB value
+ * @param saturation the saturation of the HSB value
+ * @param brightness the brightness of the HSB value
+ * @return the RGB value
+ * @see #getRGB()
+ * @see #Color(int)
+ * @see ColorModel#getRGBdefault()
+ */
+ public static int HSBtoRGB(float hue, float saturation, float brightness)
+ {
+ if (saturation == 0)
+ return convert(brightness, brightness, brightness, 0);
+ if (saturation < 0 || saturation > 1 || brightness < 0 || brightness > 1)
+ throw new IllegalArgumentException();
+ hue = hue - (float) Math.floor(hue);
+ int i = (int) (6 * hue);
+ float f = 6 * hue - i;
+ float p = brightness * (1 - saturation);
+ float q = brightness * (1 - saturation * f);
+ float t = brightness * (1 - saturation * (1 - f));
+ switch (i)
+ {
+ case 0:
+ return convert(brightness, t, p, 0);
+ case 1:
+ return convert(q, brightness, p, 0);
+ case 2:
+ return convert(p, brightness, t, 0);
+ case 3:
+ return convert(p, q, brightness, 0);
+ case 4:
+ return convert(t, p, brightness, 0);
+ case 5:
+ return convert(brightness, p, q, 0);
+ default:
+ throw new InternalError("impossible");
+ }
+ }
+
+ /**
+ * Converts from the RGB (red, green, blue) color model to the HSB (hue,
+ * saturation, brightness) color model. If the array is null, a new one
+ * is created, otherwise it is recycled. The results will be in the range
+ * 0.0-1.0 if the inputs are in the range 0-255.
+ *
+ * @param red the red part of the RGB value
+ * @param green the green part of the RGB value
+ * @param blue the blue part of the RGB value
+ * @param array an array for the result (at least 3 elements), or null
+ * @return the array containing HSB value
+ * @throws ArrayIndexOutOfBoundsException of array is too small
+ * @see #getRGB()
+ * @see #Color(int)
+ * @see ColorModel#getRGBdefault()
+ */
+ public static float[] RGBtoHSB(int red, int green, int blue, float array[])
+ {
+ if (array == null)
+ array = new float[3];
+ // Calculate brightness.
+ int min;
+ int max;
+ if (red < green)
+ {
+ min = red;
+ max = green;
+ }
+ else
+ {
+ min = green;
+ max = red;
+ }
+ if (blue > max)
+ max = blue;
+ else if (blue < min)
+ min = blue;
+ array[2] = max / 255f;
+ // Calculate saturation.
+ if (max == 0)
+ array[1] = 0;
+ else
+ array[1] = (max - min) / max;
+ // Calculate hue.
+ if (array[1] == 0)
+ array[0] = 0;
+ else
+ {
+ float delta = (max - min) * 6;
+ if (red == max)
+ array[0] = (green - blue) / delta;
+ else if (green == max)
+ array[0] = 1f / 3 + (blue - red) / delta;
+ else
+ array[0] = 2f / 3 + (red - green) / delta;
+ if (array[0] < 0)
+ array[0]++;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a new instance of <code>Color</code> based on the specified
+ * HSB values. The hue may be any floating point; it's fractional portion
+ * is used to select the angle in the HSB model. The saturation and
+ * brightness must be between 0 and 1.
+ *
+ * @param hue the hue of the HSB value
+ * @param saturation the saturation of the HSB value
+ * @param brightness the brightness of the HSB value
+ * @return the new <code>Color</code> object
+ */
+ public static Color getHSBColor(float hue, float saturation,
+ float brightness)
+ {
+ return new Color(HSBtoRGB(hue, saturation, brightness), false);
+ }
+
+ /**
+ * Returns a float array with the red, green, and blue components, and the
+ * alpha value, in the default sRGB space, with values in the range 0.0-1.0.
+ * If the array is null, a new one is created, otherwise it is recycled.
+ *
+ * @param array the array to put results into (at least 4 elements), or null
+ * @return the RGB components and alpha value
+ * @throws ArrayIndexOutOfBoundsException if array is too small
+ */
+ public float[] getRGBComponents(float[] array)
+ {
+ if (array == null)
+ array = new float[4];
+ getRGBColorComponents(array);
+ // Stupid serialization issues require this check.
+ array[3] = (falpha == 0 && frgbvalue == null
+ ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
+ return array;
+ }
+
+ /**
+ * Returns a float array with the red, green, and blue components, in the
+ * default sRGB space, with values in the range 0.0-1.0. If the array is
+ * null, a new one is created, otherwise it is recycled.
+ *
+ * @param array the array to put results into (at least 3 elements), or null
+ * @return the RGB components
+ * @throws ArrayIndexOutOfBoundsException if array is too small
+ */
+ public float[] getRGBColorComponents(float[] array)
+ {
+ if (array == null)
+ array = new float[3];
+ else if (array == frgbvalue)
+ return array; // Optimization for getColorComponents(float[]).
+ if (frgbvalue == null)
+ {
+ // Do not inline getRGB() to this.value, because of SystemColor.
+ int value = getRGB();
+ frgbvalue = new float[] { ((value & RED_MASK) >> 16) / 255f,
+ ((value & GREEN_MASK) >> 8) / 255f,
+ (value & BLUE_MASK) / 255f };
+ }
+ array[0] = frgbvalue[0];
+ array[1] = frgbvalue[1];
+ array[2] = frgbvalue[2];
+ return array;
+ }
+
+ /**
+ * Returns a float array containing the color and alpha components of this
+ * color in the ColorSpace it was created with (the constructors which do
+ * not take a ColorSpace parameter use a default sRGB ColorSpace). If the
+ * array is null, a new one is created, otherwise it is recycled, and must
+ * have at least one more position than components used in the color space.
+ *
+ * @param array the array to put results into, or null
+ * @return the original color space components and alpha value
+ * @throws ArrayIndexOutOfBoundsException if array is too small
+ */
+ public float[] getComponents(float[] array)
+ {
+ int numComponents = cs == null ? 3 : cs.getNumComponents();
+ if (array == null)
+ array = new float[1 + numComponents];
+ getColorComponents(array);
+ // Stupid serialization issues require this check.
+ array[numComponents] = (falpha == 0 && frgbvalue == null
+ ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
+ return array;
+ }
+
+ /**
+ * Returns a float array containing the color components of this color in
+ * the ColorSpace it was created with (the constructors which do not take
+ * a ColorSpace parameter use a default sRGB ColorSpace). If the array is
+ * null, a new one is created, otherwise it is recycled, and must have at
+ * least as many positions as used in the color space.
+ *
+ * @param array the array to put results into, or null
+ * @return the original color space components
+ * @throws ArrayIndexOutOfBoundsException if array is too small
+ */
+ public float[] getColorComponents(float[] array)
+ {
+ int numComponents = cs == null ? 3 : cs.getNumComponents();
+ if (array == null)
+ array = new float[numComponents];
+ if (fvalue == null) // If fvalue is null, cs should be null too.
+ fvalue = getRGBColorComponents(frgbvalue);
+ System.arraycopy(fvalue, 0, array, 0, numComponents);
+ return array;
+ }
+
+ /**
+ * Returns a float array containing the color and alpha components of this
+ * color in the given ColorSpace. If the array is null, a new one is
+ * created, otherwise it is recycled, and must have at least one more
+ * position than components used in the color space.
+ *
+ * @param space the color space to translate to
+ * @param array the array to put results into, or null
+ * @return the color space components and alpha value
+ * @throws ArrayIndexOutOfBoundsException if array is too small
+ * @throws NullPointerException if space is null
+ */
+ public float[] getComponents(ColorSpace space, float[] array)
+ {
+ int numComponents = space.getNumComponents();
+ if (array == null)
+ array = new float[1 + numComponents];
+ getColorComponents(space, array);
+ // Stupid serialization issues require this check.
+ array[numComponents] = (falpha == 0 && frgbvalue == null
+ ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
+ return array;
+ }
+
+ /**
+ * Returns a float array containing the color components of this color in
+ * the given ColorSpace. If the array is null, a new one is created,
+ * otherwise it is recycled, and must have at least as many positions as
+ * used in the color space.
+ *
+ * @param space the color space to translate to
+ * @return the color space components
+ * @throws ArrayIndexOutOfBoundsException if array is too small
+ * @throws NullPointerException if space is null
+ */
+ public float[] getColorComponents(ColorSpace space, float[] array)
+ {
+ float[] components = space.fromRGB(getRGBColorComponents(frgbvalue));
+ if (array == null)
+ return components;
+ System.arraycopy(components, 0, array, 0, components.length);
+ return array;
+ }
+
+ /**
+ * Returns the color space of this color. Except for the constructor which
+ * takes a ColorSpace argument, this will be an implementation of
+ * ColorSpace.CS_sRGB.
+ *
+ * @return the color space
+ */
+ public ColorSpace getColorSpace()
+ {
+ return cs == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : cs;
+ }
+
+ /**
+ * Returns a paint context, used for filling areas of a raster scan with
+ * this color. Since the color is constant across the entire rectangle, and
+ * since it is always in sRGB space, this implementation returns the same
+ * object, regardless of the parameters. Subclasses, however, may have a
+ * mutable result.
+ *
+ * @param cm the requested color model
+ * @param deviceBounds the bounding box in device coordinates, ignored
+ * @param userBounds the bounding box in user coordinates, ignored
+ * @param xform the bounds transformation, ignored
+ * @param hints any rendering hints, ignored
+ * @return a context for painting this solid color
+ */
+ public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+ Rectangle2D userBounds,
+ AffineTransform xform,
+ RenderingHints hints)
+ {
+ if (context == null || !context.getColorModel().equals(cm))
+ context = new ColorPaintContext(cm,value);
+ return context;
+ }
+
+ /**
+ * Returns the transparency level of this color.
+ *
+ * @return one of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}
+ */
+ public int getTransparency()
+ {
+ // Do not inline getRGB() to this.value, because of SystemColor.
+ int alpha = getRGB() & ALPHA_MASK;
+ return alpha == (255 << 24) ? OPAQUE : alpha == 0 ? BITMASK : TRANSLUCENT;
+ }
+
+ /**
+ * Converts float values to integer value.
+ *
+ * @param red the red value
+ * @param green the green value
+ * @param blue the blue value
+ * @param alpha the alpha value
+ * @return the integer value made of 8-bit sections
+ * @throws IllegalArgumentException if parameters are out of range 0.0-1.0
+ */
+ private static int convert(float red, float green, float blue, float alpha)
+ {
+ if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1
+ || alpha < 0 || alpha > 1)
+ throw new IllegalArgumentException("Bad RGB values");
+ int redval = Math.round(255 * red);
+ int greenval = Math.round(255 * green);
+ int blueval = Math.round(255 * blue);
+ int alphaval = Math.round(255 * alpha);
+ return (alphaval << 24) | (redval << 16) | (greenval << 8) | blueval;
+ }
+} // class Color
diff --git a/libjava/classpath/java/awt/ColorPaintContext.java b/libjava/classpath/java/awt/ColorPaintContext.java
new file mode 100644
index 0000000..759ba9d
--- /dev/null
+++ b/libjava/classpath/java/awt/ColorPaintContext.java
@@ -0,0 +1,195 @@
+/* ColorPaintContext.java -- context for painting solid colors
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+/**
+ * This class provides a paint context which will fill a rectanglar region of
+ * a raster scan with the given color. However, it is not yet completely
+ * implemented.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+class ColorPaintContext implements PaintContext
+{
+ /**
+ * The color to fill any raster with. Package visible for use in
+ * SystemColor.
+ */
+ final int color;
+ final ColorModel colorModel;
+
+ private ColorRaster cachedRaster;
+
+
+ /**
+ * Create the context for a given color.
+ *
+ * @param c The solid color to use.
+ */
+ ColorPaintContext(int colorRGB)
+ {
+ this(ColorModel.getRGBdefault(), colorRGB);
+ }
+
+ /**
+ * Create the context for a given color.
+ *
+ * @param cm The color model of this context.
+ * @param c The solid color to use.
+ */
+ ColorPaintContext(ColorModel cm,int colorRGB)
+ {
+ color = colorRGB;
+ colorModel = cm;
+ }
+
+ /**
+ * Release the resources allocated for the paint. As the color is constant,
+ * there aren't any resources.
+ */
+ public void dispose()
+ {
+ }
+
+ /**
+ * Return the color model of this context.
+ *
+ * @return the context color model
+ */
+ public ColorModel getColorModel()
+ {
+ return colorModel;
+ }
+
+ /**
+ * Return a raster containing the colors for the graphics operation.
+ *
+ * @param x the x-coordinate, in device space
+ * @param y the y-coordinate, in device space
+ * @param width the width, in device space
+ * @param height the height, in device space
+ * @return a raster for the given area and color
+ */
+ public Raster getRaster(int x, int y, int width, int height)
+ {
+ if( cachedRaster == null
+ || cachedRaster.getWidth() < width
+ || cachedRaster.getHeight() < height)
+ {
+ cachedRaster = new ColorRaster(colorModel, 0, 0, width, height, color);
+ }
+ return cachedRaster.createChild(0 ,0 ,width ,height ,x ,y , null);
+ }
+
+ /**
+ * A ColorRaster is a raster that is completely filled with one color. The
+ * data layout is taken from the color model given to the constructor.
+ */
+ private class ColorRaster extends Raster
+ {
+
+ /**
+ * Create a raster that is compaltible with the given color model and
+ * filled with the given color.
+ * @param cm The color model for this raster.
+ * @param x The smallest horizontal corrdinate in the raster.
+ * @param y The smallest vertical coordinate in the raster.
+ * @param width The width of the raster.
+ * @param height The height of the raster.
+ * @param rgbPixel The RGB value of the color for this raster.
+ */
+ ColorRaster(ColorModel cm,int x, int y, int width, int height, int rgbPixel)
+ {
+ super(cm.createCompatibleSampleModel(width,height),new Point(x,y));
+ Object pixel = cm.getDataElements(rgbPixel,null);
+ getSampleModel().setDataElements(0, 0,
+ width, height,
+ multiplyData(pixel,null,width*height),
+ dataBuffer);
+ }
+
+
+
+ private Object multiplyData(Object src, Object dest, int factor)
+ {
+ Object from;
+ int srcLength = 0;
+ if (src instanceof byte[])
+ {
+ srcLength = ((byte[])src).length;
+
+ if (dest == null) dest = new byte[factor * srcLength];
+ }
+ else if (src instanceof short[])
+ {
+ srcLength = ((short[])src).length;
+ if (dest == null) dest = new short[factor * srcLength];
+ }
+ else if (src instanceof int[])
+ {
+ srcLength = ((int[]) src).length;
+ if (dest == null) dest = new int[factor * srcLength];
+ }
+ else
+ {
+ throw new ClassCastException("Unknown data buffer type");
+ }
+
+ System.arraycopy(src,0,dest,0,srcLength);
+
+ int count = 1;
+ while(count*2 < factor)
+ {
+ System.arraycopy(dest, 0, dest, count * srcLength, count*srcLength);
+ count *= 2;
+ }
+
+ if(factor > count)
+ System.arraycopy(dest,0, dest, count * srcLength,
+ (factor - count) * srcLength );
+
+ return dest;
+ }
+
+ }
+
+} // class ColorPaintContext
diff --git a/libjava/classpath/java/awt/Component.java b/libjava/classpath/java/awt/Component.java
new file mode 100644
index 0000000..4491904
--- /dev/null
+++ b/libjava/classpath/java/awt/Component.java
@@ -0,0 +1,6017 @@
+/* Component.java -- a graphics component
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.dnd.DropTarget;
+import java.awt.event.ActionEvent;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.HierarchyBoundsListener;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
+import java.awt.event.InputEvent;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InputMethodListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
+import java.awt.im.InputContext;
+import java.awt.im.InputMethodRequests;
+import java.awt.image.BufferStrategy;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+import java.awt.peer.ComponentPeer;
+import java.awt.peer.LightweightPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+
+/**
+ * The root of all evil. All graphical representations are subclasses of this
+ * giant class, which is designed for screen display and user interaction.
+ * This class can be extended directly to build a lightweight component (one
+ * not associated with a native window); lightweight components must reside
+ * inside a heavyweight window.
+ *
+ * <p>This class is Serializable, which has some big implications. A user can
+ * save the state of all graphical components in one VM, and reload them in
+ * another. Note that this class will only save Serializable listeners, and
+ * ignore the rest, without causing any serialization exceptions. However, by
+ * making a listener serializable, and adding it to another element, you link
+ * in that entire element to the state of this component. To get around this,
+ * use the idiom shown in the example below - make listeners non-serializable
+ * in inner classes, rather than using this object itself as the listener, if
+ * external objects do not need to save the state of this object.
+ *
+ * <pre>
+ * import java.awt.*;
+ * import java.awt.event.*;
+ * import java.io.Serializable;
+ * class MyApp implements Serializable
+ * {
+ * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
+ * // Serializing aButton will not suck in an instance of MyApp, with its
+ * // accompanying field bigOne.
+ * Button aButton = new Button();
+ * class MyActionListener implements ActionListener
+ * {
+ * public void actionPerformed(ActionEvent e)
+ * {
+ * System.out.println("Hello There");
+ * }
+ * }
+ * MyApp()
+ * {
+ * aButton.addActionListener(new MyActionListener());
+ * }
+ * }
+ * </pre>
+ *
+ * <p>Status: Incomplete. The event dispatch mechanism is implemented. All
+ * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
+ * incomplete or only stubs; except for methods relating to the Drag and
+ * Drop, Input Method, and Accessibility frameworks: These methods are
+ * present but commented out.
+ *
+ * @author original author unknown
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ * @status still missing 1.4 support
+ */
+public abstract class Component
+ implements ImageObserver, MenuContainer, Serializable
+{
+ // Word to the wise - this file is huge. Search for '\f' (^L) for logical
+ // sectioning by fields, public API, private API, and nested classes.
+
+
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -7644114512714619750L;
+
+ /**
+ * Constant returned by the <code>getAlignmentY</code> method to indicate
+ * that the component wishes to be aligned to the top relative to
+ * other components.
+ *
+ * @see #getAlignmentY()
+ */
+ public static final float TOP_ALIGNMENT = 0;
+
+ /**
+ * Constant returned by the <code>getAlignmentY</code> and
+ * <code>getAlignmentX</code> methods to indicate
+ * that the component wishes to be aligned to the center relative to
+ * other components.
+ *
+ * @see #getAlignmentX()
+ * @see #getAlignmentY()
+ */
+ public static final float CENTER_ALIGNMENT = 0.5f;
+
+ /**
+ * Constant returned by the <code>getAlignmentY</code> method to indicate
+ * that the component wishes to be aligned to the bottom relative to
+ * other components.
+ *
+ * @see #getAlignmentY()
+ */
+ public static final float BOTTOM_ALIGNMENT = 1;
+
+ /**
+ * Constant returned by the <code>getAlignmentX</code> method to indicate
+ * that the component wishes to be aligned to the right relative to
+ * other components.
+ *
+ * @see #getAlignmentX()
+ */
+ public static final float RIGHT_ALIGNMENT = 1;
+
+ /**
+ * Constant returned by the <code>getAlignmentX</code> method to indicate
+ * that the component wishes to be aligned to the left relative to
+ * other components.
+ *
+ * @see #getAlignmentX()
+ */
+ public static final float LEFT_ALIGNMENT = 0;
+
+ /**
+ * Make the treelock a String so that it can easily be identified
+ * in debug dumps. We clone the String in order to avoid a conflict in
+ * the unlikely event that some other package uses exactly the same string
+ * as a lock object.
+ */
+ static final Object treeLock = new String("AWT_TREE_LOCK");
+
+ // Serialized fields from the serialization spec.
+
+ /**
+ * The x position of the component in the parent's coordinate system.
+ *
+ * @see #getLocation()
+ * @serial the x position
+ */
+ int x;
+
+ /**
+ * The y position of the component in the parent's coordinate system.
+ *
+ * @see #getLocation()
+ * @serial the y position
+ */
+ int y;
+
+ /**
+ * The component width.
+ *
+ * @see #getSize()
+ * @serial the width
+ */
+ int width;
+
+ /**
+ * The component height.
+ *
+ * @see #getSize()
+ * @serial the height
+ */
+ int height;
+
+ /**
+ * The foreground color for the component. This may be null.
+ *
+ * @see #getForeground()
+ * @see #setForeground(Color)
+ * @serial the foreground color
+ */
+ Color foreground;
+
+ /**
+ * The background color for the component. This may be null.
+ *
+ * @see #getBackground()
+ * @see #setBackground(Color)
+ * @serial the background color
+ */
+ Color background;
+
+ /**
+ * The default font used in the component. This may be null.
+ *
+ * @see #getFont()
+ * @see #setFont(Font)
+ * @serial the font
+ */
+ Font font;
+
+ /**
+ * The font in use by the peer, or null if there is no peer.
+ *
+ * @serial the peer's font
+ */
+ Font peerFont;
+
+ /**
+ * The cursor displayed when the pointer is over this component. This may
+ * be null.
+ *
+ * @see #getCursor()
+ * @see #setCursor(Cursor)
+ */
+ Cursor cursor;
+
+ /**
+ * The locale for the component.
+ *
+ * @see #getLocale()
+ * @see #setLocale(Locale)
+ */
+ Locale locale = Locale.getDefault ();
+
+ /**
+ * True if the object should ignore repaint events (usually because it is
+ * not showing).
+ *
+ * @see #getIgnoreRepaint()
+ * @see #setIgnoreRepaint(boolean)
+ * @serial true to ignore repaints
+ * @since 1.4
+ */
+ boolean ignoreRepaint;
+
+ /**
+ * True when the object is visible (although it is only showing if all
+ * ancestors are likewise visible). For component, this defaults to true.
+ *
+ * @see #isVisible()
+ * @see #setVisible(boolean)
+ * @serial true if visible
+ */
+ boolean visible = true;
+
+ /**
+ * True if the object is enabled, meaning it can interact with the user.
+ * For component, this defaults to true.
+ *
+ * @see #isEnabled()
+ * @see #setEnabled(boolean)
+ * @serial true if enabled
+ */
+ boolean enabled = true;
+
+ /**
+ * True if the object is valid. This is set to false any time a size
+ * adjustment means the component need to be layed out again.
+ *
+ * @see #isValid()
+ * @see #validate()
+ * @see #invalidate()
+ * @serial true if layout is valid
+ */
+ boolean valid;
+
+ /**
+ * The DropTarget for drag-and-drop operations.
+ *
+ * @see #getDropTarget()
+ * @see #setDropTarget(DropTarget)
+ * @serial the drop target, or null
+ * @since 1.2
+ */
+ DropTarget dropTarget;
+
+ /**
+ * The list of popup menus for this component.
+ *
+ * @see #add(PopupMenu)
+ * @serial the list of popups
+ */
+ Vector popups;
+
+ /**
+ * The component's name. May be null, in which case a default name is
+ * generated on the first use.
+ *
+ * @see #getName()
+ * @see #setName(String)
+ * @serial the name
+ */
+ String name;
+
+ /**
+ * True once the user has set the name. Note that the user may set the name
+ * to null.
+ *
+ * @see #name
+ * @see #getName()
+ * @see #setName(String)
+ * @serial true if the name has been explicitly set
+ */
+ boolean nameExplicitlySet;
+
+ /**
+ * Indicates if the object can be focused. Defaults to true for components.
+ *
+ * @see #isFocusable()
+ * @see #setFocusable(boolean)
+ * @since 1.4
+ */
+ boolean focusable = true;
+
+ /**
+ * Tracks whether this component's {@link #isFocusTraversable}
+ * method has been overridden.
+ *
+ * @since 1.4
+ */
+ int isFocusTraversableOverridden;
+
+ /**
+ * The focus traversal keys, if not inherited from the parent or
+ * default keyboard focus manager. These sets will contain only
+ * AWTKeyStrokes that represent press and release events to use as
+ * focus control.
+ *
+ * @see #getFocusTraversalKeys(int)
+ * @see #setFocusTraversalKeys(int, Set)
+ * @since 1.4
+ */
+ Set[] focusTraversalKeys;
+
+ /**
+ * True if focus traversal keys are enabled. This defaults to true for
+ * Component. If this is true, keystrokes in focusTraversalKeys are trapped
+ * and processed automatically rather than being passed on to the component.
+ *
+ * @see #getFocusTraversalKeysEnabled()
+ * @see #setFocusTraversalKeysEnabled(boolean)
+ * @since 1.4
+ */
+ boolean focusTraversalKeysEnabled = true;
+
+ /**
+ * Cached information on the minimum size. Should have been transient.
+ *
+ * @serial ignore
+ */
+ Dimension minSize;
+
+ /**
+ * Cached information on the preferred size. Should have been transient.
+ *
+ * @serial ignore
+ */
+ Dimension prefSize;
+
+ /**
+ * Set to true if an event is to be handled by this component, false if
+ * it is to be passed up the hierarcy.
+ *
+ * @see #dispatchEvent(AWTEvent)
+ * @serial true to process event locally
+ */
+ boolean newEventsOnly;
+
+ /**
+ * Set by subclasses to enable event handling of particular events, and
+ * left alone when modifying listeners. For component, this defaults to
+ * enabling only input methods.
+ *
+ * @see #enableInputMethods(boolean)
+ * @see AWTEvent
+ * @serial the mask of events to process
+ */
+ long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK;
+
+ /**
+ * Describes all registered PropertyChangeListeners.
+ *
+ * @see #addPropertyChangeListener(PropertyChangeListener)
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ * @see #firePropertyChange(String, Object, Object)
+ * @serial the property change listeners
+ * @since 1.2
+ */
+ PropertyChangeSupport changeSupport;
+
+ /**
+ * True if the component has been packed (layed out).
+ *
+ * @serial true if this is packed
+ */
+ boolean isPacked;
+
+ /**
+ * The serialization version for this class. Currently at version 4.
+ *
+ * XXX How do we handle prior versions?
+ *
+ * @serial the serialization version
+ */
+ int componentSerializedDataVersion = 4;
+
+ /**
+ * The accessible context associated with this component. This is only set
+ * by subclasses.
+ *
+ * @see #getAccessibleContext()
+ * @serial the accessibility context
+ * @since 1.2
+ */
+ AccessibleContext accessibleContext;
+
+
+ // Guess what - listeners are special cased in serialization. See
+ // readObject and writeObject.
+
+ /** Component listener chain. */
+ transient ComponentListener componentListener;
+
+ /** Focus listener chain. */
+ transient FocusListener focusListener;
+
+ /** Key listener chain. */
+ transient KeyListener keyListener;
+
+ /** Mouse listener chain. */
+ transient MouseListener mouseListener;
+
+ /** Mouse motion listener chain. */
+ transient MouseMotionListener mouseMotionListener;
+
+ /**
+ * Mouse wheel listener chain.
+ *
+ * @since 1.4
+ */
+ transient MouseWheelListener mouseWheelListener;
+
+ /**
+ * Input method listener chain.
+ *
+ * @since 1.2
+ */
+ transient InputMethodListener inputMethodListener;
+
+ /**
+ * Hierarcy listener chain.
+ *
+ * @since 1.3
+ */
+ transient HierarchyListener hierarchyListener;
+
+ /**
+ * Hierarcy bounds listener chain.
+ *
+ * @since 1.3
+ */
+ transient HierarchyBoundsListener hierarchyBoundsListener;
+
+ // Anything else is non-serializable, and should be declared "transient".
+
+ /** The parent. */
+ transient Container parent;
+
+ /** The associated native peer. */
+ transient ComponentPeer peer;
+
+ /** The preferred component orientation. */
+ transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN;
+
+ /**
+ * The associated graphics configuration.
+ *
+ * @since 1.4
+ */
+ transient GraphicsConfiguration graphicsConfig;
+
+ /**
+ * The buffer strategy for repainting.
+ *
+ * @since 1.4
+ */
+ transient BufferStrategy bufferStrategy;
+
+ /**
+ * true if requestFocus was called on this component when its
+ * top-level ancestor was not focusable.
+ */
+ private transient FocusEvent pendingFocusRequest = null;
+
+ /**
+ * The system properties that affect image updating.
+ */
+ private static transient boolean incrementalDraw;
+ private static transient Long redrawRate;
+
+ static
+ {
+ incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
+ redrawRate = Long.getLong ("awt.image.redrawrate");
+ }
+
+ // Public and protected API.
+
+ /**
+ * Default constructor for subclasses. When Component is extended directly,
+ * it forms a lightweight component that must be hosted in an opaque native
+ * container higher in the tree.
+ */
+ protected Component()
+ {
+ }
+
+ /**
+ * Returns the name of this component.
+ *
+ * @return the name of this component
+ * @see #setName(String)
+ * @since 1.1
+ */
+ public String getName()
+ {
+ if (name == null && ! nameExplicitlySet)
+ name = generateName();
+ return name;
+ }
+
+ /**
+ * Sets the name of this component to the specified name.
+ *
+ * @param name the new name of this component
+ * @see #getName()
+ * @since 1.1
+ */
+ public void setName(String name)
+ {
+ nameExplicitlySet = true;
+ this.name = name;
+ }
+
+ /**
+ * Returns the parent of this component.
+ *
+ * @return the parent of this component
+ */
+ public Container getParent()
+ {
+ return parent;
+ }
+
+ /**
+ * Returns the native windowing system peer for this component. Only the
+ * platform specific implementation code should call this method.
+ *
+ * @return the peer for this component
+ * @deprecated user programs should not directly manipulate peers; use
+ * {@link #isDisplayable()} instead
+ */
+ // Classpath's Gtk peers rely on this.
+ public ComponentPeer getPeer()
+ {
+ return peer;
+ }
+
+ /**
+ * Set the associated drag-and-drop target, which receives events when this
+ * is enabled.
+ *
+ * @param dt the new drop target
+ * @see #isEnabled()
+ */
+ public void setDropTarget(DropTarget dt)
+ {
+ this.dropTarget = dt;
+ }
+
+ /**
+ * Gets the associated drag-and-drop target, if there is one.
+ *
+ * @return the drop target
+ */
+ public DropTarget getDropTarget()
+ {
+ return dropTarget;
+ }
+
+ /**
+ * Returns the graphics configuration of this component, if there is one.
+ * If it has not been set, it is inherited from the parent.
+ *
+ * @return the graphics configuration, or null
+ * @since 1.3
+ */
+ public GraphicsConfiguration getGraphicsConfiguration()
+ {
+ return getGraphicsConfigurationImpl();
+ }
+
+ /**
+ * Returns the object used for synchronization locks on this component
+ * when performing tree and layout functions.
+ *
+ * @return the synchronization lock for this component
+ */
+ public final Object getTreeLock()
+ {
+ return treeLock;
+ }
+
+ /**
+ * Returns the toolkit in use for this component. The toolkit is associated
+ * with the frame this component belongs to.
+ *
+ * @return the toolkit for this component
+ */
+ public Toolkit getToolkit()
+ {
+ if (peer != null)
+ {
+ Toolkit tk = peer.getToolkit();
+ if (tk != null)
+ return tk;
+ }
+ // Get toolkit for lightweight component.
+ if (parent != null)
+ return parent.getToolkit();
+ return Toolkit.getDefaultToolkit();
+ }
+
+ /**
+ * Tests whether or not this component is valid. A invalid component needs
+ * to have its layout redone.
+ *
+ * @return true if this component is valid
+ * @see #validate()
+ * @see #invalidate()
+ */
+ public boolean isValid()
+ {
+ return valid;
+ }
+
+ /**
+ * Tests if the component is displayable. It must be connected to a native
+ * screen resource, and all its ancestors must be displayable. A containment
+ * hierarchy is made displayable when a window is packed or made visible.
+ *
+ * @return true if the component is displayable
+ * @see Container#add(Component)
+ * @see Container#remove(Component)
+ * @see Window#pack()
+ * @see Window#show()
+ * @see Window#dispose()
+ * @since 1.2
+ */
+ public boolean isDisplayable()
+ {
+ if (parent != null)
+ return parent.isDisplayable();
+ return false;
+ }
+
+ /**
+ * Tests whether or not this component is visible. Except for top-level
+ * frames, components are initially visible.
+ *
+ * @return true if the component is visible
+ * @see #setVisible(boolean)
+ */
+ public boolean isVisible()
+ {
+ return visible;
+ }
+
+ /**
+ * Tests whether or not this component is actually being shown on
+ * the screen. This will be true if and only if it this component is
+ * visible and its parent components are all visible.
+ *
+ * @return true if the component is showing on the screen
+ * @see #setVisible(boolean)
+ */
+ public boolean isShowing()
+ {
+ if (! visible || peer == null)
+ return false;
+
+ return parent == null ? true : parent.isShowing();
+ }
+
+ /**
+ * Tests whether or not this component is enabled. Components are enabled
+ * by default, and must be enabled to receive user input or generate events.
+ *
+ * @return true if the component is enabled
+ * @see #setEnabled(boolean)
+ */
+ public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ /**
+ * Enables or disables this component. The component must be enabled to
+ * receive events (except that lightweight components always receive mouse
+ * events).
+ *
+ * @param enabled true to enable this component
+ *
+ * @see #isEnabled()
+ * @see #isLightweight()
+ *
+ * @since 1.1
+ */
+ public void setEnabled(boolean enabled)
+ {
+ enable(enabled);
+ }
+
+ /**
+ * Enables this component.
+ *
+ * @deprecated use {@link #setEnabled(boolean)} instead
+ */
+ public void enable()
+ {
+ this.enabled = true;
+ if (peer != null)
+ peer.setEnabled (true);
+ }
+
+ /**
+ * Enables or disables this component.
+ *
+ * @param enabled true to enable this component
+ *
+ * @deprecated use {@link #setEnabled(boolean)} instead
+ */
+ public void enable(boolean enabled)
+ {
+ if (enabled)
+ enable();
+ else
+ disable();
+ }
+
+ /**
+ * Disables this component.
+ *
+ * @deprecated use {@link #setEnabled(boolean)} instead
+ */
+ public void disable()
+ {
+ this.enabled = false;
+ if (peer != null)
+ peer.setEnabled (false);
+ }
+
+ /**
+ * Checks if this image is painted to an offscreen image buffer that is
+ * later copied to screen (double buffering reduces flicker). This version
+ * returns false, so subclasses must override it if they provide double
+ * buffering.
+ *
+ * @return true if this is double buffered; defaults to false
+ */
+ public boolean isDoubleBuffered()
+ {
+ return false;
+ }
+
+ /**
+ * Enables or disables input method support for this component. By default,
+ * components have this enabled. Input methods are given the opportunity
+ * to process key events before this component and its listeners.
+ *
+ * @param enable true to enable input method processing
+ * @see #processKeyEvent(KeyEvent)
+ * @since 1.2
+ */
+ public void enableInputMethods(boolean enable)
+ {
+ if (enable)
+ eventMask |= AWTEvent.INPUT_ENABLED_EVENT_MASK;
+ else
+ eventMask &= ~AWTEvent.INPUT_ENABLED_EVENT_MASK;
+ }
+
+ /**
+ * Makes this component visible or invisible. Note that it wtill might
+ * not show the component, if a parent is invisible.
+ *
+ * @param visible true to make this component visible
+ *
+ * @see #isVisible()
+ *
+ * @since 1.1
+ */
+ public void setVisible(boolean visible)
+ {
+ // Inspection by subclassing shows that Sun's implementation calls
+ // show(boolean) which then calls show() or hide(). It is the show()
+ // method that is overriden in subclasses like Window.
+ show(visible);
+ }
+
+ /**
+ * Makes this component visible on the screen.
+ *
+ * @deprecated use {@link #setVisible(boolean)} instead
+ */
+ public void show()
+ {
+ // We must set visible before showing the peer. Otherwise the
+ // peer could post paint events before visible is true, in which
+ // case lightweight components are not initially painted --
+ // Container.paint first calls isShowing () before painting itself
+ // and its children.
+ if(!isVisible())
+ {
+ this.visible = true;
+ if (peer != null)
+ peer.setVisible(true);
+ invalidate();
+ ComponentEvent ce =
+ new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
+ /**
+ * Makes this component visible or invisible.
+ *
+ * @param visible true to make this component visible
+ *
+ * @deprecated use {@link #setVisible(boolean)} instead
+ */
+ public void show(boolean visible)
+ {
+ if (visible)
+ show();
+ else
+ hide();
+ }
+
+ /**
+ * Hides this component so that it is no longer shown on the screen.
+ *
+ * @deprecated use {@link #setVisible(boolean)} instead
+ */
+ public void hide()
+ {
+ if (isVisible())
+ {
+ if (peer != null)
+ peer.setVisible(false);
+ this.visible = false;
+ invalidate();
+ ComponentEvent ce =
+ new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
+ /**
+ * Returns this component's foreground color. If not set, this is inherited
+ * from the parent.
+ *
+ * @return this component's foreground color, or null
+ * @see #setForeground(Color)
+ */
+ public Color getForeground()
+ {
+ if (foreground != null)
+ return foreground;
+ return parent == null ? SystemColor.windowText : parent.getForeground();
+ }
+
+ /**
+ * Sets this component's foreground color to the specified color. This is a
+ * bound property.
+ *
+ * @param c the new foreground color
+ * @see #getForeground()
+ */
+ public void setForeground(Color c)
+ {
+ firePropertyChange("foreground", foreground, c);
+ if (peer != null)
+ peer.setForeground(c);
+ foreground = c;
+ }
+
+ /**
+ * Tests if the foreground was explicitly set, or just inherited from the
+ * parent.
+ *
+ * @return true if the foreground has been set
+ * @since 1.4
+ */
+ public boolean isForegroundSet()
+ {
+ return foreground != null;
+ }
+
+ /**
+ * Returns this component's background color. If not set, this is inherited
+ * from the parent.
+ *
+ * @return the background color of the component, or null
+ * @see #setBackground(Color)
+ */
+ public Color getBackground()
+ {
+ if (background != null)
+ return background;
+ return parent == null ? SystemColor.window : parent.getBackground();
+ }
+
+ /**
+ * Sets this component's background color to the specified color. The parts
+ * of the component affected by the background color may by system dependent.
+ * This is a bound property.
+ *
+ * @param c the new background color
+ * @see #getBackground()
+ */
+ public void setBackground(Color c)
+ {
+ // return if the background is already set to that color.
+ if (background != null && c != null)
+ if (background.equals(c))
+ return;
+ // If c is null, inherit from closest ancestor whose bg is set.
+ if (c == null && parent != null)
+ c = parent.getBackground();
+ firePropertyChange("background", background, c);
+ if (peer != null && c != null)
+ peer.setBackground(c);
+ background = c;
+ }
+
+ /**
+ * Tests if the background was explicitly set, or just inherited from the
+ * parent.
+ *
+ * @return true if the background has been set
+ * @since 1.4
+ */
+ public boolean isBackgroundSet()
+ {
+ return background != null;
+ }
+
+ /**
+ * Returns the font in use for this component. If not set, this is inherited
+ * from the parent.
+ *
+ * @return the font for this component
+ * @see #setFont(Font)
+ */
+ public Font getFont()
+ {
+ if (font != null)
+ return font;
+
+ if (parent != null)
+ return parent.getFont ();
+ else
+ return new Font ("Dialog", Font.PLAIN, 12);
+ }
+
+ /**
+ * Sets the font for this component to the specified font. This is a bound
+ * property.
+ *
+ * @param newFont the new font for this component
+ *
+ * @see #getFont()
+ */
+ public void setFont(Font newFont)
+ {
+ if (font == newFont)
+ return;
+
+ Font oldFont = font;
+ font = newFont;
+ if (peer != null)
+ peer.setFont(font);
+ firePropertyChange("font", oldFont, newFont);
+ invalidate();
+ }
+
+ /**
+ * Tests if the font was explicitly set, or just inherited from the parent.
+ *
+ * @return true if the font has been set
+ * @since 1.4
+ */
+ public boolean isFontSet()
+ {
+ return font != null;
+ }
+
+ /**
+ * Returns the locale for this component. If this component does not
+ * have a locale, the locale of the parent component is returned.
+ *
+ * @return the locale for this component
+ * @throws IllegalComponentStateException if it has no locale or parent
+ * @see #setLocale(Locale)
+ * @since 1.1
+ */
+ public Locale getLocale()
+ {
+ if (locale != null)
+ return locale;
+ if (parent == null)
+ throw new IllegalComponentStateException
+ ("Component has no parent: can't determine Locale");
+ return parent.getLocale();
+ }
+
+ /**
+ * Sets the locale for this component to the specified locale. This is a
+ * bound property.
+ *
+ * @param newLocale the new locale for this component
+ */
+ public void setLocale(Locale newLocale)
+ {
+ if (locale == newLocale)
+ return;
+
+ Locale oldLocale = locale;
+ locale = newLocale;
+ firePropertyChange("locale", oldLocale, newLocale);
+ // New writing/layout direction or more/less room for localized labels.
+ invalidate();
+ }
+
+ /**
+ * Returns the color model of the device this componet is displayed on.
+ *
+ * @return this object's color model
+ * @see Toolkit#getColorModel()
+ */
+ public ColorModel getColorModel()
+ {
+ GraphicsConfiguration config = getGraphicsConfiguration();
+ return config != null ? config.getColorModel()
+ : getToolkit().getColorModel();
+ }
+
+ /**
+ * Returns the location of this component's top left corner relative to
+ * its parent component. This may be outdated, so for synchronous behavior,
+ * you should use a component listner.
+ *
+ * @return the location of this component
+ * @see #setLocation(int, int)
+ * @see #getLocationOnScreen()
+ * @since 1.1
+ */
+ public Point getLocation()
+ {
+ return location ();
+ }
+
+ /**
+ * Returns the location of this component's top left corner in screen
+ * coordinates.
+ *
+ * @return the location of this component in screen coordinates
+ * @throws IllegalComponentStateException if the component is not showing
+ */
+ public Point getLocationOnScreen()
+ {
+ if (! isShowing())
+ throw new IllegalComponentStateException("component "
+ + getClass().getName()
+ + " not showing");
+ // We know peer != null here.
+ return peer.getLocationOnScreen();
+ }
+
+ /**
+ * Returns the location of this component's top left corner relative to
+ * its parent component.
+ *
+ * @return the location of this component
+ * @deprecated use {@link #getLocation()} instead
+ */
+ public Point location()
+ {
+ return new Point (x, y);
+ }
+
+ /**
+ * Moves this component to the specified location, relative to the parent's
+ * coordinates. The coordinates are the new upper left corner of this
+ * component.
+ *
+ * @param x the new X coordinate of this component
+ * @param y the new Y coordinate of this component
+ * @see #getLocation()
+ * @see #setBounds(int, int, int, int)
+ */
+ public void setLocation(int x, int y)
+ {
+ move (x, y);
+ }
+
+ /**
+ * Moves this component to the specified location, relative to the parent's
+ * coordinates. The coordinates are the new upper left corner of this
+ * component.
+ *
+ * @param x the new X coordinate of this component
+ * @param y the new Y coordinate of this component
+ * @deprecated use {@link #setLocation(int, int)} instead
+ */
+ public void move(int x, int y)
+ {
+ setBounds(x, y, this.width, this.height);
+ }
+
+ /**
+ * Moves this component to the specified location, relative to the parent's
+ * coordinates. The coordinates are the new upper left corner of this
+ * component.
+ *
+ * @param p new coordinates for this component
+ * @throws NullPointerException if p is null
+ * @see #getLocation()
+ * @see #setBounds(int, int, int, int)
+ * @since 1.1
+ */
+ public void setLocation(Point p)
+ {
+ setLocation(p.x, p.y);
+ }
+
+ /**
+ * Returns the size of this object.
+ *
+ * @return the size of this object
+ * @see #setSize(int, int)
+ * @since 1.1
+ */
+ public Dimension getSize()
+ {
+ return size ();
+ }
+
+ /**
+ * Returns the size of this object.
+ *
+ * @return the size of this object
+ * @deprecated use {@link #getSize()} instead
+ */
+ public Dimension size()
+ {
+ return new Dimension (width, height);
+ }
+
+ /**
+ * Sets the size of this component to the specified width and height.
+ *
+ * @param width the new width of this component
+ * @param height the new height of this component
+ * @see #getSize()
+ * @see #setBounds(int, int, int, int)
+ */
+ public void setSize(int width, int height)
+ {
+ resize (width, height);
+ }
+
+ /**
+ * Sets the size of this component to the specified value.
+ *
+ * @param width the new width of the component
+ * @param height the new height of the component
+ * @deprecated use {@link #setSize(int, int)} instead
+ */
+ public void resize(int width, int height)
+ {
+ setBounds(this.x, this.y, width, height);
+ }
+
+ /**
+ * Sets the size of this component to the specified value.
+ *
+ * @param d the new size of this component
+ * @throws NullPointerException if d is null
+ * @see #setSize(int, int)
+ * @see #setBounds(int, int, int, int)
+ * @since 1.1
+ */
+ public void setSize(Dimension d)
+ {
+ resize (d);
+ }
+
+ /**
+ * Sets the size of this component to the specified value.
+ *
+ * @param d the new size of this component
+ * @throws NullPointerException if d is null
+ * @deprecated use {@link #setSize(Dimension)} instead
+ */
+ public void resize(Dimension d)
+ {
+ resize (d.width, d.height);
+ }
+
+ /**
+ * Returns a bounding rectangle for this component. Note that the
+ * returned rectange is relative to this component's parent, not to
+ * the screen.
+ *
+ * @return the bounding rectangle for this component
+ * @see #setBounds(int, int, int, int)
+ * @see #getLocation()
+ * @see #getSize()
+ */
+ public Rectangle getBounds()
+ {
+ return bounds ();
+ }
+
+ /**
+ * Returns a bounding rectangle for this component. Note that the
+ * returned rectange is relative to this component's parent, not to
+ * the screen.
+ *
+ * @return the bounding rectangle for this component
+ * @deprecated use {@link #getBounds()} instead
+ */
+ public Rectangle bounds()
+ {
+ return new Rectangle (x, y, width, height);
+ }
+
+ /**
+ * Sets the bounding rectangle for this component to the specified values.
+ * Note that these coordinates are relative to the parent, not to the screen.
+ *
+ * @param x the X coordinate of the upper left corner of the rectangle
+ * @param y the Y coordinate of the upper left corner of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @see #getBounds()
+ * @see #setLocation(int, int)
+ * @see #setLocation(Point)
+ * @see #setSize(int, int)
+ * @see #setSize(Dimension)
+ * @since 1.1
+ */
+ public void setBounds(int x, int y, int w, int h)
+ {
+ reshape (x, y, w, h);
+ }
+
+ /**
+ * Sets the bounding rectangle for this component to the specified values.
+ * Note that these coordinates are relative to the parent, not to the screen.
+ *
+ * @param x the X coordinate of the upper left corner of the rectangle
+ * @param y the Y coordinate of the upper left corner of the rectangle
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ * @deprecated use {@link #setBounds(int, int, int, int)} instead
+ */
+ public void reshape(int x, int y, int width, int height)
+ {
+ int oldx = this.x;
+ int oldy = this.y;
+ int oldwidth = this.width;
+ int oldheight = this.height;
+
+ if (this.x == x && this.y == y
+ && this.width == width && this.height == height)
+ return;
+ invalidate ();
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ if (peer != null)
+ peer.setBounds (x, y, width, height);
+
+ // Erase old bounds and repaint new bounds for lightweights.
+ if (isLightweight() && isShowing ())
+ {
+ boolean shouldRepaintParent = false;
+ boolean shouldRepaintSelf = false;
+
+ if (parent != null)
+ {
+ Rectangle parentBounds = parent.getBounds();
+ Rectangle oldBounds = new Rectangle(parent.getX() + oldx,
+ parent.getY() + oldy,
+ oldwidth, oldheight);
+ Rectangle newBounds = new Rectangle(parent.getX() + x,
+ parent.getY() + y,
+ width, height);
+ shouldRepaintParent = parentBounds.intersects(oldBounds);
+ shouldRepaintSelf = parentBounds.intersects(newBounds);
+ }
+
+ if (shouldRepaintParent && parent != null)
+ parent.repaint(oldx, oldy, oldwidth, oldheight);
+ if (shouldRepaintSelf)
+ repaint();
+ }
+
+ // Only post event if this component is visible and has changed size.
+ if (isShowing ()
+ && (oldx != x || oldy != y))
+ {
+ ComponentEvent ce = new ComponentEvent(this,
+ ComponentEvent.COMPONENT_MOVED);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ if (isShowing ()
+ && (oldwidth != width || oldheight != height))
+ {
+ ComponentEvent ce = new ComponentEvent(this,
+ ComponentEvent.COMPONENT_RESIZED);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
+ /**
+ * Sets the bounding rectangle for this component to the specified
+ * rectangle. Note that these coordinates are relative to the parent, not
+ * to the screen.
+ *
+ * @param r the new bounding rectangle
+ * @throws NullPointerException if r is null
+ * @see #getBounds()
+ * @see #setLocation(Point)
+ * @see #setSize(Dimension)
+ * @since 1.1
+ */
+ public void setBounds(Rectangle r)
+ {
+ setBounds (r.x, r.y, r.width, r.height);
+ }
+
+ /**
+ * Gets the x coordinate of the upper left corner. This is more efficient
+ * than getBounds().x or getLocation().x.
+ *
+ * @return the current x coordinate
+ * @since 1.2
+ */
+ public int getX()
+ {
+ return x;
+ }
+
+ /**
+ * Gets the y coordinate of the upper left corner. This is more efficient
+ * than getBounds().y or getLocation().y.
+ *
+ * @return the current y coordinate
+ * @since 1.2
+ */
+ public int getY()
+ {
+ return y;
+ }
+
+ /**
+ * Gets the width of the component. This is more efficient than
+ * getBounds().width or getSize().width.
+ *
+ * @return the current width
+ * @since 1.2
+ */
+ public int getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Gets the height of the component. This is more efficient than
+ * getBounds().height or getSize().height.
+ *
+ * @return the current width
+ * @since 1.2
+ */
+ public int getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Returns the bounds of this component. This allows reuse of an existing
+ * rectangle, if r is non-null.
+ *
+ * @param r the rectangle to use, or null
+ * @return the bounds
+ */
+ public Rectangle getBounds(Rectangle r)
+ {
+ if (r == null)
+ r = new Rectangle();
+ r.x = x;
+ r.y = y;
+ r.width = width;
+ r.height = height;
+ return r;
+ }
+
+ /**
+ * Returns the size of this component. This allows reuse of an existing
+ * dimension, if d is non-null.
+ *
+ * @param d the dimension to use, or null
+ * @return the size
+ */
+ public Dimension getSize(Dimension d)
+ {
+ if (d == null)
+ d = new Dimension();
+ d.width = width;
+ d.height = height;
+ return d;
+ }
+
+ /**
+ * Returns the location of this component. This allows reuse of an existing
+ * point, if p is non-null.
+ *
+ * @param p the point to use, or null
+ * @return the location
+ */
+ public Point getLocation(Point p)
+ {
+ if (p == null)
+ p = new Point();
+ p.x = x;
+ p.y = y;
+ return p;
+ }
+
+ /**
+ * Tests if this component is opaque. All "heavyweight" (natively-drawn)
+ * components are opaque. A component is opaque if it draws all pixels in
+ * the bounds; a lightweight component is partially transparent if it lets
+ * pixels underneath show through. Subclasses that guarantee that all pixels
+ * will be drawn should override this.
+ *
+ * @return true if this is opaque
+ * @see #isLightweight()
+ * @since 1.2
+ */
+ public boolean isOpaque()
+ {
+ return ! isLightweight();
+ }
+
+ /**
+ * Return whether the component is lightweight. That means the component has
+ * no native peer, but is displayable. This applies to subclasses of
+ * Component not in this package, such as javax.swing.
+ *
+ * @return true if the component has a lightweight peer
+ * @see #isDisplayable()
+ * @since 1.2
+ */
+ public boolean isLightweight()
+ {
+ return peer instanceof LightweightPeer;
+ }
+
+ /**
+ * Returns the component's preferred size.
+ *
+ * @return the component's preferred size
+ * @see #getMinimumSize()
+ * @see LayoutManager
+ */
+ public Dimension getPreferredSize()
+ {
+ return preferredSize();
+ }
+
+ /**
+ * Returns the component's preferred size.
+ *
+ * @return the component's preferred size
+ * @deprecated use {@link #getPreferredSize()} instead
+ */
+ public Dimension preferredSize()
+ {
+ if (prefSize == null)
+ if (peer == null)
+ return new Dimension(width, height);
+ else
+ prefSize = peer.getPreferredSize();
+ return prefSize;
+ }
+
+ /**
+ * Returns the component's minimum size.
+ *
+ * @return the component's minimum size
+ * @see #getPreferredSize()
+ * @see LayoutManager
+ */
+ public Dimension getMinimumSize()
+ {
+ return minimumSize();
+ }
+
+ /**
+ * Returns the component's minimum size.
+ *
+ * @return the component's minimum size
+ * @deprecated use {@link #getMinimumSize()} instead
+ */
+ public Dimension minimumSize()
+ {
+ if (minSize == null)
+ minSize = (peer != null ? peer.getMinimumSize()
+ : new Dimension(width, height));
+ return minSize;
+ }
+
+ /**
+ * Returns the component's maximum size.
+ *
+ * @return the component's maximum size
+ * @see #getMinimumSize()
+ * @see #getPreferredSize()
+ * @see LayoutManager
+ */
+ public Dimension getMaximumSize()
+ {
+ return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Returns the preferred horizontal alignment of this component. The value
+ * returned will be between {@link #LEFT_ALIGNMENT} and
+ * {@link #RIGHT_ALIGNMENT}, inclusive.
+ *
+ * @return the preferred horizontal alignment of this component
+ */
+ public float getAlignmentX()
+ {
+ return CENTER_ALIGNMENT;
+ }
+
+ /**
+ * Returns the preferred vertical alignment of this component. The value
+ * returned will be between {@link #TOP_ALIGNMENT} and
+ * {@link #BOTTOM_ALIGNMENT}, inclusive.
+ *
+ * @return the preferred vertical alignment of this component
+ */
+ public float getAlignmentY()
+ {
+ return CENTER_ALIGNMENT;
+ }
+
+ /**
+ * Calls the layout manager to re-layout the component. This is called
+ * during validation of a container in most cases.
+ *
+ * @see #validate()
+ * @see LayoutManager
+ */
+ public void doLayout()
+ {
+ layout ();
+ }
+
+ /**
+ * Calls the layout manager to re-layout the component. This is called
+ * during validation of a container in most cases.
+ *
+ * @deprecated use {@link #doLayout()} instead
+ */
+ public void layout()
+ {
+ // Nothing to do unless we're a container.
+ }
+
+ /**
+ * Called to ensure that the layout for this component is valid. This is
+ * usually called on containers.
+ *
+ * @see #invalidate()
+ * @see #doLayout()
+ * @see LayoutManager
+ * @see Container#validate()
+ */
+ public void validate()
+ {
+ valid = true;
+ }
+
+ /**
+ * Invalidates this component and all of its parent components. This will
+ * cause them to have their layout redone. This is called frequently, so
+ * make it fast.
+ */
+ public void invalidate()
+ {
+ valid = false;
+ prefSize = null;
+ minSize = null;
+ if (parent != null && parent.valid)
+ parent.invalidate();
+ }
+
+ /**
+ * Returns a graphics object for this component. Returns <code>null</code>
+ * if this component is not currently displayed on the screen.
+ *
+ * @return a graphics object for this component
+ * @see #paint(Graphics)
+ */
+ public Graphics getGraphics()
+ {
+ if (peer != null)
+ {
+ Graphics gfx = peer.getGraphics();
+ if (gfx != null)
+ return gfx;
+ // create graphics for lightweight:
+ Container parent = getParent();
+ if (parent != null)
+ {
+ gfx = parent.getGraphics();
+ Rectangle bounds = getBounds();
+ gfx.setClip(bounds);
+ gfx.translate(bounds.x, bounds.y);
+ return gfx;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the font metrics for the specified font in this component.
+ *
+ * @param font the font to retrieve metrics for
+ * @return the font metrics for the specified font
+ * @throws NullPointerException if font is null
+ * @see #getFont()
+ * @see Toolkit#getFontMetrics(Font)
+ */
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return peer == null ? getToolkit().getFontMetrics(font)
+ : peer.getFontMetrics(font);
+ }
+
+ /**
+ * Sets the cursor for this component to the specified cursor. The cursor
+ * is displayed when the point is contained by the component, and the
+ * component is visible, displayable, and enabled. This is inherited by
+ * subcomponents unless they set their own cursor.
+ *
+ * @param cursor the new cursor for this component
+ * @see #isEnabled()
+ * @see #isShowing()
+ * @see #getCursor()
+ * @see #contains(int, int)
+ * @see Toolkit#createCustomCursor(Image, Point, String)
+ */
+ public void setCursor(Cursor cursor)
+ {
+ this.cursor = cursor;
+ if (peer != null)
+ peer.setCursor(cursor);
+ }
+
+ /**
+ * Returns the cursor for this component. If not set, this is inherited
+ * from the parent, or from Cursor.getDefaultCursor().
+ *
+ * @return the cursor for this component
+ */
+ public Cursor getCursor()
+ {
+ if (cursor != null)
+ return cursor;
+ return parent != null ? parent.getCursor() : Cursor.getDefaultCursor();
+ }
+
+ /**
+ * Tests if the cursor was explicitly set, or just inherited from the parent.
+ *
+ * @return true if the cursor has been set
+ * @since 1.4
+ */
+ public boolean isCursorSet()
+ {
+ return cursor != null;
+ }
+
+ /**
+ * Paints this component on the screen. The clipping region in the graphics
+ * context will indicate the region that requires painting. This is called
+ * whenever the component first shows, or needs to be repaired because
+ * something was temporarily drawn on top. It is not necessary for
+ * subclasses to call <code>super.paint(g)</code>. Components with no area
+ * are not painted.
+ *
+ * @param g the graphics context for this paint job
+ * @see #update(Graphics)
+ */
+ public void paint(Graphics g)
+ {
+ // Paint the heavyweight peer
+ if (!isLightweight() && peer != null)
+ peer.paint(g);
+ }
+
+ /**
+ * Updates this component. This is called in response to
+ * <code>repaint</code>. This method fills the component with the
+ * background color, then sets the foreground color of the specified
+ * graphics context to the foreground color of this component and calls
+ * the <code>paint()</code> method. The coordinates of the graphics are
+ * relative to this component. Subclasses should call either
+ * <code>super.update(g)</code> or <code>paint(g)</code>.
+ *
+ * @param g the graphics context for this update
+ *
+ * @see #paint(Graphics)
+ * @see #repaint()
+ */
+ public void update(Graphics g)
+ {
+ if (!isLightweight())
+ {
+ Rectangle clip = g.getClipBounds();
+ if (clip == null)
+ g.clearRect(0, 0, width, height);
+ else
+ g.clearRect(clip.x, clip.y, clip.width, clip.height);
+ }
+
+ paint(g);
+ }
+
+ /**
+ * Paints this entire component, including any sub-components.
+ *
+ * @param g the graphics context for this paint job
+ *
+ * @see #paint(Graphics)
+ */
+ public void paintAll(Graphics g)
+ {
+ if (! visible)
+ return;
+ paint(g);
+ }
+
+ /**
+ * Repaint this entire component. The <code>update()</code> method
+ * on this component will be called as soon as possible.
+ *
+ * @see #update(Graphics)
+ * @see #repaint(long, int, int, int, int)
+ */
+ public void repaint()
+ {
+ repaint(0, 0, 0, width, height);
+ }
+
+ /**
+ * Repaint this entire component. The <code>update()</code> method on this
+ * component will be called in approximate the specified number of
+ * milliseconds.
+ *
+ * @param tm milliseconds before this component should be repainted
+ * @see #paint(Graphics)
+ * @see #repaint(long, int, int, int, int)
+ */
+ public void repaint(long tm)
+ {
+ repaint(tm, 0, 0, width, height);
+ }
+
+ /**
+ * Repaints the specified rectangular region within this component. The
+ * <code>update</code> method on this component will be called as soon as
+ * possible. The coordinates are relative to this component.
+ *
+ * @param x the X coordinate of the upper left of the region to repaint
+ * @param y the Y coordinate of the upper left of the region to repaint
+ * @param w the width of the region to repaint
+ * @param h the height of the region to repaint
+ * @see #update(Graphics)
+ * @see #repaint(long, int, int, int, int)
+ */
+ public void repaint(int x, int y, int w, int h)
+ {
+ repaint(0, x, y, w, h);
+ }
+
+ /**
+ * Repaints the specified rectangular region within this component. The
+ * <code>update</code> method on this component will be called in
+ * approximately the specified number of milliseconds. The coordinates
+ * are relative to this component.
+ *
+ * @param tm milliseconds before this component should be repainted
+ * @param x the X coordinate of the upper left of the region to repaint
+ * @param y the Y coordinate of the upper left of the region to repaint
+ * @param width the width of the region to repaint
+ * @param height the height of the region to repaint
+ * @see #update(Graphics)
+ */
+ public void repaint(long tm, int x, int y, int width, int height)
+ {
+ // Handle lightweight repainting by forwarding to native parent
+ if (isLightweight() && parent != null)
+ {
+ if (parent != null)
+ parent.repaint(tm, x + getX(), y + getY(), width, height);
+ }
+ else if (peer != null)
+ peer.repaint(tm, x, y, width, height);
+ }
+
+ /**
+ * Prints this component. This method is provided so that printing can be
+ * done in a different manner from painting. However, the implementation
+ * in this class simply calls the <code>paint()</code> method.
+ *
+ * @param g the graphics context of the print device
+ *
+ * @see #paint(Graphics)
+ */
+ public void print(Graphics g)
+ {
+ paint(g);
+ }
+
+ /**
+ * Prints this component, including all sub-components. This method is
+ * provided so that printing can be done in a different manner from
+ * painting. However, the implementation in this class simply calls the
+ * <code>paintAll()</code> method.
+ *
+ * @param g the graphics context of the print device
+ *
+ * @see #paintAll(Graphics)
+ */
+ public void printAll(Graphics g)
+ {
+ paintAll(g);
+ }
+
+ /**
+ * Called when an image has changed so that this component is repainted.
+ * This incrementally draws an image as more bits are available, when
+ * possible. Incremental drawing is enabled if the system property
+ * <code>awt.image.incrementalDraw</code> is not present or is true, in which
+ * case the redraw rate is set to 100ms or the value of the system property
+ * <code>awt.image.redrawrate</code>.
+ *
+ * <p>The coordinate system used depends on the particular flags.
+ *
+ * @param img the image that has been updated
+ * @param flags tlags as specified in <code>ImageObserver</code>
+ * @param x the X coordinate
+ * @param y the Y coordinate
+ * @param w the width
+ * @param h the height
+ * @return false if the image is completely loaded, loading has been
+ * aborted, or an error has occurred. true if more updates are
+ * required.
+ * @see ImageObserver
+ * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
+ * @see Graphics#drawImage(Image, int, int, ImageObserver)
+ * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
+ * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
+ * @see ImageObserver#imageUpdate(Image, int, int, int, int, int)
+ */
+ public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
+ {
+ if ((flags & (FRAMEBITS | ALLBITS)) != 0)
+ repaint ();
+ else if ((flags & SOMEBITS) != 0)
+ {
+ if (incrementalDraw)
+ {
+ if (redrawRate != null)
+ {
+ long tm = redrawRate.longValue();
+ if (tm < 0)
+ tm = 0;
+ repaint (tm);
+ }
+ else
+ repaint (100);
+ }
+ }
+ return (flags & (ALLBITS | ABORT | ERROR)) == 0;
+ }
+
+ /**
+ * Creates an image from the specified producer.
+ *
+ * @param producer the image procedure to create the image from
+ * @return the resulting image
+ */
+ public Image createImage(ImageProducer producer)
+ {
+ // Sun allows producer to be null.
+ if (peer != null)
+ return peer.createImage(producer);
+ else
+ return getToolkit().createImage(producer);
+ }
+
+ /**
+ * Creates an image with the specified width and height for use in
+ * double buffering. Headless environments do not support images.
+ *
+ * @param width the width of the image
+ * @param height the height of the image
+ * @return the requested image, or null if it is not supported
+ */
+ public Image createImage (int width, int height)
+ {
+ Image returnValue = null;
+ if (!GraphicsEnvironment.isHeadless ())
+ {
+ if (isLightweight () && parent != null)
+ returnValue = parent.createImage (width, height);
+ else if (peer != null)
+ returnValue = peer.createImage (width, height);
+ }
+ return returnValue;
+ }
+
+ /**
+ * Creates an image with the specified width and height for use in
+ * double buffering. Headless environments do not support images.
+ *
+ * @param width the width of the image
+ * @param height the height of the image
+ * @return the requested image, or null if it is not supported
+ * @since 1.4
+ */
+ public VolatileImage createVolatileImage(int width, int height)
+ {
+ if (GraphicsEnvironment.isHeadless())
+ return null;
+ GraphicsConfiguration config = getGraphicsConfiguration();
+ return config == null ? null
+ : config.createCompatibleVolatileImage(width, height);
+ }
+
+ /**
+ * Creates an image with the specified width and height for use in
+ * double buffering. Headless environments do not support images. The image
+ * will support the specified capabilities.
+ *
+ * @param width the width of the image
+ * @param height the height of the image
+ * @param caps the requested capabilities
+ * @return the requested image, or null if it is not supported
+ * @throws AWTException if a buffer with the capabilities cannot be created
+ * @since 1.4
+ */
+ public VolatileImage createVolatileImage(int width, int height,
+ ImageCapabilities caps)
+ throws AWTException
+ {
+ if (GraphicsEnvironment.isHeadless())
+ return null;
+ GraphicsConfiguration config = getGraphicsConfiguration();
+ return config == null ? null
+ : config.createCompatibleVolatileImage(width, height, caps);
+ }
+
+ /**
+ * Prepares the specified image for rendering on this component.
+ *
+ * @param image the image to prepare for rendering
+ * @param observer the observer to notify of image preparation status
+ * @return true if the image is already fully prepared
+ * @throws NullPointerException if image is null
+ */
+ public boolean prepareImage(Image image, ImageObserver observer)
+ {
+ return prepareImage(image, image.getWidth(observer),
+ image.getHeight(observer), observer);
+ }
+
+ /**
+ * Prepares the specified image for rendering on this component at the
+ * specified scaled width and height
+ *
+ * @param image the image to prepare for rendering
+ * @param width the scaled width of the image
+ * @param height the scaled height of the image
+ * @param observer the observer to notify of image preparation status
+ * @return true if the image is already fully prepared
+ */
+ public boolean prepareImage(Image image, int width, int height,
+ ImageObserver observer)
+ {
+ if (peer != null)
+ return peer.prepareImage(image, width, height, observer);
+ else
+ return getToolkit().prepareImage(image, width, height, observer);
+ }
+
+ /**
+ * Returns the status of the loading of the specified image. The value
+ * returned will be those flags defined in <code>ImageObserver</code>.
+ *
+ * @param image the image to check on
+ * @param observer the observer to notify of image loading progress
+ * @return the image observer flags indicating the status of the load
+ * @see #prepareImage(Image, int, int, ImageObserver)
+ * @see Toolkit#checkImage(Image, int, int, ImageObserver)
+ * @throws NullPointerException if image is null
+ */
+ public int checkImage(Image image, ImageObserver observer)
+ {
+ return checkImage(image, -1, -1, observer);
+ }
+
+ /**
+ * Returns the status of the loading of the specified image. The value
+ * returned will be those flags defined in <code>ImageObserver</code>.
+ *
+ * @param image the image to check on
+ * @param width the scaled image width
+ * @param height the scaled image height
+ * @param observer the observer to notify of image loading progress
+ * @return the image observer flags indicating the status of the load
+ * @see #prepareImage(Image, int, int, ImageObserver)
+ * @see Toolkit#checkImage(Image, int, int, ImageObserver)
+ */
+ public int checkImage(Image image, int width, int height,
+ ImageObserver observer)
+ {
+ if (peer != null)
+ return peer.checkImage(image, width, height, observer);
+ return getToolkit().checkImage(image, width, height, observer);
+ }
+
+ /**
+ * Sets whether paint messages delivered by the operating system should be
+ * ignored. This does not affect messages from AWT, except for those
+ * triggered by OS messages. Setting this to true can allow faster
+ * performance in full-screen mode or page-flipping.
+ *
+ * @param ignoreRepaint the new setting for ignoring repaint events
+ * @see #getIgnoreRepaint()
+ * @see BufferStrategy
+ * @see GraphicsDevice#setFullScreenWindow(Window)
+ * @since 1.4
+ */
+ public void setIgnoreRepaint(boolean ignoreRepaint)
+ {
+ this.ignoreRepaint = ignoreRepaint;
+ }
+
+ /**
+ * Test whether paint events from the operating system are ignored.
+ *
+ * @return the status of ignoring paint events
+ * @see #setIgnoreRepaint(boolean)
+ * @since 1.4
+ */
+ public boolean getIgnoreRepaint()
+ {
+ return ignoreRepaint;
+ }
+
+ /**
+ * Tests whether or not the specified point is contained within this
+ * component. Coordinates are relative to this component.
+ *
+ * @param x the X coordinate of the point to test
+ * @param y the Y coordinate of the point to test
+ * @return true if the point is within this component
+ * @see #getComponentAt(int, int)
+ */
+ public boolean contains(int x, int y)
+ {
+ return inside (x, y);
+ }
+
+ /**
+ * Tests whether or not the specified point is contained within this
+ * component. Coordinates are relative to this component.
+ *
+ * @param x the X coordinate of the point to test
+ * @param y the Y coordinate of the point to test
+ * @return true if the point is within this component
+ * @deprecated use {@link #contains(int, int)} instead
+ */
+ public boolean inside(int x, int y)
+ {
+ return x >= 0 && y >= 0 && x < width && y < height;
+ }
+
+ /**
+ * Tests whether or not the specified point is contained within this
+ * component. Coordinates are relative to this component.
+ *
+ * @param p the point to test
+ * @return true if the point is within this component
+ * @throws NullPointerException if p is null
+ * @see #getComponentAt(Point)
+ * @since 1.1
+ */
+ public boolean contains(Point p)
+ {
+ return contains (p.x, p.y);
+ }
+
+ /**
+ * Returns the component occupying the position (x,y). This will either
+ * be this component, an immediate child component, or <code>null</code>
+ * if neither of the first two occupies the specified location.
+ *
+ * @param x the X coordinate to search for components at
+ * @param y the Y coordinate to search for components at
+ * @return the component at the specified location, or null
+ * @see #contains(int, int)
+ */
+ public Component getComponentAt(int x, int y)
+ {
+ return locate (x, y);
+ }
+
+ /**
+ * Returns the component occupying the position (x,y). This will either
+ * be this component, an immediate child component, or <code>null</code>
+ * if neither of the first two occupies the specified location.
+ *
+ * @param x the X coordinate to search for components at
+ * @param y the Y coordinate to search for components at
+ * @return the component at the specified location, or null
+ * @deprecated use {@link #getComponentAt(int, int)} instead
+ */
+ public Component locate(int x, int y)
+ {
+ return contains (x, y) ? this : null;
+ }
+
+ /**
+ * Returns the component occupying the position (x,y). This will either
+ * be this component, an immediate child component, or <code>null</code>
+ * if neither of the first two occupies the specified location.
+ *
+ * @param p the point to search for components at
+ * @return the component at the specified location, or null
+ * @throws NullPointerException if p is null
+ * @see #contains(Point)
+ * @since 1.1
+ */
+ public Component getComponentAt(Point p)
+ {
+ return getComponentAt (p.x, p.y);
+ }
+
+ /**
+ * AWT 1.0 event delivery.
+ *
+ * Deliver an AWT 1.0 event to this Component. This method simply
+ * calls {@link #postEvent}.
+ *
+ * @param e the event to deliver
+ * @deprecated use {@link #dispatchEvent (AWTEvent)} instead
+ */
+ public void deliverEvent (Event e)
+ {
+ postEvent (e);
+ }
+
+ /**
+ * Forwards AWT events to processEvent() if:<ul>
+ * <li>Events have been enabled for this type of event via
+ * <code>enableEvents()</code></li>,
+ * <li>There is at least one registered listener for this type of event</li>
+ * </ul>
+ *
+ * @param e the event to dispatch
+ */
+ public final void dispatchEvent(AWTEvent e)
+ {
+ // Some subclasses in the AWT package need to override this behavior,
+ // hence the use of dispatchEventImpl().
+ dispatchEventImpl(e);
+ if (peer != null && ! e.consumed)
+ peer.handleEvent(e);
+ }
+
+ /**
+ * AWT 1.0 event handler.
+ *
+ * This method simply calls handleEvent and returns the result.
+ *
+ * @param e the event to handle
+ * @return true if the event was handled, false otherwise
+ * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
+ */
+ public boolean postEvent (Event e)
+ {
+ boolean handled = handleEvent (e);
+
+ if (!handled && getParent() != null)
+ // FIXME: need to translate event coordinates to parent's
+ // coordinate space.
+ handled = getParent ().postEvent (e);
+
+ return handled;
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see ComponentEvent
+ * @see #removeComponentListener(ComponentListener)
+ * @see #getComponentListeners()
+ * @since 1.1
+ */
+ public synchronized void addComponentListener(ComponentListener listener)
+ {
+ componentListener = AWTEventMulticaster.add(componentListener, listener);
+ if (componentListener != null)
+ enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see ComponentEvent
+ * @see #addComponentListener(ComponentListener)
+ * @see #getComponentListeners()
+ * @since 1.1
+ */
+ public synchronized void removeComponentListener(ComponentListener listener)
+ {
+ componentListener = AWTEventMulticaster.remove(componentListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addComponentListener(ComponentListener)
+ * @see #removeComponentListener(ComponentListener)
+ * @since 1.4
+ */
+ public synchronized ComponentListener[] getComponentListeners()
+ {
+ return (ComponentListener[])
+ AWTEventMulticaster.getListeners(componentListener,
+ ComponentListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see FocusEvent
+ * @see #removeFocusListener(FocusListener)
+ * @see #getFocusListeners()
+ * @since 1.1
+ */
+ public synchronized void addFocusListener(FocusListener listener)
+ {
+ focusListener = AWTEventMulticaster.add(focusListener, listener);
+ if (focusListener != null)
+ enableEvents(AWTEvent.FOCUS_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see FocusEvent
+ * @see #addFocusListener(FocusListener)
+ * @see #getFocusListeners()
+ * @since 1.1
+ */
+ public synchronized void removeFocusListener(FocusListener listener)
+ {
+ focusListener = AWTEventMulticaster.remove(focusListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addFocusListener(FocusListener)
+ * @see #removeFocusListener(FocusListener)
+ * @since 1.4
+ */
+ public synchronized FocusListener[] getFocusListeners()
+ {
+ return (FocusListener[])
+ AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see HierarchyEvent
+ * @see #removeHierarchyListener(HierarchyListener)
+ * @see #getHierarchyListeners()
+ * @since 1.3
+ */
+ public synchronized void addHierarchyListener(HierarchyListener listener)
+ {
+ hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener);
+ if (hierarchyListener != null)
+ enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see HierarchyEvent
+ * @see #addHierarchyListener(HierarchyListener)
+ * @see #getHierarchyListeners()
+ * @since 1.3
+ */
+ public synchronized void removeHierarchyListener(HierarchyListener listener)
+ {
+ hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addHierarchyListener(HierarchyListener)
+ * @see #removeHierarchyListener(HierarchyListener)
+ * @since 1.4
+ */
+ public synchronized HierarchyListener[] getHierarchyListeners()
+ {
+ return (HierarchyListener[])
+ AWTEventMulticaster.getListeners(hierarchyListener,
+ HierarchyListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see HierarchyEvent
+ * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
+ * @see #getHierarchyBoundsListeners()
+ * @since 1.3
+ */
+ public synchronized void
+ addHierarchyBoundsListener(HierarchyBoundsListener listener)
+ {
+ hierarchyBoundsListener =
+ AWTEventMulticaster.add(hierarchyBoundsListener, listener);
+ if (hierarchyBoundsListener != null)
+ enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see HierarchyEvent
+ * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
+ * @see #getHierarchyBoundsListeners()
+ * @since 1.3
+ */
+ public synchronized void
+ removeHierarchyBoundsListener(HierarchyBoundsListener listener)
+ {
+ hierarchyBoundsListener =
+ AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
+ * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
+ * @since 1.4
+ */
+ public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
+ {
+ return (HierarchyBoundsListener[])
+ AWTEventMulticaster.getListeners(hierarchyBoundsListener,
+ HierarchyBoundsListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see KeyEvent
+ * @see #removeKeyListener(KeyListener)
+ * @see #getKeyListeners()
+ * @since 1.1
+ */
+ public synchronized void addKeyListener(KeyListener listener)
+ {
+ keyListener = AWTEventMulticaster.add(keyListener, listener);
+ if (keyListener != null)
+ enableEvents(AWTEvent.KEY_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see KeyEvent
+ * @see #addKeyListener(KeyListener)
+ * @see #getKeyListeners()
+ * @since 1.1
+ */
+ public synchronized void removeKeyListener(KeyListener listener)
+ {
+ keyListener = AWTEventMulticaster.remove(keyListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addKeyListener(KeyListener)
+ * @see #removeKeyListener(KeyListener)
+ * @since 1.4
+ */
+ public synchronized KeyListener[] getKeyListeners()
+ {
+ return (KeyListener[])
+ AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see MouseEvent
+ * @see #removeMouseListener(MouseListener)
+ * @see #getMouseListeners()
+ * @since 1.1
+ */
+ public synchronized void addMouseListener(MouseListener listener)
+ {
+ mouseListener = AWTEventMulticaster.add(mouseListener, listener);
+ if (mouseListener != null)
+ enableEvents(AWTEvent.MOUSE_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see MouseEvent
+ * @see #addMouseListener(MouseListener)
+ * @see #getMouseListeners()
+ * @since 1.1
+ */
+ public synchronized void removeMouseListener(MouseListener listener)
+ {
+ mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addMouseListener(MouseListener)
+ * @see #removeMouseListener(MouseListener)
+ * @since 1.4
+ */
+ public synchronized MouseListener[] getMouseListeners()
+ {
+ return (MouseListener[])
+ AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see MouseEvent
+ * @see #removeMouseMotionListener(MouseMotionListener)
+ * @see #getMouseMotionListeners()
+ * @since 1.1
+ */
+ public synchronized void addMouseMotionListener(MouseMotionListener listener)
+ {
+ mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
+ if (mouseMotionListener != null)
+ enableEvents(AWTEvent.MOUSE_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see MouseEvent
+ * @see #addMouseMotionListener(MouseMotionListener)
+ * @see #getMouseMotionListeners()
+ * @since 1.1
+ */
+ public synchronized void removeMouseMotionListener(MouseMotionListener listener)
+ {
+ mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addMouseMotionListener(MouseMotionListener)
+ * @see #removeMouseMotionListener(MouseMotionListener)
+ * @since 1.4
+ */
+ public synchronized MouseMotionListener[] getMouseMotionListeners()
+ {
+ return (MouseMotionListener[])
+ AWTEventMulticaster.getListeners(mouseMotionListener,
+ MouseMotionListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see MouseEvent
+ * @see MouseWheelEvent
+ * @see #removeMouseWheelListener(MouseWheelListener)
+ * @see #getMouseWheelListeners()
+ * @since 1.4
+ */
+ public synchronized void addMouseWheelListener(MouseWheelListener listener)
+ {
+ mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, listener);
+ if (mouseWheelListener != null)
+ enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see MouseEvent
+ * @see MouseWheelEvent
+ * @see #addMouseWheelListener(MouseWheelListener)
+ * @see #getMouseWheelListeners()
+ * @since 1.4
+ */
+ public synchronized void removeMouseWheelListener(MouseWheelListener listener)
+ {
+ mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addMouseWheelListener(MouseWheelListener)
+ * @see #removeMouseWheelListener(MouseWheelListener)
+ * @since 1.4
+ */
+ public synchronized MouseWheelListener[] getMouseWheelListeners()
+ {
+ return (MouseWheelListener[])
+ AWTEventMulticaster.getListeners(mouseWheelListener,
+ MouseWheelListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this component. This is harmless if the
+ * listener is null, but if the listener has already been registered, it
+ * will now be registered twice.
+ *
+ * @param listener the new listener to add
+ * @see InputMethodEvent
+ * @see #removeInputMethodListener(InputMethodListener)
+ * @see #getInputMethodListeners()
+ * @see #getInputMethodRequests()
+ * @since 1.2
+ */
+ public synchronized void addInputMethodListener(InputMethodListener listener)
+ {
+ inputMethodListener = AWTEventMulticaster.add(inputMethodListener, listener);
+ if (inputMethodListener != null)
+ enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the component. This is harmless if
+ * the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see InputMethodEvent
+ * @see #addInputMethodListener(InputMethodListener)
+ * @see #getInputMethodRequests()
+ * @since 1.2
+ */
+ public synchronized void removeInputMethodListener(InputMethodListener listener)
+ {
+ inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addInputMethodListener(InputMethodListener)
+ * @see #removeInputMethodListener(InputMethodListener)
+ * @since 1.4
+ */
+ public synchronized InputMethodListener[] getInputMethodListeners()
+ {
+ return (InputMethodListener[])
+ AWTEventMulticaster.getListeners(inputMethodListener,
+ InputMethodListener.class);
+ }
+
+ /**
+ * Returns all registered EventListers of the given listenerType.
+ *
+ * @param listenerType the class of listeners to filter
+ * @return an array of registered listeners
+ * @see #getComponentListeners()
+ * @see #getFocusListeners()
+ * @see #getHierarchyListeners()
+ * @see #getHierarchyBoundsListeners()
+ * @see #getKeyListeners()
+ * @see #getMouseListeners()
+ * @see #getMouseMotionListeners()
+ * @see #getMouseWheelListeners()
+ * @see #getInputMethodListeners()
+ * @see #getPropertyChangeListeners()
+ * @since 1.3
+ */
+ public EventListener[] getListeners(Class listenerType)
+ {
+ if (listenerType == ComponentListener.class)
+ return getComponentListeners();
+ if (listenerType == FocusListener.class)
+ return getFocusListeners();
+ if (listenerType == HierarchyListener.class)
+ return getHierarchyListeners();
+ if (listenerType == HierarchyBoundsListener.class)
+ return getHierarchyBoundsListeners();
+ if (listenerType == KeyListener.class)
+ return getKeyListeners();
+ if (listenerType == MouseListener.class)
+ return getMouseListeners();
+ if (listenerType == MouseMotionListener.class)
+ return getMouseMotionListeners();
+ if (listenerType == MouseWheelListener.class)
+ return getMouseWheelListeners();
+ if (listenerType == InputMethodListener.class)
+ return getInputMethodListeners();
+ if (listenerType == PropertyChangeListener.class)
+ return getPropertyChangeListeners();
+ return (EventListener[]) Array.newInstance(listenerType, 0);
+ }
+
+ /**
+ * Returns the input method request handler, for subclasses which support
+ * on-the-spot text input. By default, input methods are handled by AWT,
+ * and this returns null.
+ *
+ * @return the input method handler, null by default
+ * @since 1.2
+ */
+ public InputMethodRequests getInputMethodRequests()
+ {
+ return null;
+ }
+
+ /**
+ * Gets the input context of this component, which is inherited from the
+ * parent unless this is overridden.
+ *
+ * @return the text input context
+ * @since 1.2
+ */
+ public InputContext getInputContext()
+ {
+ return parent == null ? null : parent.getInputContext();
+ }
+
+ /**
+ * Enables the specified events. The events to enable are specified
+ * by OR-ing together the desired masks from <code>AWTEvent</code>.
+ *
+ * <p>Events are enabled by default when a listener is attached to the
+ * component for that event type. This method can be used by subclasses
+ * to ensure the delivery of a specified event regardless of whether
+ * or not a listener is attached.
+ *
+ * @param eventsToEnable the desired events to enable
+ * @see #processEvent(AWTEvent)
+ * @see #disableEvents(long)
+ * @see AWTEvent
+ * @since 1.1
+ */
+ protected final void enableEvents(long eventsToEnable)
+ {
+ eventMask |= eventsToEnable;
+ // TODO: Unlike Sun's implementation, I think we should try and
+ // enable/disable events at the peer (gtk/X) level. This will avoid
+ // clogging the event pipeline with useless mousemove events that
+ // we arn't interested in, etc. This will involve extending the peer
+ // interface, but thats okay because the peer interfaces have been
+ // deprecated for a long time, and no longer feature in the
+ // API specification at all.
+ if (isLightweight() && parent != null)
+ parent.enableEvents(eventsToEnable);
+ else if (peer != null)
+ peer.setEventMask(eventMask);
+ }
+
+ /**
+ * Disables the specified events. The events to disable are specified
+ * by OR-ing together the desired masks from <code>AWTEvent</code>.
+ *
+ * @param eventsToDisable the desired events to disable
+ * @see #enableEvents(long)
+ * @since 1.1
+ */
+ protected final void disableEvents(long eventsToDisable)
+ {
+ eventMask &= ~eventsToDisable;
+ // forward new event mask to peer?
+ }
+
+ /**
+ * This is called by the EventQueue if two events with the same event id
+ * and owner component are queued. Returns a new combined event, or null if
+ * no combining is done. The coelesced events are currently mouse moves
+ * (intermediate ones are discarded) and paint events (a merged paint is
+ * created in place of the two events).
+ *
+ * @param existingEvent the event on the queue
+ * @param newEvent the new event that might be entered on the queue
+ * @return null if both events are kept, or the replacement coelesced event
+ */
+ protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
+ {
+ switch (existingEvent.id)
+ {
+ case MouseEvent.MOUSE_MOVED:
+ case MouseEvent.MOUSE_DRAGGED:
+ // Just drop the old (intermediate) event and return the new one.
+ return newEvent;
+ case PaintEvent.PAINT:
+ case PaintEvent.UPDATE:
+ return coalescePaintEvents((PaintEvent) existingEvent,
+ (PaintEvent) newEvent);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Processes the specified event. In this class, this method simply
+ * calls one of the more specific event handlers.
+ *
+ * @param e the event to process
+ * @throws NullPointerException if e is null
+ * @see #processComponentEvent(ComponentEvent)
+ * @see #processFocusEvent(FocusEvent)
+ * @see #processKeyEvent(KeyEvent)
+ * @see #processMouseEvent(MouseEvent)
+ * @see #processMouseMotionEvent(MouseEvent)
+ * @see #processInputMethodEvent(InputMethodEvent)
+ * @see #processHierarchyEvent(HierarchyEvent)
+ * @see #processMouseWheelEvent(MouseWheelEvent)
+ * @since 1.1
+ */
+ protected void processEvent(AWTEvent e)
+ {
+ /* Note: the order of these if statements are
+ important. Subclasses must be checked first. Eg. MouseEvent
+ must be checked before ComponentEvent, since a MouseEvent
+ object is also an instance of a ComponentEvent. */
+
+ if (e instanceof FocusEvent)
+ processFocusEvent((FocusEvent) e);
+ else if (e instanceof MouseWheelEvent)
+ processMouseWheelEvent((MouseWheelEvent) e);
+ else if (e instanceof MouseEvent)
+ {
+ if (e.id == MouseEvent.MOUSE_MOVED
+ || e.id == MouseEvent.MOUSE_DRAGGED)
+ processMouseMotionEvent((MouseEvent) e);
+ else
+ processMouseEvent((MouseEvent) e);
+ }
+ else if (e instanceof KeyEvent)
+ processKeyEvent((KeyEvent) e);
+ else if (e instanceof InputMethodEvent)
+ processInputMethodEvent((InputMethodEvent) e);
+ else if (e instanceof ComponentEvent)
+ processComponentEvent((ComponentEvent) e);
+ else if (e instanceof HierarchyEvent)
+ {
+ if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
+ processHierarchyEvent((HierarchyEvent) e);
+ else
+ processHierarchyBoundsEvent((HierarchyEvent) e);
+ }
+ }
+
+ /**
+ * Called when a component event is dispatched and component events are
+ * enabled. This method passes the event along to any listeners
+ * that are attached.
+ *
+ * @param e the <code>ComponentEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see ComponentListener
+ * @see #addComponentListener(ComponentListener)
+ * @see #enableEvents(long)
+ * @since 1.1
+ */
+ protected void processComponentEvent(ComponentEvent e)
+ {
+ if (componentListener == null)
+ return;
+ switch (e.id)
+ {
+ case ComponentEvent.COMPONENT_HIDDEN:
+ componentListener.componentHidden(e);
+ break;
+ case ComponentEvent.COMPONENT_MOVED:
+ componentListener.componentMoved(e);
+ break;
+ case ComponentEvent.COMPONENT_RESIZED:
+ componentListener.componentResized(e);
+ break;
+ case ComponentEvent.COMPONENT_SHOWN:
+ componentListener.componentShown(e);
+ break;
+ }
+ }
+
+ /**
+ * Called when a focus event is dispatched and component events are
+ * enabled. This method passes the event along to any listeners
+ * that are attached.
+ *
+ * @param e the <code>FocusEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see FocusListener
+ * @see #addFocusListener(FocusListener)
+ * @see #enableEvents(long)
+ * @since 1.1
+ */
+ protected void processFocusEvent(FocusEvent e)
+ {
+ if (focusListener == null)
+ return;
+
+ switch (e.id)
+ {
+ case FocusEvent.FOCUS_GAINED:
+ focusListener.focusGained(e);
+ break;
+ case FocusEvent.FOCUS_LOST:
+ focusListener.focusLost(e);
+ break;
+ }
+ }
+
+ /**
+ * Called when a key event is dispatched and component events are
+ * enabled. This method passes the event along to any listeners
+ * that are attached.
+ *
+ * @param e the <code>KeyEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see KeyListener
+ * @see #addKeyListener(KeyListener)
+ * @see #enableEvents(long)
+ * @since 1.1
+ */
+ protected void processKeyEvent(KeyEvent e)
+ {
+ if (keyListener == null)
+ return;
+ switch (e.id)
+ {
+ case KeyEvent.KEY_PRESSED:
+ keyListener.keyPressed(e);
+ break;
+ case KeyEvent.KEY_RELEASED:
+ keyListener.keyReleased(e);
+ break;
+ case KeyEvent.KEY_TYPED:
+ keyListener.keyTyped(e);
+ break;
+ }
+ }
+
+ /**
+ * Called when a regular mouse event is dispatched and component events are
+ * enabled. This method passes the event along to any listeners
+ * that are attached.
+ *
+ * @param e the <code>MouseEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see MouseListener
+ * @see #addMouseListener(MouseListener)
+ * @see #enableEvents(long)
+ * @since 1.1
+ */
+ protected void processMouseEvent(MouseEvent e)
+ {
+ if (mouseListener == null)
+ return;
+ switch (e.id)
+ {
+ case MouseEvent.MOUSE_CLICKED:
+ mouseListener.mouseClicked(e);
+ break;
+ case MouseEvent.MOUSE_ENTERED:
+ mouseListener.mouseEntered(e);
+ break;
+ case MouseEvent.MOUSE_EXITED:
+ mouseListener.mouseExited(e);
+ break;
+ case MouseEvent.MOUSE_PRESSED:
+ mouseListener.mousePressed(e);
+ break;
+ case MouseEvent.MOUSE_RELEASED:
+ mouseListener.mouseReleased(e);
+ break;
+ }
+ e.consume();
+ }
+
+ /**
+ * Called when a mouse motion event is dispatched and component events are
+ * enabled. This method passes the event along to any listeners
+ * that are attached.
+ *
+ * @param e the <code>MouseMotionEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see MouseMotionListener
+ * @see #addMouseMotionListener(MouseMotionListener)
+ * @see #enableEvents(long)
+ * @since 1.1
+ */
+ protected void processMouseMotionEvent(MouseEvent e)
+ {
+ if (mouseMotionListener == null)
+ return;
+ switch (e.id)
+ {
+ case MouseEvent.MOUSE_DRAGGED:
+ mouseMotionListener.mouseDragged(e);
+ break;
+ case MouseEvent.MOUSE_MOVED:
+ mouseMotionListener.mouseMoved(e);
+ break;
+ }
+ e.consume();
+ }
+
+ /**
+ * Called when a mouse wheel event is dispatched and component events are
+ * enabled. This method passes the event along to any listeners that are
+ * attached.
+ *
+ * @param e the <code>MouseWheelEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see MouseWheelListener
+ * @see #addMouseWheelListener(MouseWheelListener)
+ * @see #enableEvents(long)
+ * @since 1.4
+ */
+ protected void processMouseWheelEvent(MouseWheelEvent e)
+ {
+ if (mouseWheelListener != null
+ && e.id == MouseEvent.MOUSE_WHEEL)
+ {
+ mouseWheelListener.mouseWheelMoved(e);
+ e.consume();
+ }
+ }
+
+ /**
+ * Called when an input method event is dispatched and component events are
+ * enabled. This method passes the event along to any listeners that are
+ * attached.
+ *
+ * @param e the <code>InputMethodEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see InputMethodListener
+ * @see #addInputMethodListener(InputMethodListener)
+ * @see #enableEvents(long)
+ * @since 1.2
+ */
+ protected void processInputMethodEvent(InputMethodEvent e)
+ {
+ if (inputMethodListener == null)
+ return;
+ switch (e.id)
+ {
+ case InputMethodEvent.CARET_POSITION_CHANGED:
+ inputMethodListener.caretPositionChanged(e);
+ break;
+ case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
+ inputMethodListener.inputMethodTextChanged(e);
+ break;
+ }
+ }
+
+ /**
+ * Called when a hierarchy change event is dispatched and component events
+ * are enabled. This method passes the event along to any listeners that are
+ * attached.
+ *
+ * @param e the <code>HierarchyEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see HierarchyListener
+ * @see #addHierarchyListener(HierarchyListener)
+ * @see #enableEvents(long)
+ * @since 1.3
+ */
+ protected void processHierarchyEvent(HierarchyEvent e)
+ {
+ if (hierarchyListener == null)
+ return;
+ if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
+ hierarchyListener.hierarchyChanged(e);
+ }
+
+ /**
+ * Called when a hierarchy bounds event is dispatched and component events
+ * are enabled. This method passes the event along to any listeners that are
+ * attached.
+ *
+ * @param e the <code>HierarchyEvent</code> to process
+ * @throws NullPointerException if e is null
+ * @see HierarchyBoundsListener
+ * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
+ * @see #enableEvents(long)
+ * @since 1.3
+ */
+ protected void processHierarchyBoundsEvent(HierarchyEvent e)
+ {
+ if (hierarchyBoundsListener == null)
+ return;
+ switch (e.id)
+ {
+ case HierarchyEvent.ANCESTOR_MOVED:
+ hierarchyBoundsListener.ancestorMoved(e);
+ break;
+ case HierarchyEvent.ANCESTOR_RESIZED:
+ hierarchyBoundsListener.ancestorResized(e);
+ break;
+ }
+ }
+
+ /**
+ * AWT 1.0 event handler.
+ *
+ * This method calls one of the event-specific handler methods. For
+ * example for key events, either {@link #keyDown(Event,int)}
+ * or {@link #keyUp(Event,int)} is called. A derived
+ * component can override one of these event-specific methods if it
+ * only needs to handle certain event types. Otherwise it can
+ * override handleEvent itself and handle any event.
+ *
+ * @param evt the event to handle
+ * @return true if the event was handled, false otherwise
+ * @deprecated use {@link #processEvent(AWTEvent)} instead
+ */
+ public boolean handleEvent (Event evt)
+ {
+ switch (evt.id)
+ {
+ // Handle key events.
+ case Event.KEY_ACTION:
+ case Event.KEY_PRESS:
+ return keyDown (evt, evt.key);
+ case Event.KEY_ACTION_RELEASE:
+ case Event.KEY_RELEASE:
+ return keyUp (evt, evt.key);
+
+ // Handle mouse events.
+ case Event.MOUSE_DOWN:
+ return mouseDown (evt, evt.x, evt.y);
+ case Event.MOUSE_UP:
+ return mouseUp (evt, evt.x, evt.y);
+ case Event.MOUSE_MOVE:
+ return mouseMove (evt, evt.x, evt.y);
+ case Event.MOUSE_DRAG:
+ return mouseDrag (evt, evt.x, evt.y);
+ case Event.MOUSE_ENTER:
+ return mouseEnter (evt, evt.x, evt.y);
+ case Event.MOUSE_EXIT:
+ return mouseExit (evt, evt.x, evt.y);
+
+ // Handle focus events.
+ case Event.GOT_FOCUS:
+ return gotFocus (evt, evt.arg);
+ case Event.LOST_FOCUS:
+ return lostFocus (evt, evt.arg);
+
+ // Handle action event.
+ case Event.ACTION_EVENT:
+ return action (evt, evt.arg);
+ }
+ // Unknown event.
+ return false;
+ }
+
+ /**
+ * AWT 1.0 MOUSE_DOWN event handler. This method is meant to be
+ * overridden by components providing their own MOUSE_DOWN handler.
+ * The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param x the x coordinate, ignored
+ * @param y the y coordinate, ignored
+ * @return false
+ * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
+ */
+ public boolean mouseDown(Event evt, int x, int y)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 MOUSE_DRAG event handler. This method is meant to be
+ * overridden by components providing their own MOUSE_DRAG handler.
+ * The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param x the x coordinate, ignored
+ * @param y the y coordinate, ignored
+ * @return false
+ * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
+ */
+ public boolean mouseDrag(Event evt, int x, int y)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 MOUSE_UP event handler. This method is meant to be
+ * overridden by components providing their own MOUSE_UP handler.
+ * The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param x the x coordinate, ignored
+ * @param y the y coordinate, ignored
+ * @return false
+ * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
+ */
+ public boolean mouseUp(Event evt, int x, int y)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 MOUSE_MOVE event handler. This method is meant to be
+ * overridden by components providing their own MOUSE_MOVE handler.
+ * The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param x the x coordinate, ignored
+ * @param y the y coordinate, ignored
+ * @return false
+ * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
+ */
+ public boolean mouseMove(Event evt, int x, int y)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 MOUSE_ENTER event handler. This method is meant to be
+ * overridden by components providing their own MOUSE_ENTER handler.
+ * The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param x the x coordinate, ignored
+ * @param y the y coordinate, ignored
+ * @return false
+ * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
+ */
+ public boolean mouseEnter(Event evt, int x, int y)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 MOUSE_EXIT event handler. This method is meant to be
+ * overridden by components providing their own MOUSE_EXIT handler.
+ * The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param x the x coordinate, ignored
+ * @param y the y coordinate, ignored
+ * @return false
+ * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
+ */
+ public boolean mouseExit(Event evt, int x, int y)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 KEY_PRESS and KEY_ACTION event handler. This method is
+ * meant to be overridden by components providing their own key
+ * press handler. The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param key the key pressed, ignored
+ * @return false
+ * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
+ */
+ public boolean keyDown(Event evt, int key)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler. This
+ * method is meant to be overridden by components providing their
+ * own key release handler. The default implementation simply
+ * returns false.
+ *
+ * @param evt the event to handle
+ * @param key the key pressed, ignored
+ * @return false
+ * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
+ */
+ public boolean keyUp(Event evt, int key)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 ACTION_EVENT event handler. This method is meant to be
+ * overridden by components providing their own action event
+ * handler. The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param what the object acted on, ignored
+ * @return false
+ * @deprecated in classes which support actions, use
+ * <code>processActionEvent(ActionEvent)</code> instead
+ */
+ public boolean action(Event evt, Object what)
+ {
+ return false;
+ }
+
+ /**
+ * Called to inform this component it has been added to a container.
+ * A native peer - if any - is created at this time. This method is
+ * called automatically by the AWT system and should not be called by
+ * user level code.
+ *
+ * @see #isDisplayable()
+ * @see #removeNotify()
+ */
+ public void addNotify()
+ {
+ if (peer == null)
+ peer = getToolkit().createComponent(this);
+ /* Now that all the children has gotten their peers, we should
+ have the event mask needed for this component and its
+ lightweight subcomponents. */
+ peer.setEventMask(eventMask);
+ /* We do not invalidate here, but rather leave that job up to
+ the peer. For efficiency, the peer can choose not to
+ invalidate if it is happy with the current dimensions,
+ etc. */
+ }
+
+ /**
+ * Called to inform this component is has been removed from its
+ * container. Its native peer - if any - is destroyed at this time.
+ * This method is called automatically by the AWT system and should
+ * not be called by user level code.
+ *
+ * @see #isDisplayable()
+ * @see #addNotify()
+ */
+ public void removeNotify()
+ {
+ // We null our peer field before disposing of it, such that if we're
+ // not the event dispatch thread and the dispatch thread is awoken by
+ // the dispose call, there will be no race checking the peer's null
+ // status.
+
+ ComponentPeer tmp = peer;
+ peer = null;
+ if (tmp != null)
+ tmp.dispose();
+ }
+
+ /**
+ * AWT 1.0 GOT_FOCUS event handler. This method is meant to be
+ * overridden by components providing their own GOT_FOCUS handler.
+ * The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param what the Object focused, ignored
+ * @return false
+ * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
+ */
+ public boolean gotFocus(Event evt, Object what)
+ {
+ return false;
+ }
+
+ /**
+ * AWT 1.0 LOST_FOCUS event handler. This method is meant to be
+ * overridden by components providing their own LOST_FOCUS handler.
+ * The default implementation simply returns false.
+ *
+ * @param evt the event to handle
+ * @param what the Object focused, ignored
+ * @return false
+ * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
+ */
+ public boolean lostFocus(Event evt, Object what)
+ {
+ return false;
+ }
+
+ /**
+ * Tests whether or not this component is in the group that can be
+ * traversed using the keyboard traversal mechanism (such as the TAB key).
+ *
+ * @return true if the component is traversed via the TAB key
+ * @see #setFocusable(boolean)
+ * @since 1.1
+ * @deprecated use {@link #isFocusable()} instead
+ */
+ public boolean isFocusTraversable()
+ {
+ return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable());
+ }
+
+ /**
+ * Tests if this component can receive focus.
+ *
+ * @return true if this component can receive focus
+ * @since 1.4
+ */
+ public boolean isFocusable()
+ {
+ return focusable;
+ }
+
+ /**
+ * Specify whether this component can receive focus. This method also
+ * sets the {@link #isFocusTraversableOverridden} field to 1, which
+ * appears to be the undocumented way {@link
+ * DefaultFocusTraversalPolicy#accept(Component)} determines whether to
+ * respect the {@link #isFocusable()} method of the component.
+ *
+ * @param focusable the new focusable status
+ * @since 1.4
+ */
+ public void setFocusable(boolean focusable)
+ {
+ firePropertyChange("focusable", this.focusable, focusable);
+ this.focusable = focusable;
+ this.isFocusTraversableOverridden = 1;
+ }
+
+ /**
+ * Sets the focus traversal keys for one of the three focus
+ * traversal directions supported by Components:
+ * {@link KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS},
+ * {@link KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS}, or
+ * {@link KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS}. Normally, the
+ * default values should match the operating system's native
+ * choices. To disable a given traversal, use
+ * <code>Collections.EMPTY_SET</code>. The event dispatcher will
+ * consume PRESSED, RELEASED, and TYPED events for the specified
+ * key, although focus can only transfer on PRESSED or RELEASED.
+ *
+ * <p>The defaults are:
+ * <table>
+ * <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
+ * <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
+ * <td>Normal forward traversal</td>
+ * <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr>
+ * <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
+ * <td>Normal backward traversal</td>
+ * <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr>
+ * <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
+ * <td>Go up a traversal cycle</td><td>None</td></tr>
+ * </table>
+ *
+ * If keystrokes is null, this component's focus traversal key set
+ * is inherited from one of its ancestors. If none of its ancestors
+ * has its own set of focus traversal keys, the focus traversal keys
+ * are set to the defaults retrieved from the current
+ * KeyboardFocusManager. If not null, the set must contain only
+ * AWTKeyStrokes that are not already focus keys and are not
+ * KEY_TYPED events.
+ *
+ * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
+ * UP_CYCLE_TRAVERSAL_KEYS
+ * @param keystrokes a set of keys, or null
+ * @throws IllegalArgumentException if id or keystrokes is invalid
+ * @see #getFocusTraversalKeys(int)
+ * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
+ * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
+ * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
+ * @since 1.4
+ */
+ public void setFocusTraversalKeys(int id, Set keystrokes)
+ {
+ if (keystrokes == null)
+ {
+ Container parent = getParent ();
+
+ while (parent != null)
+ {
+ if (parent.areFocusTraversalKeysSet (id))
+ {
+ keystrokes = parent.getFocusTraversalKeys (id);
+ break;
+ }
+ parent = parent.getParent ();
+ }
+
+ if (keystrokes == null)
+ keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
+ getDefaultFocusTraversalKeys (id);
+ }
+
+ Set sa;
+ Set sb;
+ String name;
+ switch (id)
+ {
+ case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ name = "forwardFocusTraversalKeys";
+ break;
+ case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ name = "backwardFocusTraversalKeys";
+ break;
+ case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ name = "upCycleFocusTraversalKeys";
+ break;
+ default:
+ throw new IllegalArgumentException ();
+ }
+
+ int i = keystrokes.size ();
+ Iterator iter = keystrokes.iterator ();
+
+ while (--i >= 0)
+ {
+ Object o = iter.next ();
+ if (!(o instanceof AWTKeyStroke)
+ || sa.contains (o) || sb.contains (o)
+ || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
+ throw new IllegalArgumentException ();
+ }
+
+ if (focusTraversalKeys == null)
+ focusTraversalKeys = new Set[3];
+
+ keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
+ firePropertyChange (name, focusTraversalKeys[id], keystrokes);
+
+ focusTraversalKeys[id] = keystrokes;
+ }
+
+ /**
+ * Returns the set of keys for a given focus traversal action, as
+ * defined in <code>setFocusTraversalKeys</code>. If not set, this
+ * is inherited from the parent component, which may have gotten it
+ * from the KeyboardFocusManager.
+ *
+ * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
+ * or UP_CYCLE_TRAVERSAL_KEYS
+ *
+ * @return set of traversal keys
+ *
+ * @throws IllegalArgumentException if id is invalid
+ *
+ * @see #setFocusTraversalKeys (int, Set)
+ * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
+ * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
+ * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
+ *
+ * @since 1.4
+ */
+ public Set getFocusTraversalKeys (int id)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException();
+
+ Set s = null;
+
+ if (focusTraversalKeys != null)
+ s = focusTraversalKeys[id];
+
+ if (s == null && parent != null)
+ s = parent.getFocusTraversalKeys (id);
+
+ return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
+ .getDefaultFocusTraversalKeys(id)) : s;
+ }
+
+ /**
+ * Tests whether the focus traversal keys for a given action are explicitly
+ * set or inherited.
+ *
+ * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
+ * or UP_CYCLE_TRAVERSAL_KEYS
+ * @return true if that set is explicitly specified
+ * @throws IllegalArgumentException if id is invalid
+ * @see #getFocusTraversalKeys (int)
+ * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
+ * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
+ * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
+ * @since 1.4
+ */
+ public boolean areFocusTraversalKeysSet (int id)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+
+ return focusTraversalKeys != null && focusTraversalKeys[id] != null;
+ }
+
+ /**
+ * Enable or disable focus traversal keys on this Component. If
+ * they are, then the keyboard focus manager consumes and acts on
+ * key press and release events that trigger focus traversal, and
+ * discards the corresponding key typed events. If focus traversal
+ * keys are disabled, then all key events that would otherwise
+ * trigger focus traversal are sent to this Component.
+ *
+ * @param focusTraversalKeysEnabled the new value of the flag
+ * @see #getFocusTraversalKeysEnabled ()
+ * @see #setFocusTraversalKeys (int, Set)
+ * @see #getFocusTraversalKeys (int)
+ * @since 1.4
+ */
+ public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled)
+ {
+ firePropertyChange ("focusTraversalKeysEnabled",
+ this.focusTraversalKeysEnabled,
+ focusTraversalKeysEnabled);
+ this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
+ }
+
+ /**
+ * Check whether or not focus traversal keys are enabled on this
+ * Component. If they are, then the keyboard focus manager consumes
+ * and acts on key press and release events that trigger focus
+ * traversal, and discards the corresponding key typed events. If
+ * focus traversal keys are disabled, then all key events that would
+ * otherwise trigger focus traversal are sent to this Component.
+ *
+ * @return true if focus traversal keys are enabled
+ * @see #setFocusTraversalKeysEnabled (boolean)
+ * @see #setFocusTraversalKeys (int, Set)
+ * @see #getFocusTraversalKeys (int)
+ * @since 1.4
+ */
+ public boolean getFocusTraversalKeysEnabled ()
+ {
+ return focusTraversalKeysEnabled;
+ }
+
+ /**
+ * Request that this Component be given the keyboard input focus and
+ * that its top-level ancestor become the focused Window.
+ *
+ * For the request to be granted, the Component must be focusable,
+ * displayable and showing and the top-level Window to which it
+ * belongs must be focusable. If the request is initially denied on
+ * the basis that the top-level Window is not focusable, the request
+ * will be remembered and granted when the Window does become
+ * focused.
+ *
+ * Never assume that this Component is the focus owner until it
+ * receives a FOCUS_GAINED event.
+ *
+ * The behaviour of this method is platform-dependent.
+ * {@link #requestFocusInWindow()} should be used instead.
+ *
+ * @see #requestFocusInWindow ()
+ * @see FocusEvent
+ * @see #addFocusListener (FocusListener)
+ * @see #isFocusable ()
+ * @see #isDisplayable ()
+ * @see KeyboardFocusManager#clearGlobalFocusOwner ()
+ */
+ public void requestFocus ()
+ {
+ if (isDisplayable ()
+ && isShowing ()
+ && isFocusable ())
+ {
+ synchronized (getTreeLock ())
+ {
+ // Find this Component's top-level ancestor.
+ Container parent = getParent ();
+
+ while (parent != null
+ && !(parent instanceof Window))
+ parent = parent.getParent ();
+
+ Window toplevel = (Window) parent;
+ if (toplevel.isFocusableWindow ())
+ {
+ if (peer != null && !isLightweight())
+ // This call will cause a FOCUS_GAINED event to be
+ // posted to the system event queue if the native
+ // windowing system grants the focus request.
+ peer.requestFocus ();
+ else
+ {
+ // Either our peer hasn't been created yet or we're a
+ // lightweight component. In either case we want to
+ // post a FOCUS_GAINED event.
+ EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+ synchronized (eq)
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+ Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+ if (currentFocusOwner != null)
+ {
+ eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
+ false, this));
+ eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false,
+ currentFocusOwner));
+ }
+ else
+ eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false));
+ }
+ }
+ }
+ else
+ pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED);
+ }
+ }
+ }
+
+ /**
+ * Request that this Component be given the keyboard input focus and
+ * that its top-level ancestor become the focused Window.
+ *
+ * For the request to be granted, the Component must be focusable,
+ * displayable and showing and the top-level Window to which it
+ * belongs must be focusable. If the request is initially denied on
+ * the basis that the top-level Window is not focusable, the request
+ * will be remembered and granted when the Window does become
+ * focused.
+ *
+ * Never assume that this Component is the focus owner until it
+ * receives a FOCUS_GAINED event.
+ *
+ * The behaviour of this method is platform-dependent.
+ * {@link #requestFocusInWindow()} should be used instead.
+ *
+ * If the return value is false, the request is guaranteed to fail.
+ * If the return value is true, the request will succeed unless it
+ * is vetoed or something in the native windowing system intervenes,
+ * preventing this Component's top-level ancestor from becoming
+ * focused. This method is meant to be called by derived
+ * lightweight Components that want to avoid unnecessary repainting
+ * when they know a given focus transfer need only be temporary.
+ *
+ * @param temporary true if the focus request is temporary
+ * @return true if the request has a chance of success
+ * @see #requestFocusInWindow ()
+ * @see FocusEvent
+ * @see #addFocusListener (FocusListener)
+ * @see #isFocusable ()
+ * @see #isDisplayable ()
+ * @see KeyboardFocusManager#clearGlobalFocusOwner ()
+ * @since 1.4
+ */
+ protected boolean requestFocus (boolean temporary)
+ {
+ if (isDisplayable ()
+ && isShowing ()
+ && isFocusable ())
+ {
+ synchronized (getTreeLock ())
+ {
+ // Find this Component's top-level ancestor.
+ Container parent = getParent ();
+
+ while (parent != null
+ && !(parent instanceof Window))
+ parent = parent.getParent ();
+
+ Window toplevel = (Window) parent;
+ if (toplevel.isFocusableWindow ())
+ {
+ if (peer != null && !isLightweight())
+ // This call will cause a FOCUS_GAINED event to be
+ // posted to the system event queue if the native
+ // windowing system grants the focus request.
+ peer.requestFocus ();
+ else
+ {
+ // Either our peer hasn't been created yet or we're a
+ // lightweight component. In either case we want to
+ // post a FOCUS_GAINED event.
+ EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+ synchronized (eq)
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+ Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+ if (currentFocusOwner != null)
+ {
+ eq.postEvent (new FocusEvent(currentFocusOwner,
+ FocusEvent.FOCUS_LOST,
+ temporary, this));
+ eq.postEvent (new FocusEvent(this,
+ FocusEvent.FOCUS_GAINED,
+ temporary,
+ currentFocusOwner));
+ }
+ else
+ eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
+ }
+ }
+ }
+ else
+ // FIXME: need to add a focus listener to our top-level
+ // ancestor, so that we can post this event when it becomes
+ // the focused window.
+ pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary);
+ }
+ }
+ // Always return true.
+ return true;
+ }
+
+ /**
+ * Request that this component be given the keyboard input focus, if
+ * its top-level ancestor is the currently focused Window. A
+ * <code>FOCUS_GAINED</code> event will be fired if and only if this
+ * request is successful. To be successful, the component must be
+ * displayable, showing, and focusable, and its ancestor top-level
+ * Window must be focused.
+ *
+ * If the return value is false, the request is guaranteed to fail.
+ * If the return value is true, the request will succeed unless it
+ * is vetoed or something in the native windowing system intervenes,
+ * preventing this Component's top-level ancestor from becoming
+ * focused.
+ *
+ * @return true if the request has a chance of success
+ * @see #requestFocus ()
+ * @see FocusEvent
+ * @see #addFocusListener (FocusListener)
+ * @see #isFocusable ()
+ * @see #isDisplayable ()
+ * @see KeyboardFocusManager#clearGlobalFocusOwner ()
+ * @since 1.4
+ */
+ public boolean requestFocusInWindow ()
+ {
+ return requestFocusInWindow (false);
+ }
+
+ /**
+ * Request that this component be given the keyboard input focus, if
+ * its top-level ancestor is the currently focused Window. A
+ * <code>FOCUS_GAINED</code> event will be fired if and only if this
+ * request is successful. To be successful, the component must be
+ * displayable, showing, and focusable, and its ancestor top-level
+ * Window must be focused.
+ *
+ * If the return value is false, the request is guaranteed to fail.
+ * If the return value is true, the request will succeed unless it
+ * is vetoed or something in the native windowing system intervenes,
+ * preventing this Component's top-level ancestor from becoming
+ * focused. This method is meant to be called by derived
+ * lightweight Components that want to avoid unnecessary repainting
+ * when they know a given focus transfer need only be temporary.
+ *
+ * @param temporary true if the focus request is temporary
+ * @return true if the request has a chance of success
+ * @see #requestFocus ()
+ * @see FocusEvent
+ * @see #addFocusListener (FocusListener)
+ * @see #isFocusable ()
+ * @see #isDisplayable ()
+ * @see KeyboardFocusManager#clearGlobalFocusOwner ()
+ * @since 1.4
+ */
+ protected boolean requestFocusInWindow (boolean temporary)
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ Window focusedWindow = manager.getFocusedWindow ();
+
+ if (isDisplayable ()
+ && isShowing ()
+ && isFocusable ())
+ {
+ if (focusedWindow != null)
+ {
+ synchronized (getTreeLock ())
+ {
+ Container parent = getParent ();
+
+ while (parent != null
+ && !(parent instanceof Window))
+ parent = parent.getParent ();
+
+ Window toplevel = (Window) parent;
+
+ // Check if top-level ancestor is currently focused window.
+ if (focusedWindow == toplevel)
+ {
+ if (peer != null
+ && !isLightweight()
+ && !(this instanceof Window))
+ // This call will cause a FOCUS_GAINED event to be
+ // posted to the system event queue if the native
+ // windowing system grants the focus request.
+ peer.requestFocus ();
+ else
+ {
+ // Either our peer hasn't been created yet or we're a
+ // lightweight component. In either case we want to
+ // post a FOCUS_GAINED event.
+ EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+ synchronized (eq)
+ {
+ Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+ if (currentFocusOwner != null)
+ {
+ eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
+ temporary, this));
+ eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary,
+ currentFocusOwner));
+ }
+ else
+ eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
+ }
+ }
+ }
+ else
+ return false;
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Transfers focus to the next component in the focus traversal
+ * order, as though this were the current focus owner.
+ *
+ * @see #requestFocus()
+ * @since 1.1
+ */
+ public void transferFocus ()
+ {
+ nextFocus ();
+ }
+
+ /**
+ * Returns the root container that owns the focus cycle where this
+ * component resides. A focus cycle root is in two cycles, one as
+ * the ancestor, and one as the focusable element; this call always
+ * returns the ancestor.
+ *
+ * @return the ancestor container that owns the focus cycle
+ * @since 1.4
+ */
+ public Container getFocusCycleRootAncestor ()
+ {
+ if (this instanceof Window
+ && ((Container) this).isFocusCycleRoot ())
+ return (Container) this;
+
+ Container parent = getParent ();
+
+ while (parent != null
+ && !parent.isFocusCycleRoot ())
+ parent = parent.getParent ();
+
+ return parent;
+ }
+
+ /**
+ * Tests if the container is the ancestor of the focus cycle that
+ * this component belongs to.
+ *
+ * @param c the container to test
+ * @return true if c is the focus cycle root
+ * @since 1.4
+ */
+ public boolean isFocusCycleRoot (Container c)
+ {
+ return c == getFocusCycleRootAncestor ();
+ }
+
+ /**
+ * AWT 1.0 focus event processor. Transfers focus to the next
+ * component in the focus traversal order, as though this were the
+ * current focus owner.
+ *
+ * @deprecated use {@link #transferFocus ()} instead
+ */
+ public void nextFocus ()
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ manager.focusNextComponent (this);
+ }
+
+ /**
+ * Transfers focus to the previous component in the focus traversal
+ * order, as though this were the current focus owner.
+ *
+ * @see #requestFocus ()
+ * @since 1.4
+ */
+ public void transferFocusBackward ()
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ manager.focusPreviousComponent (this);
+ }
+
+ /**
+ * Transfers focus to the focus cycle root of this component.
+ * However, if this is a Window, the default focus owner in the
+ * window in the current focus cycle is focused instead.
+ *
+ * @see #requestFocus()
+ * @see #isFocusCycleRoot(Container)
+ * @since 1.4
+ */
+ public void transferFocusUpCycle ()
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ manager.upFocusCycle (this);
+ }
+
+ /**
+ * Tests if this component is the focus owner. Use {@link
+ * #isFocusOwner ()} instead.
+ *
+ * @return true if this component owns focus
+ * @since 1.2
+ */
+ public boolean hasFocus ()
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ Component focusOwner = manager.getFocusOwner ();
+
+ return this == focusOwner;
+ }
+
+ /**
+ * Tests if this component is the focus owner.
+ *
+ * @return true if this component owns focus
+ * @since 1.4
+ */
+ public boolean isFocusOwner()
+ {
+ return hasFocus ();
+ }
+
+ /**
+ * Adds the specified popup menu to this component.
+ *
+ * @param popup the popup menu to be added
+ *
+ * @see #remove(MenuComponent)
+ *
+ * @since 1.1
+ */
+ public synchronized void add(PopupMenu popup)
+ {
+ if (popups == null)
+ popups = new Vector();
+ popups.add(popup);
+
+ if (popup.parent != null)
+ popup.parent.remove(popup);
+ popup.parent = this;
+ if (peer != null)
+ popup.addNotify();
+ }
+
+ /**
+ * Removes the specified popup menu from this component.
+ *
+ * @param popup the popup menu to remove
+ * @see #add(PopupMenu)
+ * @since 1.1
+ */
+ public synchronized void remove(MenuComponent popup)
+ {
+ if (popups != null)
+ popups.remove(popup);
+ }
+
+ /**
+ * Returns a debugging string representing this component. The string may
+ * be empty but not null.
+ *
+ * @return a string representing this component
+ */
+ protected String paramString()
+ {
+ StringBuffer param = new StringBuffer();
+ String name = getName();
+ if (name != null)
+ param.append(name).append(",");
+ param.append(x).append(",").append(y).append(",").append(width)
+ .append("x").append(height);
+ if (! isValid())
+ param.append(",invalid");
+ if (! isVisible())
+ param.append(",invisible");
+ if (! isEnabled())
+ param.append(",disabled");
+ if (! isOpaque())
+ param.append(",translucent");
+ if (isDoubleBuffered())
+ param.append(",doublebuffered");
+ return param.toString();
+ }
+
+ /**
+ * Returns a string representation of this component. This is implemented
+ * as <code>getClass().getName() + '[' + paramString() + ']'</code>.
+ *
+ * @return a string representation of this component
+ */
+ public String toString()
+ {
+ return getClass().getName() + '[' + paramString() + ']';
+ }
+
+ /**
+ * Prints a listing of this component to <code>System.out</code>.
+ *
+ * @see #list(PrintStream)
+ */
+ public void list()
+ {
+ list(System.out, 0);
+ }
+
+ /**
+ * Prints a listing of this component to the specified print stream.
+ *
+ * @param out the <code>PrintStream</code> to print to
+ */
+ public void list(PrintStream out)
+ {
+ list(out, 0);
+ }
+
+ /**
+ * Prints a listing of this component to the specified print stream,
+ * starting at the specified indentation point.
+ *
+ * @param out the <code>PrintStream</code> to print to
+ * @param indent the indentation point
+ */
+ public void list(PrintStream out, int indent)
+ {
+ for (int i = 0; i < indent; ++i)
+ out.print(' ');
+ out.println(toString());
+ }
+
+ /**
+ * Prints a listing of this component to the specified print writer.
+ *
+ * @param out the <code>PrintWrinter</code> to print to
+ * @since 1.1
+ */
+ public void list(PrintWriter out)
+ {
+ list(out, 0);
+ }
+
+ /**
+ * Prints a listing of this component to the specified print writer,
+ * starting at the specified indentation point.
+ *
+ * @param out the <code>PrintWriter</code> to print to
+ * @param indent the indentation point
+ * @since 1.1
+ */
+ public void list(PrintWriter out, int indent)
+ {
+ for (int i = 0; i < indent; ++i)
+ out.print(' ');
+ out.println(toString());
+ }
+
+ /**
+ * Adds the specified property listener to this component. This is harmless
+ * if the listener is null, but if the listener has already been registered,
+ * it will now be registered twice. The property listener ignores inherited
+ * properties. Recognized properties include:<br>
+ * <ul>
+ * <li>the font (<code>"font"</code>)</li>
+ * <li>the background color (<code>"background"</code>)</li>
+ * <li>the foreground color (<code>"foreground"</code>)</li>
+ * <li>the focusability (<code>"focusable"</code>)</li>
+ * <li>the focus key traversal enabled state
+ * (<code>"focusTraversalKeysEnabled"</code>)</li>
+ * <li>the set of forward traversal keys
+ * (<code>"forwardFocusTraversalKeys"</code>)</li>
+ * <li>the set of backward traversal keys
+ * (<code>"backwardFocusTraversalKeys"</code>)</li>
+ * <li>the set of up-cycle traversal keys
+ * (<code>"upCycleFocusTraversalKeys"</code>)</li>
+ * </ul>
+ *
+ * @param listener the new listener to add
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ * @see #getPropertyChangeListeners()
+ * @see #addPropertyChangeListener(String, PropertyChangeListener)
+ * @since 1.1
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener)
+ {
+ if (changeSupport == null)
+ changeSupport = new PropertyChangeSupport(this);
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes the specified property listener from the component. This is
+ * harmless if the listener was not previously registered.
+ *
+ * @param listener the listener to remove
+ * @see #addPropertyChangeListener(PropertyChangeListener)
+ * @see #getPropertyChangeListeners()
+ * @see #removePropertyChangeListener(String, PropertyChangeListener)
+ * @since 1.1
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener)
+ {
+ if (changeSupport != null)
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addPropertyChangeListener(PropertyChangeListener)
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ * @see #getPropertyChangeListeners(String)
+ * @since 1.4
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners()
+ {
+ return changeSupport == null ? new PropertyChangeListener[0]
+ : changeSupport.getPropertyChangeListeners();
+ }
+
+ /**
+ * Adds the specified property listener to this component. This is harmless
+ * if the listener is null, but if the listener has already been registered,
+ * it will now be registered twice. The property listener ignores inherited
+ * properties. The listener is keyed to a single property. Recognized
+ * properties include:<br>
+ * <ul>
+ * <li>the font (<code>"font"</code>)</li>
+ * <li>the background color (<code>"background"</code>)</li>
+ * <li>the foreground color (<code>"foreground"</code>)</li>
+ * <li>the focusability (<code>"focusable"</code>)</li>
+ * <li>the focus key traversal enabled state
+ * (<code>"focusTraversalKeysEnabled"</code>)</li>
+ * <li>the set of forward traversal keys
+ * (<code>"forwardFocusTraversalKeys"</code>)</li>
+p * <li>the set of backward traversal keys
+ * (<code>"backwardFocusTraversalKeys"</code>)</li>
+ * <li>the set of up-cycle traversal keys
+ * (<code>"upCycleFocusTraversalKeys"</code>)</li>
+ * </ul>
+ *
+ * @param propertyName the property name to filter on
+ * @param listener the new listener to add
+ * @see #removePropertyChangeListener(String, PropertyChangeListener)
+ * @see #getPropertyChangeListeners(String)
+ * @see #addPropertyChangeListener(PropertyChangeListener)
+ * @since 1.1
+ */
+ public void addPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener)
+ {
+ if (changeSupport == null)
+ changeSupport = new PropertyChangeSupport(this);
+ changeSupport.addPropertyChangeListener(propertyName, listener);
+ }
+
+ /**
+ * Removes the specified property listener on a particular property from
+ * the component. This is harmless if the listener was not previously
+ * registered.
+ *
+ * @param propertyName the property name to filter on
+ * @param listener the listener to remove
+ * @see #addPropertyChangeListener(String, PropertyChangeListener)
+ * @see #getPropertyChangeListeners(String)
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ * @since 1.1
+ */
+ public void removePropertyChangeListener(String propertyName,
+ PropertyChangeListener listener)
+ {
+ if (changeSupport != null)
+ changeSupport.removePropertyChangeListener(propertyName, listener);
+ }
+
+ /**
+ * Returns an array of all specified listeners on the named property that
+ * are registered on this component.
+ *
+ * @return an array of listeners
+ * @see #addPropertyChangeListener(String, PropertyChangeListener)
+ * @see #removePropertyChangeListener(String, PropertyChangeListener)
+ * @see #getPropertyChangeListeners()
+ * @since 1.4
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners(String property)
+ {
+ return changeSupport == null ? new PropertyChangeListener[0]
+ : changeSupport.getPropertyChangeListeners(property);
+ }
+
+ /**
+ * Report a change in a bound property to any registered property listeners.
+ *
+ * @param propertyName the property that changed
+ * @param oldValue the old property value
+ * @param newValue the new property value
+ */
+ protected void firePropertyChange(String propertyName, Object oldValue,
+ Object newValue)
+ {
+ if (changeSupport != null)
+ changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ /**
+ * Report a change in a bound property to any registered property listeners.
+ *
+ * @param propertyName the property that changed
+ * @param oldValue the old property value
+ * @param newValue the new property value
+ */
+ protected void firePropertyChange(String propertyName, boolean oldValue,
+ boolean newValue)
+ {
+ if (changeSupport != null)
+ changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ /**
+ * Report a change in a bound property to any registered property listeners.
+ *
+ * @param propertyName the property that changed
+ * @param oldValue the old property value
+ * @param newValue the new property value
+ */
+ protected void firePropertyChange(String propertyName, int oldValue,
+ int newValue)
+ {
+ if (changeSupport != null)
+ changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ /**
+ * Sets the text layout orientation of this component. New components default
+ * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only
+ * the current component, while
+ * {@link #applyComponentOrientation(ComponentOrientation)} affects the
+ * entire hierarchy.
+ *
+ * @param o the new orientation
+ * @throws NullPointerException if o is null
+ * @see #getComponentOrientation()
+ */
+ public void setComponentOrientation(ComponentOrientation o)
+ {
+ if (o == null)
+ throw new NullPointerException();
+ ComponentOrientation oldOrientation = orientation;
+ orientation = o;
+ firePropertyChange("componentOrientation", oldOrientation, o);
+ }
+
+ /**
+ * Determines the text layout orientation used by this component.
+ *
+ * @return the component orientation
+ * @see #setComponentOrientation(ComponentOrientation)
+ */
+ public ComponentOrientation getComponentOrientation()
+ {
+ return orientation;
+ }
+
+ /**
+ * Sets the text layout orientation of this component. New components default
+ * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the
+ * entire hierarchy, while
+ * {@link #setComponentOrientation(ComponentOrientation)} affects only the
+ * current component.
+ *
+ * @param o the new orientation
+ * @throws NullPointerException if o is null
+ * @see #getComponentOrientation()
+ * @since 1.4
+ */
+ public void applyComponentOrientation(ComponentOrientation o)
+ {
+ setComponentOrientation(o);
+ }
+
+ /**
+ * Returns the accessibility framework context of this class. Component is
+ * not accessible, so the default implementation returns null. Subclasses
+ * must override this behavior, and return an appropriate subclass of
+ * {@link AccessibleAWTComponent}.
+ *
+ * @return the accessibility context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ return null;
+ }
+
+
+ // Helper methods; some are package visible for use by subclasses.
+
+ /**
+ * Subclasses should override this to return unique component names like
+ * "menuitem0".
+ *
+ * @return the generated name for this component
+ */
+ String generateName()
+ {
+ // Component is abstract.
+ return null;
+ }
+
+ /**
+ * Sets the peer for this component.
+ *
+ * @param peer the new peer
+ */
+ final void setPeer(ComponentPeer peer)
+ {
+ this.peer = peer;
+ }
+
+ /**
+ * Implementation method that allows classes such as Canvas and Window to
+ * override the graphics configuration without violating the published API.
+ *
+ * @return the graphics configuration
+ */
+ GraphicsConfiguration getGraphicsConfigurationImpl()
+ {
+ if (peer != null)
+ {
+ GraphicsConfiguration config = peer.getGraphicsConfiguration();
+ if (config != null)
+ return config;
+ }
+
+ if (parent != null)
+ return parent.getGraphicsConfiguration();
+
+ return null;
+ }
+
+ /**
+ * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0
+ * event ({@link Event}).
+ *
+ * @param e an AWT 1.1 event to translate
+ *
+ * @return an AWT 1.0 event representing e
+ */
+ static Event translateEvent (AWTEvent e)
+ {
+ Component target = (Component) e.getSource ();
+ Event translated = null;
+
+ if (e instanceof InputEvent)
+ {
+ InputEvent ie = (InputEvent) e;
+ long when = ie.getWhen ();
+
+ int oldID = 0;
+ int id = e.getID ();
+
+ int oldMods = 0;
+ int mods = ie.getModifiersEx ();
+
+ if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)
+ oldMods |= Event.META_MASK;
+ else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0)
+ oldMods |= Event.ALT_MASK;
+
+ if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0)
+ oldMods |= Event.SHIFT_MASK;
+
+ if ((mods & InputEvent.CTRL_DOWN_MASK) != 0)
+ oldMods |= Event.CTRL_MASK;
+
+ if ((mods & InputEvent.META_DOWN_MASK) != 0)
+ oldMods |= Event.META_MASK;
+
+ if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
+ oldMods |= Event.ALT_MASK;
+
+ if (e instanceof MouseEvent)
+ {
+ if (id == MouseEvent.MOUSE_PRESSED)
+ oldID = Event.MOUSE_DOWN;
+ else if (id == MouseEvent.MOUSE_RELEASED)
+ oldID = Event.MOUSE_UP;
+ else if (id == MouseEvent.MOUSE_MOVED)
+ oldID = Event.MOUSE_MOVE;
+ else if (id == MouseEvent.MOUSE_DRAGGED)
+ oldID = Event.MOUSE_DRAG;
+ else if (id == MouseEvent.MOUSE_ENTERED)
+ oldID = Event.MOUSE_ENTER;
+ else if (id == MouseEvent.MOUSE_EXITED)
+ oldID = Event.MOUSE_EXIT;
+ else
+ // No analogous AWT 1.0 mouse event.
+ return null;
+
+ MouseEvent me = (MouseEvent) e;
+
+ translated = new Event (target, when, oldID,
+ me.getX (), me.getY (), 0, oldMods);
+ }
+ else if (e instanceof KeyEvent)
+ {
+ if (id == KeyEvent.KEY_PRESSED)
+ oldID = Event.KEY_PRESS;
+ else if (e.getID () == KeyEvent.KEY_RELEASED)
+ oldID = Event.KEY_RELEASE;
+ else
+ // No analogous AWT 1.0 key event.
+ return null;
+
+ int oldKey = 0;
+ int newKey = ((KeyEvent) e).getKeyCode ();
+ switch (newKey)
+ {
+ case KeyEvent.VK_BACK_SPACE:
+ oldKey = Event.BACK_SPACE;
+ break;
+ case KeyEvent.VK_CAPS_LOCK:
+ oldKey = Event.CAPS_LOCK;
+ break;
+ case KeyEvent.VK_DELETE:
+ oldKey = Event.DELETE;
+ break;
+ case KeyEvent.VK_DOWN:
+ case KeyEvent.VK_KP_DOWN:
+ oldKey = Event.DOWN;
+ break;
+ case KeyEvent.VK_END:
+ oldKey = Event.END;
+ break;
+ case KeyEvent.VK_ENTER:
+ oldKey = Event.ENTER;
+ break;
+ case KeyEvent.VK_ESCAPE:
+ oldKey = Event.ESCAPE;
+ break;
+ case KeyEvent.VK_F1:
+ oldKey = Event.F1;
+ break;
+ case KeyEvent.VK_F10:
+ oldKey = Event.F10;
+ break;
+ case KeyEvent.VK_F11:
+ oldKey = Event.F11;
+ break;
+ case KeyEvent.VK_F12:
+ oldKey = Event.F12;
+ break;
+ case KeyEvent.VK_F2:
+ oldKey = Event.F2;
+ break;
+ case KeyEvent.VK_F3:
+ oldKey = Event.F3;
+ break;
+ case KeyEvent.VK_F4:
+ oldKey = Event.F4;
+ break;
+ case KeyEvent.VK_F5:
+ oldKey = Event.F5;
+ break;
+ case KeyEvent.VK_F6:
+ oldKey = Event.F6;
+ break;
+ case KeyEvent.VK_F7:
+ oldKey = Event.F7;
+ break;
+ case KeyEvent.VK_F8:
+ oldKey = Event.F8;
+ break;
+ case KeyEvent.VK_F9:
+ oldKey = Event.F9;
+ break;
+ case KeyEvent.VK_HOME:
+ oldKey = Event.HOME;
+ break;
+ case KeyEvent.VK_INSERT:
+ oldKey = Event.INSERT;
+ break;
+ case KeyEvent.VK_LEFT:
+ case KeyEvent.VK_KP_LEFT:
+ oldKey = Event.LEFT;
+ break;
+ case KeyEvent.VK_NUM_LOCK:
+ oldKey = Event.NUM_LOCK;
+ break;
+ case KeyEvent.VK_PAUSE:
+ oldKey = Event.PAUSE;
+ break;
+ case KeyEvent.VK_PAGE_DOWN:
+ oldKey = Event.PGDN;
+ break;
+ case KeyEvent.VK_PAGE_UP:
+ oldKey = Event.PGUP;
+ break;
+ case KeyEvent.VK_PRINTSCREEN:
+ oldKey = Event.PRINT_SCREEN;
+ break;
+ case KeyEvent.VK_RIGHT:
+ case KeyEvent.VK_KP_RIGHT:
+ oldKey = Event.RIGHT;
+ break;
+ case KeyEvent.VK_SCROLL_LOCK:
+ oldKey = Event.SCROLL_LOCK;
+ break;
+ case KeyEvent.VK_TAB:
+ oldKey = Event.TAB;
+ break;
+ case KeyEvent.VK_UP:
+ case KeyEvent.VK_KP_UP:
+ oldKey = Event.UP;
+ break;
+ default:
+ oldKey = newKey;
+ }
+
+ translated = new Event (target, when, oldID,
+ 0, 0, oldKey, oldMods);
+ }
+ }
+ else if (e instanceof ActionEvent)
+ translated = new Event (target, Event.ACTION_EVENT,
+ ((ActionEvent) e).getActionCommand ());
+
+ return translated;
+ }
+
+ /**
+ * Implementation of dispatchEvent. Allows trusted package classes
+ * to dispatch additional events first. This implementation first
+ * translates <code>e</code> to an AWT 1.0 event and sends the
+ * result to {@link #postEvent}. If the AWT 1.0 event is not
+ * handled, and events of type <code>e</code> are enabled for this
+ * component, e is passed on to {@link #processEvent}.
+ *
+ * @param e the event to dispatch
+ */
+
+ void dispatchEventImpl (AWTEvent e)
+ {
+ Event oldEvent = translateEvent (e);
+
+ if (oldEvent != null)
+ postEvent (oldEvent);
+
+ if (eventTypeEnabled (e.id))
+ {
+ // the trick we use to communicate between dispatch and redispatch
+ // is to have KeyboardFocusManager.redispatch synchronize on the
+ // object itself. we then do not redispatch to KeyboardFocusManager
+ // if we are already holding the lock.
+ if (! Thread.holdsLock(e))
+ {
+ switch (e.id)
+ {
+ case WindowEvent.WINDOW_GAINED_FOCUS:
+ case WindowEvent.WINDOW_LOST_FOCUS:
+ case KeyEvent.KEY_PRESSED:
+ case KeyEvent.KEY_RELEASED:
+ case KeyEvent.KEY_TYPED:
+ case FocusEvent.FOCUS_GAINED:
+ case FocusEvent.FOCUS_LOST:
+ if (KeyboardFocusManager
+ .getCurrentKeyboardFocusManager()
+ .dispatchEvent(e))
+ return;
+ case MouseEvent.MOUSE_PRESSED:
+ if (isLightweight())
+ requestFocus();
+ break;
+ }
+ }
+ processEvent (e);
+ }
+ }
+
+ /**
+ * Tells whether or not an event type is enabled.
+ */
+ boolean eventTypeEnabled (int type)
+ {
+ if (type > AWTEvent.RESERVED_ID_MAX)
+ return true;
+
+ switch (type)
+ {
+ case ComponentEvent.COMPONENT_HIDDEN:
+ case ComponentEvent.COMPONENT_MOVED:
+ case ComponentEvent.COMPONENT_RESIZED:
+ case ComponentEvent.COMPONENT_SHOWN:
+ return (componentListener != null
+ || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0);
+
+ case KeyEvent.KEY_PRESSED:
+ case KeyEvent.KEY_RELEASED:
+ case KeyEvent.KEY_TYPED:
+ return (keyListener != null
+ || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0);
+
+ case MouseEvent.MOUSE_CLICKED:
+ case MouseEvent.MOUSE_ENTERED:
+ case MouseEvent.MOUSE_EXITED:
+ case MouseEvent.MOUSE_PRESSED:
+ case MouseEvent.MOUSE_RELEASED:
+ case MouseEvent.MOUSE_MOVED:
+ case MouseEvent.MOUSE_DRAGGED:
+ return (mouseListener != null
+ || mouseMotionListener != null
+ || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
+
+ case FocusEvent.FOCUS_GAINED:
+ case FocusEvent.FOCUS_LOST:
+ return (focusListener != null
+ || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0);
+
+ case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
+ case InputMethodEvent.CARET_POSITION_CHANGED:
+ return (inputMethodListener != null
+ || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0);
+
+ case PaintEvent.PAINT:
+ case PaintEvent.UPDATE:
+ return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0;
+
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Coalesce paint events. Current heuristic is: Merge if the union of
+ * areas is less than twice that of the sum of the areas. The X server
+ * tend to create a lot of paint events that are adjacent but not
+ * overlapping.
+ *
+ * <pre>
+ * +------+
+ * | +-----+ ...will be merged
+ * | | |
+ * | | |
+ * +------+ |
+ * +-----+
+ *
+ * +---------------+--+
+ * | | | ...will not be merged
+ * +---------------+ |
+ * | |
+ * | |
+ * | |
+ * | |
+ * | |
+ * +--+
+ * </pre>
+ *
+ * @param queuedEvent the first paint event
+ * @param newEvent the second paint event
+ * @return the combined paint event, or null
+ */
+ private PaintEvent coalescePaintEvents(PaintEvent queuedEvent,
+ PaintEvent newEvent)
+ {
+ Rectangle r1 = queuedEvent.getUpdateRect();
+ Rectangle r2 = newEvent.getUpdateRect();
+ Rectangle union = r1.union(r2);
+
+ int r1a = r1.width * r1.height;
+ int r2a = r2.width * r2.height;
+ int ua = union.width * union.height;
+
+ if (ua > (r1a+r2a)*2)
+ return null;
+ /* The 2 factor should maybe be reconsidered. Perhaps 3/2
+ would be better? */
+
+ newEvent.setUpdateRect(union);
+ return newEvent;
+ }
+
+ /**
+ * This method is used to implement transferFocus(). CHILD is the child
+ * making the request. This is overridden by Container; when called for an
+ * ordinary component there is no child and so we always return null.
+ *
+ * FIXME: is this still needed, in light of focus traversal policies?
+ *
+ * @param child the component making the request
+ * @return the next component to focus on
+ */
+ Component findNextFocusComponent(Component child)
+ {
+ return null;
+ }
+
+ /**
+ * Deserializes this component. This regenerates all serializable listeners
+ * which were registered originally.
+ *
+ * @param s the stream to read from
+ * @throws ClassNotFoundException if deserialization fails
+ * @throws IOException if the stream fails
+ */
+ private void readObject(ObjectInputStream s)
+ throws ClassNotFoundException, IOException
+ {
+ s.defaultReadObject();
+ String key = (String) s.readObject();
+ while (key != null)
+ {
+ Object listener = s.readObject();
+ if ("componentL".equals(key))
+ addComponentListener((ComponentListener) listener);
+ else if ("focusL".equals(key))
+ addFocusListener((FocusListener) listener);
+ else if ("keyL".equals(key))
+ addKeyListener((KeyListener) listener);
+ else if ("mouseL".equals(key))
+ addMouseListener((MouseListener) listener);
+ else if ("mouseMotionL".equals(key))
+ addMouseMotionListener((MouseMotionListener) listener);
+ else if ("inputMethodL".equals(key))
+ addInputMethodListener((InputMethodListener) listener);
+ else if ("hierarchyL".equals(key))
+ addHierarchyListener((HierarchyListener) listener);
+ else if ("hierarchyBoundsL".equals(key))
+ addHierarchyBoundsListener((HierarchyBoundsListener) listener);
+ else if ("mouseWheelL".equals(key))
+ addMouseWheelListener((MouseWheelListener) listener);
+ key = (String) s.readObject();
+ }
+ }
+
+ /**
+ * Serializes this component. This ignores all listeners which do not
+ * implement Serializable, but includes those that do.
+ *
+ * @param s the stream to write to
+ * @throws IOException if the stream fails
+ */
+ private void writeObject(ObjectOutputStream s) throws IOException
+ {
+ s.defaultWriteObject();
+ AWTEventMulticaster.save(s, "componentL", componentListener);
+ AWTEventMulticaster.save(s, "focusL", focusListener);
+ AWTEventMulticaster.save(s, "keyL", keyListener);
+ AWTEventMulticaster.save(s, "mouseL", mouseListener);
+ AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener);
+ AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener);
+ AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener);
+ AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener);
+ AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener);
+ s.writeObject(null);
+ }
+
+
+ // Nested classes.
+
+ /**
+ * This class provides accessibility support for subclasses of container.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ * @status updated to 1.4
+ */
+ protected abstract class AccessibleAWTComponent extends AccessibleContext
+ implements Serializable, AccessibleComponent
+ {
+ /**
+ * Compatible with JDK 1.3+.
+ */
+ private static final long serialVersionUID = 642321655757800191L;
+
+ /**
+ * Converts show/hide events to PropertyChange events, and is registered
+ * as a component listener on this component.
+ *
+ * @serial the component handler
+ */
+ protected ComponentListener accessibleAWTComponentHandler
+ = new AccessibleAWTComponentHandler();
+
+ /**
+ * Converts focus events to PropertyChange events, and is registered
+ * as a focus listener on this component.
+ *
+ * @serial the focus handler
+ */
+ protected FocusListener accessibleAWTFocusHandler
+ = new AccessibleAWTFocusHandler();
+
+ /**
+ * The default constructor.
+ */
+ protected AccessibleAWTComponent()
+ {
+ Component.this.addComponentListener(accessibleAWTComponentHandler);
+ Component.this.addFocusListener(accessibleAWTFocusHandler);
+ }
+
+ /**
+ * Adds a global property change listener to the accessible component.
+ *
+ * @param l the listener to add
+ * @see #ACCESSIBLE_NAME_PROPERTY
+ * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
+ * @see #ACCESSIBLE_STATE_PROPERTY
+ * @see #ACCESSIBLE_VALUE_PROPERTY
+ * @see #ACCESSIBLE_SELECTION_PROPERTY
+ * @see #ACCESSIBLE_TEXT_PROPERTY
+ * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
+ */
+ public void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ Component.this.addPropertyChangeListener(l);
+ super.addPropertyChangeListener(l);
+ }
+
+ /**
+ * Removes a global property change listener from this accessible
+ * component.
+ *
+ * @param l the listener to remove
+ */
+ public void removePropertyChangeListener(PropertyChangeListener l)
+ {
+ Component.this.removePropertyChangeListener(l);
+ super.removePropertyChangeListener(l);
+ }
+
+ /**
+ * Returns the accessible name of this component. It is almost always
+ * wrong to return getName(), since it is not localized. In fact, for
+ * things like buttons, this should be the text of the button, not the
+ * name of the object. The tooltip text might also be appropriate.
+ *
+ * @return the name
+ * @see #setAccessibleName(String)
+ */
+ public String getAccessibleName()
+ {
+ return accessibleName == null ? getName() : accessibleName;
+ }
+
+ /**
+ * Returns a brief description of this accessible context. This should
+ * be localized.
+ *
+ * @return a description of this component
+ * @see #setAccessibleDescription(String)
+ */
+ public String getAccessibleDescription()
+ {
+ return accessibleDescription;
+ }
+
+ /**
+ * Returns the role of this component.
+ *
+ * @return the accessible role
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.AWT_COMPONENT;
+ }
+
+ /**
+ * Returns a state set describing this component's state.
+ *
+ * @return a new state set
+ * @see AccessibleState
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet s = new AccessibleStateSet();
+ if (Component.this.isEnabled())
+ s.add(AccessibleState.ENABLED);
+ if (isFocusable())
+ s.add(AccessibleState.FOCUSABLE);
+ if (isFocusOwner())
+ s.add(AccessibleState.FOCUSED);
+ if (isOpaque())
+ s.add(AccessibleState.OPAQUE);
+ if (Component.this.isShowing())
+ s.add(AccessibleState.SHOWING);
+ if (Component.this.isVisible())
+ s.add(AccessibleState.VISIBLE);
+ return s;
+ }
+
+ /**
+ * Returns the parent of this component, if it is accessible.
+ *
+ * @return the accessible parent
+ */
+ public Accessible getAccessibleParent()
+ {
+ if (accessibleParent == null)
+ {
+ Container parent = getParent();
+ accessibleParent = parent instanceof Accessible
+ ? (Accessible) parent : null;
+ }
+ return accessibleParent;
+ }
+
+ /**
+ * Returns the index of this component in its accessible parent.
+ *
+ * @return the index, or -1 if the parent is not accessible
+ * @see #getAccessibleParent()
+ */
+ public int getAccessibleIndexInParent()
+ {
+ if (getAccessibleParent() == null)
+ return -1;
+ AccessibleContext context
+ = ((Component) accessibleParent).getAccessibleContext();
+ if (context == null)
+ return -1;
+ for (int i = context.getAccessibleChildrenCount(); --i >= 0; )
+ if (context.getAccessibleChild(i) == Component.this)
+ return i;
+ return -1;
+ }
+
+ /**
+ * Returns the number of children of this component which implement
+ * Accessible. Subclasses must override this if they can have children.
+ *
+ * @return the number of accessible children, default 0
+ */
+ public int getAccessibleChildrenCount()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the ith accessible child. Subclasses must override this if
+ * they can have children.
+ *
+ * @return the ith accessible child, or null
+ * @see #getAccessibleChildrenCount()
+ */
+ public Accessible getAccessibleChild(int i)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the locale of this component.
+ *
+ * @return the locale
+ * @throws IllegalComponentStateException if the locale is unknown
+ */
+ public Locale getLocale()
+ {
+ return Component.this.getLocale();
+ }
+
+ /**
+ * Returns this, since it is an accessible component.
+ *
+ * @return the accessible component
+ */
+ public AccessibleComponent getAccessibleComponent()
+ {
+ return this;
+ }
+
+ /**
+ * Gets the background color.
+ *
+ * @return the background color
+ * @see #setBackground(Color)
+ */
+ public Color getBackground()
+ {
+ return Component.this.getBackground();
+ }
+
+ /**
+ * Sets the background color.
+ *
+ * @param c the background color
+ * @see #getBackground()
+ * @see #isOpaque()
+ */
+ public void setBackground(Color c)
+ {
+ Component.this.setBackground(c);
+ }
+
+ /**
+ * Gets the foreground color.
+ *
+ * @return the foreground color
+ * @see #setForeground(Color)
+ */
+ public Color getForeground()
+ {
+ return Component.this.getForeground();
+ }
+
+ /**
+ * Sets the foreground color.
+ *
+ * @param c the foreground color
+ * @see #getForeground()
+ */
+ public void setForeground(Color c)
+ {
+ Component.this.setForeground(c);
+ }
+
+ /**
+ * Gets the cursor.
+ *
+ * @return the cursor
+ * @see #setCursor(Cursor)
+ */
+ public Cursor getCursor()
+ {
+ return Component.this.getCursor();
+ }
+
+ /**
+ * Sets the cursor.
+ *
+ * @param cursor the cursor
+ * @see #getCursor()
+ */
+ public void setCursor(Cursor cursor)
+ {
+ Component.this.setCursor(cursor);
+ }
+
+ /**
+ * Gets the font.
+ *
+ * @return the font
+ * @see #setFont(Font)
+ */
+ public Font getFont()
+ {
+ return Component.this.getFont();
+ }
+
+ /**
+ * Sets the font.
+ *
+ * @param f the font
+ * @see #getFont()
+ */
+ public void setFont(Font f)
+ {
+ Component.this.setFont(f);
+ }
+
+ /**
+ * Gets the font metrics for a font.
+ *
+ * @param f the font to look up
+ * @return its metrics
+ * @throws NullPointerException if f is null
+ * @see #getFont()
+ */
+ public FontMetrics getFontMetrics(Font f)
+ {
+ return Component.this.getFontMetrics(f);
+ }
+
+ /**
+ * Tests if the component is enabled.
+ *
+ * @return true if the component is enabled
+ * @see #setEnabled(boolean)
+ * @see #getAccessibleStateSet()
+ * @see AccessibleState#ENABLED
+ */
+ public boolean isEnabled()
+ {
+ return Component.this.isEnabled();
+ }
+
+ /**
+ * Set whether the component is enabled.
+ *
+ * @param b the new enabled status
+ * @see #isEnabled()
+ */
+ public void setEnabled(boolean b)
+ {
+ Component.this.setEnabled(b);
+ }
+
+ /**
+ * Test whether the component is visible (not necesarily showing).
+ *
+ * @return true if it is visible
+ * @see #setVisible(boolean)
+ * @see #getAccessibleStateSet()
+ * @see AccessibleState#VISIBLE
+ */
+ public boolean isVisible()
+ {
+ return Component.this.isVisible();
+ }
+
+ /**
+ * Sets the visibility of this component.
+ *
+ * @param b the desired visibility
+ * @see #isVisible()
+ */
+ public void setVisible(boolean b)
+ {
+ Component.this.setVisible(b);
+ }
+
+ /**
+ * Tests if the component is showing.
+ *
+ * @return true if this is showing
+ */
+ public boolean isShowing()
+ {
+ return Component.this.isShowing();
+ }
+
+ /**
+ * Tests if the point is contained in this component.
+ *
+ * @param p the point to check
+ * @return true if it is contained
+ * @throws NullPointerException if p is null
+ */
+ public boolean contains(Point p)
+ {
+ return Component.this.contains(p.x, p.y);
+ }
+
+ /**
+ * Returns the location of this object on the screen, or null if it is
+ * not showing.
+ *
+ * @return the location relative to screen coordinates, if showing
+ * @see #getBounds()
+ * @see #getLocation()
+ */
+ public Point getLocationOnScreen()
+ {
+ return Component.this.isShowing() ? Component.this.getLocationOnScreen()
+ : null;
+ }
+
+ /**
+ * Returns the location of this object relative to its parent's coordinate
+ * system, or null if it is not showing.
+ *
+ * @return the location
+ * @see #getBounds()
+ * @see #getLocationOnScreen()
+ */
+ public Point getLocation()
+ {
+ return Component.this.isShowing() ? Component.this.getLocation() : null;
+ }
+
+ /**
+ * Sets the location of this relative to its parent's coordinate system.
+ *
+ * @param p the location
+ * @throws NullPointerException if p is null
+ * @see #getLocation()
+ */
+ public void setLocation(Point p)
+ {
+ Component.this.setLocation(p.x, p.y);
+ }
+
+ /**
+ * Gets the bounds of this component, or null if it is not on screen.
+ *
+ * @return the bounds
+ * @see #contains(Point)
+ * @see #setBounds(Rectangle)
+ */
+ public Rectangle getBounds()
+ {
+ return Component.this.isShowing() ? Component.this.getBounds() : null;
+ }
+
+ /**
+ * Sets the bounds of this component.
+ *
+ * @param r the bounds
+ * @throws NullPointerException if r is null
+ * @see #getBounds()
+ */
+ public void setBounds(Rectangle r)
+ {
+ Component.this.setBounds(r.x, r.y, r.width, r.height);
+ }
+
+ /**
+ * Gets the size of this component, or null if it is not showing.
+ *
+ * @return the size
+ * @see #setSize(Dimension)
+ */
+ public Dimension getSize()
+ {
+ return Component.this.isShowing() ? Component.this.getSize() : null;
+ }
+
+ /**
+ * Sets the size of this component.
+ *
+ * @param d the size
+ * @throws NullPointerException if d is null
+ * @see #getSize()
+ */
+ public void setSize(Dimension d)
+ {
+ Component.this.setSize(d.width, d.height);
+ }
+
+ /**
+ * Returns the Accessible child at a point relative to the coordinate
+ * system of this component, if one exists, or null. Since components
+ * have no children, subclasses must override this to get anything besides
+ * null.
+ *
+ * @param p the point to check
+ * @return the accessible child at that point
+ * @throws NullPointerException if p is null
+ */
+ public Accessible getAccessibleAt(Point p)
+ {
+ return null;
+ }
+
+ /**
+ * Tests whether this component can accept focus.
+ *
+ * @return true if this is focus traversable
+ * @see #getAccessibleStateSet ()
+ * @see AccessibleState#FOCUSABLE
+ * @see AccessibleState#FOCUSED
+ */
+ public boolean isFocusTraversable ()
+ {
+ return Component.this.isFocusTraversable ();
+ }
+
+ /**
+ * Requests focus for this component.
+ *
+ * @see #isFocusTraversable ()
+ */
+ public void requestFocus ()
+ {
+ Component.this.requestFocus ();
+ }
+
+ /**
+ * Adds a focus listener.
+ *
+ * @param l the listener to add
+ */
+ public void addFocusListener(FocusListener l)
+ {
+ Component.this.addFocusListener(l);
+ }
+
+ /**
+ * Removes a focus listener.
+ *
+ * @param l the listener to remove
+ */
+ public void removeFocusListener(FocusListener l)
+ {
+ Component.this.removeFocusListener(l);
+ }
+
+ /**
+ * Converts component changes into property changes.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ * @status updated to 1.4
+ */
+ protected class AccessibleAWTComponentHandler implements ComponentListener
+ {
+ /**
+ * Default constructor.
+ */
+ protected AccessibleAWTComponentHandler()
+ {
+ }
+
+ /**
+ * Convert a component hidden to a property change.
+ *
+ * @param e the event to convert
+ */
+ public void componentHidden(ComponentEvent e)
+ {
+ AccessibleAWTComponent.this.firePropertyChange
+ (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null);
+ }
+
+ /**
+ * Convert a component shown to a property change.
+ *
+ * @param e the event to convert
+ */
+ public void componentShown(ComponentEvent e)
+ {
+ AccessibleAWTComponent.this.firePropertyChange
+ (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE);
+ }
+
+ /**
+ * Moving a component does not affect properties.
+ *
+ * @param e ignored
+ */
+ public void componentMoved(ComponentEvent e)
+ {
+ }
+
+ /**
+ * Resizing a component does not affect properties.
+ *
+ * @param e ignored
+ */
+ public void componentResized(ComponentEvent e)
+ {
+ }
+ } // class AccessibleAWTComponentHandler
+
+ /**
+ * Converts focus changes into property changes.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ * @status updated to 1.4
+ */
+ protected class AccessibleAWTFocusHandler implements FocusListener
+ {
+ /**
+ * Default constructor.
+ */
+ protected AccessibleAWTFocusHandler()
+ {
+ }
+
+ /**
+ * Convert a focus gained to a property change.
+ *
+ * @param e the event to convert
+ */
+ public void focusGained(FocusEvent e)
+ {
+ AccessibleAWTComponent.this.firePropertyChange
+ (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED);
+ }
+
+ /**
+ * Convert a focus lost to a property change.
+ *
+ * @param e the event to convert
+ */
+ public void focusLost(FocusEvent e)
+ {
+ AccessibleAWTComponent.this.firePropertyChange
+ (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
+ }
+ } // class AccessibleAWTComponentHandler
+ } // class AccessibleAWTComponent
+
+ /**
+ * This class provides support for blitting offscreen surfaces to a
+ * component.
+ *
+ * @see BufferStrategy
+ *
+ * @since 1.4
+ */
+ protected class BltBufferStrategy extends BufferStrategy
+ {
+ /**
+ * The capabilities of the image buffer.
+ */
+ protected BufferCapabilities caps;
+
+ /**
+ * The back buffers used in this strategy.
+ */
+ protected VolatileImage[] backBuffers;
+
+ /**
+ * Whether or not the image buffer resources are allocated and
+ * ready to be drawn into.
+ */
+ protected boolean validatedContents;
+
+ /**
+ * The width of the back buffers.
+ */
+ protected int width;
+
+ /**
+ * The height of the back buffers.
+ */
+ protected int height;
+
+ /**
+ * The front buffer.
+ */
+ private VolatileImage frontBuffer;
+
+ /**
+ * Creates a blitting buffer strategy.
+ *
+ * @param numBuffers the number of buffers, including the front
+ * buffer
+ * @param caps the capabilities of this strategy
+ */
+ protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
+ {
+ this.caps = caps;
+ createBackBuffers(numBuffers - 1);
+ width = getWidth();
+ height = getHeight();
+ }
+
+ /**
+ * Initializes the backBuffers field with an array of numBuffers
+ * VolatileImages.
+ *
+ * @param numBuffers the number of backbuffers to create
+ */
+ protected void createBackBuffers(int numBuffers)
+ {
+ GraphicsConfiguration c =
+ GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration();
+
+ backBuffers = new VolatileImage[numBuffers];
+
+ for (int i = 0; i < numBuffers; i++)
+ backBuffers[i] = c.createCompatibleVolatileImage(width, height);
+ }
+
+ /**
+ * Retrieves the capabilities of this buffer strategy.
+ *
+ * @return the capabilities of this buffer strategy
+ */
+ public BufferCapabilities getCapabilities()
+ {
+ return caps;
+ }
+
+ /**
+ * Retrieves a graphics object that can be used to draw into this
+ * strategy's image buffer.
+ *
+ * @return a graphics object
+ */
+ public Graphics getDrawGraphics()
+ {
+ // Return the backmost buffer's graphics.
+ return backBuffers[0].getGraphics();
+ }
+
+ /**
+ * Bring the contents of the back buffer to the front buffer.
+ */
+ public void show()
+ {
+ GraphicsConfiguration c =
+ GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration();
+
+ // draw the front buffer.
+ getGraphics().drawImage(backBuffers[backBuffers.length - 1],
+ width, height, null);
+
+ BufferCapabilities.FlipContents f = getCapabilities().getFlipContents();
+
+ // blit the back buffers.
+ for (int i = backBuffers.length - 1; i > 0 ; i--)
+ backBuffers[i] = backBuffers[i - 1];
+
+ // create new backmost buffer.
+ if (f == BufferCapabilities.FlipContents.UNDEFINED)
+ backBuffers[0] = c.createCompatibleVolatileImage(width, height);
+
+ // create new backmost buffer and clear it to the background
+ // color.
+ if (f == BufferCapabilities.FlipContents.BACKGROUND)
+ {
+ backBuffers[0] = c.createCompatibleVolatileImage(width, height);
+ backBuffers[0].getGraphics().clearRect(0, 0, width, height);
+ }
+
+ // FIXME: set the backmost buffer to the prior contents of the
+ // front buffer. How do we retrieve the contents of the front
+ // buffer?
+ //
+ // if (f == BufferCapabilities.FlipContents.PRIOR)
+
+ // set the backmost buffer to a copy of the new front buffer.
+ if (f == BufferCapabilities.FlipContents.COPIED)
+ backBuffers[0] = backBuffers[backBuffers.length - 1];
+ }
+
+ /**
+ * Re-create the image buffer resources if they've been lost.
+ */
+ protected void revalidate()
+ {
+ GraphicsConfiguration c =
+ GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration();
+
+ for (int i = 0; i < backBuffers.length; i++)
+ {
+ int result = backBuffers[i].validate(c);
+ if (result == VolatileImage.IMAGE_INCOMPATIBLE)
+ backBuffers[i] = c.createCompatibleVolatileImage(width, height);
+ }
+ validatedContents = true;
+ }
+
+ /**
+ * Returns whether or not the image buffer resources have been
+ * lost.
+ *
+ * @return true if the resources have been lost, false otherwise
+ */
+ public boolean contentsLost()
+ {
+ for (int i = 0; i < backBuffers.length; i++)
+ {
+ if (backBuffers[i].contentsLost())
+ {
+ validatedContents = false;
+ return true;
+ }
+ }
+ // we know that the buffer resources are valid now because we
+ // just checked them
+ validatedContents = true;
+ return false;
+ }
+
+ /**
+ * Returns whether or not the image buffer resources have been
+ * restored.
+ *
+ * @return true if the resources have been restored, false
+ * otherwise
+ */
+ public boolean contentsRestored()
+ {
+ GraphicsConfiguration c =
+ GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration();
+
+ boolean imageRestored = false;
+
+ for (int i = 0; i < backBuffers.length; i++)
+ {
+ int result = backBuffers[i].validate(c);
+ if (result == VolatileImage.IMAGE_RESTORED)
+ imageRestored = true;
+ else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
+ return false;
+ }
+ // we know that the buffer resources are valid now because we
+ // just checked them
+ validatedContents = true;
+ return imageRestored;
+ }
+ }
+
+ /**
+ * This class provides support for flipping component buffers. It
+ * can only be used on Canvases and Windows.
+ *
+ * @since 1.4
+ */
+ protected class FlipBufferStrategy extends BufferStrategy
+ {
+ /**
+ * The number of buffers.
+ */
+ protected int numBuffers;
+
+ /**
+ * The capabilities of this buffering strategy.
+ */
+ protected BufferCapabilities caps;
+
+ /**
+ * An Image reference to the drawing buffer.
+ */
+ protected Image drawBuffer;
+
+ /**
+ * A VolatileImage reference to the drawing buffer.
+ */
+ protected VolatileImage drawVBuffer;
+
+ /**
+ * Whether or not the image buffer resources are allocated and
+ * ready to be drawn into.
+ */
+ protected boolean validatedContents;
+
+ /**
+ * The width of the back buffer.
+ */
+ private int width;
+
+ /**
+ * The height of the back buffer.
+ */
+ private int height;
+
+ /**
+ * Creates a flipping buffer strategy. The only supported
+ * strategy for FlipBufferStrategy itself is a double-buffer page
+ * flipping strategy. It forms the basis for more complex derived
+ * strategies.
+ *
+ * @param numBuffers the number of buffers
+ * @param caps the capabilities of this buffering strategy
+ *
+ * @throws AWTException if the requested
+ * number-of-buffers/capabilities combination is not supported
+ */
+ protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
+ throws AWTException
+ {
+ this.caps = caps;
+ width = getWidth();
+ height = getHeight();
+
+ if (numBuffers > 1)
+ createBuffers(numBuffers, caps);
+ else
+ {
+ drawVBuffer = peer.createVolatileImage(width, height);
+ drawBuffer = drawVBuffer;
+ }
+ }
+
+ /**
+ * Creates a multi-buffer flipping strategy. The number of
+ * buffers must be greater than one and the buffer capabilities
+ * must specify page flipping.
+ *
+ * @param numBuffers the number of flipping buffers; must be
+ * greater than one
+ * @param caps the buffering capabilities; caps.isPageFlipping()
+ * must return true
+ *
+ * @throws IllegalArgumentException if numBuffers is not greater
+ * than one or if the page flipping capability is not requested
+ *
+ * @throws AWTException if the requested flipping strategy is not
+ * supported
+ */
+ protected void createBuffers(int numBuffers, BufferCapabilities caps)
+ throws AWTException
+ {
+ if (numBuffers <= 1)
+ throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
+ + " numBuffers must be greater than"
+ + " one.");
+
+ if (!caps.isPageFlipping())
+ throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
+ + " flipping must be a specified"
+ + " capability.");
+
+ peer.createBuffers(numBuffers, caps);
+ }
+
+ /**
+ * Return a direct reference to the back buffer image.
+ *
+ * @return a direct reference to the back buffer image.
+ */
+ protected Image getBackBuffer()
+ {
+ return peer.getBackBuffer();
+ }
+
+ /**
+ * Perform a flip operation to transfer the contents of the back
+ * buffer to the front buffer.
+ */
+ protected void flip(BufferCapabilities.FlipContents flipAction)
+ {
+ peer.flip(flipAction);
+ }
+
+ /**
+ * Release the back buffer's resources.
+ */
+ protected void destroyBuffers()
+ {
+ peer.destroyBuffers();
+ }
+
+ /**
+ * Retrieves the capabilities of this buffer strategy.
+ *
+ * @return the capabilities of this buffer strategy
+ */
+ public BufferCapabilities getCapabilities()
+ {
+ return caps;
+ }
+
+ /**
+ * Retrieves a graphics object that can be used to draw into this
+ * strategy's image buffer.
+ *
+ * @return a graphics object
+ */
+ public Graphics getDrawGraphics()
+ {
+ return drawVBuffer.getGraphics();
+ }
+
+ /**
+ * Re-create the image buffer resources if they've been lost.
+ */
+ protected void revalidate()
+ {
+ GraphicsConfiguration c =
+ GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration();
+
+ if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE)
+ drawVBuffer = peer.createVolatileImage(width, height);
+ validatedContents = true;
+ }
+
+ /**
+ * Returns whether or not the image buffer resources have been
+ * lost.
+ *
+ * @return true if the resources have been lost, false otherwise
+ */
+ public boolean contentsLost()
+ {
+ if (drawVBuffer.contentsLost())
+ {
+ validatedContents = false;
+ return true;
+ }
+ // we know that the buffer resources are valid now because we
+ // just checked them
+ validatedContents = true;
+ return false;
+ }
+
+ /**
+ * Returns whether or not the image buffer resources have been
+ * restored.
+ *
+ * @return true if the resources have been restored, false
+ * otherwise
+ */
+ public boolean contentsRestored()
+ {
+ GraphicsConfiguration c =
+ GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration();
+
+ int result = drawVBuffer.validate(c);
+
+ boolean imageRestored = false;
+
+ if (result == VolatileImage.IMAGE_RESTORED)
+ imageRestored = true;
+ else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
+ return false;
+
+ // we know that the buffer resources are valid now because we
+ // just checked them
+ validatedContents = true;
+ return imageRestored;
+ }
+
+ /**
+ * Bring the contents of the back buffer to the front buffer.
+ */
+ public void show()
+ {
+ flip(caps.getFlipContents());
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/ComponentOrientation.java b/libjava/classpath/java/awt/ComponentOrientation.java
new file mode 100644
index 0000000..69b14c7
--- /dev/null
+++ b/libjava/classpath/java/awt/ComponentOrientation.java
@@ -0,0 +1,215 @@
+/* ComponentOrientation.java -- describes a component's orientation
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This class is used to differentiate different orientations for text layout.
+ * It controls whether text flows left-to-right or right-to-left, and whether
+ * lines are horizontal or vertical, as in this table:<br>
+ * <pre>
+ * LT RT TL TR
+ * A B C C B A A D G G D A
+ * D E F F E D B E H H E B
+ * G H I I H G C F I I F C
+ * </pre>
+ * <b>LT</b> languages are most common (left-to-right lines, top-to-bottom).
+ * This includes Western European languages, and optionally includes Japanese,
+ * Chinese, and Korean. <b>RT</b> languages (right-to-left lines,
+ * top-to-bottom) are mainly middle eastern, such as Hebrew and Arabic.
+ * <b>TR</b> languages flow top-to-bottom in a line, right-to-left, and are
+ * the basis of Japanese, Chinese, and Korean. Finally, <b>TL</b> languages
+ * flow top-to-bottom in a line, left-to-right, as in Mongolian.
+ *
+ * <p>This is a pretty poor excuse for a type-safe enum, since it is not
+ * guaranteed that orientation objects are unique (thanks to serialization),
+ * yet there is no equals() method. You would be wise to compare the output
+ * of isHorizontal() and isLeftToRight() rather than comparing objects with
+ * ==, especially since more constants may be added in the future.
+ *
+ * @author Bryce McKinlay (bryce@albatross.co.nz)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public final class ComponentOrientation implements Serializable
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -4113291392143563828L;
+
+ /** Constant for unknown orientation. */
+ private static final int UNKNOWN_ID = 1;
+
+ /** Constant for horizontal line orientation. */
+ private static final int HORIZONTAL_ID = 2;
+
+ /** Constant for left-to-right orientation. */
+ private static final int LEFT_TO_RIGHT_ID = 4;
+
+ /**
+ * Items run left to right, and lines flow top to bottom. Examples: English,
+ * French.
+ */
+ public static final ComponentOrientation LEFT_TO_RIGHT
+ = new ComponentOrientation(HORIZONTAL_ID | LEFT_TO_RIGHT_ID);
+
+ /**
+ * Items run right to left, and lines flow top to bottom. Examples: Arabic,
+ * Hebrew.
+ */
+ public static final ComponentOrientation RIGHT_TO_LEFT
+ = new ComponentOrientation(HORIZONTAL_ID);
+
+ /**
+ * The orientation is unknown for the locale. For backwards compatibility,
+ * this behaves like LEFT_TO_RIGHT in the instance methods.
+ */
+ public static final ComponentOrientation UNKNOWN
+ = new ComponentOrientation(UNKNOWN_ID | HORIZONTAL_ID | LEFT_TO_RIGHT_ID);
+
+ /**
+ * The orientation of this object; bitwise-or of unknown (1), horizontal (2),
+ * and left-to-right (4).
+ *
+ * @serial the orientation
+ */
+ private final int orientation;
+
+ /**
+ * Construct a given orientation.
+ *
+ * @param orientation the orientation
+ */
+ private ComponentOrientation(int orientation)
+ {
+ this.orientation = orientation;
+ }
+
+ /**
+ * Returns true if the lines are horizontal, in which case lines flow
+ * top-to-bottom. For example, English, Hebrew. Counterexamples: Japanese,
+ * Chinese, Korean, Mongolian.
+ *
+ * @return true if this orientation has horizontal lines
+ */
+ public boolean isHorizontal()
+ {
+ return (orientation & HORIZONTAL_ID) != 0;
+ }
+
+ /**
+ * If isHorizontal() returns true, then this determines whether items in
+ * the line flow left-to-right. If isHorizontal() returns false, items in
+ * a line flow top-to-bottom, and this determines if lines flow
+ * left-to-right.
+ *
+ * @return true if this orientation flows left-to-right
+ */
+ public boolean isLeftToRight()
+ {
+ return (orientation & LEFT_TO_RIGHT_ID) != 0;
+ }
+
+ /**
+ * Gets an orientation appropriate for the locale.
+ *
+ * @param locale the locale
+ * @return the orientation for that locale
+ * @throws NullPointerException if locale is null
+ */
+ public static ComponentOrientation getOrientation(Locale locale)
+ {
+ // Based on iterating over all languages defined in JDK 1.4, this behavior
+ // matches Sun's. However, it makes me wonder if any non-horizontal
+ // orientations even exist, as it sure contradicts their documentation.
+ String language = locale.getLanguage();
+ if ("ar".equals(language) || "fa".equals(language) || "iw".equals(language)
+ || "ur".equals(language))
+ return RIGHT_TO_LEFT;
+ return LEFT_TO_RIGHT;
+ }
+
+ /**
+ * Gets an orientation from a resource bundle. This tries the following:
+ *
+ * <ul>
+ * <li>Use the key "Orientation" to find an instance of ComponentOrientation
+ * in the bundle.</li>
+ * <li>Get the locale of the resource bundle, and get the orientation of
+ * that locale.</li>
+ * <li>Give up and get the orientation of the default locale.</li>
+ * </ul>
+ *
+ * @param bdl the bundle to use
+ * @return the orientation
+ * @throws NullPointerException if bdl is null
+ * @deprecated use {@link #getOrientation(Locale)} instead
+ */
+ public static ComponentOrientation getOrientation(ResourceBundle bdl)
+ {
+ ComponentOrientation r;
+ try
+ {
+ r = (ComponentOrientation) bdl.getObject("Orientation");
+ if (r != null)
+ return r;
+ }
+ catch (MissingResourceException ignored)
+ {
+ }
+ catch (ClassCastException ignored)
+ {
+ }
+ try
+ {
+ r = getOrientation(bdl.getLocale());
+ if (r != null)
+ return r;
+ }
+ catch (Exception ignored)
+ {
+ }
+ return getOrientation(Locale.getDefault());
+ }
+} // class ComponentOrientation
diff --git a/libjava/classpath/java/awt/Composite.java b/libjava/classpath/java/awt/Composite.java
new file mode 100644
index 0000000..ca3abe4
--- /dev/null
+++ b/libjava/classpath/java/awt/Composite.java
@@ -0,0 +1,73 @@
+/* Composite.java -- graphics formed from composite layers
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.ColorModel;
+
+/**
+ * This interface is for graphics which are formed as composites of others.
+ * It combines {@link Graphics2D} shapes according to defined rules to form
+ * the new image. Implementations of this interface must be immutable, because
+ * they are not cloned when a Graphics2D container is cloned.
+ *
+ * <p>Since this can expose pixels to untrusted code, there is a security
+ * check on custom objects, <code>readDisplayPixels</code>, to prevent leaking
+ * restricted information graphically.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see AlphaComposite
+ * @see CompositeContext
+ * @see Graphics2D#setComposite(Composite)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface Composite
+{
+ /**
+ * Create a context state for performing the compositing operation. Several
+ * contexts may exist for this object, in a multi-threaded environment.
+ *
+ * @param srcColorModel the color model of the source
+ * @param dstColorModel the color model of the destination
+ * @param hints hints for choosing between rendering alternatives
+ */
+ CompositeContext createContext(ColorModel srcColorModel,
+ ColorModel dstColorModel,
+ RenderingHints hints);
+} // interface Composite
diff --git a/libjava/classpath/java/awt/CompositeContext.java b/libjava/classpath/java/awt/CompositeContext.java
new file mode 100644
index 0000000..018a270
--- /dev/null
+++ b/libjava/classpath/java/awt/CompositeContext.java
@@ -0,0 +1,71 @@
+/* Composite.java -- the context for compositing graphics layers
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * This interface provides an optimized environment for compositing graphics.
+ * Several such contexts may exist for a given <code>Composite</code> object.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Composite
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface CompositeContext
+{
+ /**
+ * Release resources allocated for the compositing.
+ */
+ void dispose();
+
+ /**
+ * Compose the two source images into the composite image. The destination
+ * can be the same as one of the two inputs, and the destination must be
+ * compatible with the ColorModel chosen in {@link Composite#createContext}.
+ *
+ * @param src the lower image source in compositing
+ * @param dstIn the upper image source in compositing
+ * @param dstOut the destination for the composite
+ * @see Composite
+ */
+ void compose(Raster src, Raster dstIn, WritableRaster dstOut);
+} // interface CompositeContext
diff --git a/libjava/classpath/java/awt/Container.java b/libjava/classpath/java/awt/Container.java
new file mode 100644
index 0000000..303d13b
--- /dev/null
+++ b/libjava/classpath/java/awt/Container.java
@@ -0,0 +1,2026 @@
+/* Container.java -- parent container class in AWT
+ Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ContainerEvent;
+import java.awt.event.ContainerListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.peer.ContainerPeer;
+import java.awt.peer.LightweightPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.accessibility.Accessible;
+import javax.swing.SwingUtilities;
+
+/**
+ * A generic window toolkit object that acts as a container for other objects.
+ * Components are tracked in a list, and new elements are at the end of the
+ * list or bottom of the stacking order.
+ *
+ * @author original author unknown
+ * @author Eric Blake (ebb9@email.byu.edu)
+ *
+ * @since 1.0
+ *
+ * @status still missing 1.4 support
+ */
+public class Container extends Component
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 4613797578919906343L;
+
+ /* Serialized fields from the serialization spec. */
+ int ncomponents;
+ Component[] component;
+ LayoutManager layoutMgr;
+
+ LightweightDispatcher dispatcher;
+
+ Dimension maxSize;
+
+ /**
+ * @since 1.4
+ */
+ boolean focusCycleRoot;
+
+ int containerSerializedDataVersion;
+
+ /* Anything else is non-serializable, and should be declared "transient". */
+ transient ContainerListener containerListener;
+ transient PropertyChangeSupport changeSupport;
+
+ /** The focus traversal policy that determines how focus is
+ transferred between this Container and its children. */
+ private FocusTraversalPolicy focusTraversalPolicy;
+
+ /**
+ * The focus traversal keys, if not inherited from the parent or default
+ * keyboard manager. These sets will contain only AWTKeyStrokes that
+ * represent press and release events to use as focus control.
+ *
+ * @see #getFocusTraversalKeys(int)
+ * @see #setFocusTraversalKeys(int, Set)
+ * @since 1.4
+ */
+ transient Set[] focusTraversalKeys;
+
+ /**
+ * Default constructor for subclasses.
+ */
+ public Container()
+ {
+ }
+
+ /**
+ * Returns the number of components in this container.
+ *
+ * @return The number of components in this container.
+ */
+ public int getComponentCount()
+ {
+ return countComponents ();
+ }
+
+ /**
+ * Returns the number of components in this container.
+ *
+ * @return The number of components in this container.
+ *
+ * @deprecated use {@link #getComponentCount()} instead
+ */
+ public int countComponents()
+ {
+ return ncomponents;
+ }
+
+ /**
+ * Returns the component at the specified index.
+ *
+ * @param n The index of the component to retrieve.
+ *
+ * @return The requested component.
+ *
+ * @throws ArrayIndexOutOfBoundsException If the specified index is invalid
+ */
+ public Component getComponent(int n)
+ {
+ synchronized (getTreeLock ())
+ {
+ if (n < 0 || n >= ncomponents)
+ throw new ArrayIndexOutOfBoundsException("no such component");
+
+ return component[n];
+ }
+ }
+
+ /**
+ * Returns an array of the components in this container.
+ *
+ * @return The components in this container.
+ */
+ public Component[] getComponents()
+ {
+ synchronized (getTreeLock ())
+ {
+ Component[] result = new Component[ncomponents];
+
+ if (ncomponents > 0)
+ System.arraycopy(component, 0, result, 0, ncomponents);
+
+ return result;
+ }
+ }
+
+ /**
+ * Swaps the components at position i and j, in the container.
+ */
+
+ protected void swapComponents (int i, int j)
+ {
+ synchronized (getTreeLock ())
+ {
+ if (i < 0
+ || i >= component.length
+ || j < 0
+ || j >= component.length)
+ throw new ArrayIndexOutOfBoundsException ();
+ Component tmp = component[i];
+ component[i] = component[j];
+ component[j] = tmp;
+ }
+ }
+
+ /**
+ * Returns the insets for this container, which is the space used for
+ * borders, the margin, etc.
+ *
+ * @return The insets for this container.
+ */
+ public Insets getInsets()
+ {
+ return insets ();
+ }
+
+ /**
+ * Returns the insets for this container, which is the space used for
+ * borders, the margin, etc.
+ *
+ * @return The insets for this container.
+ * @deprecated use {@link #getInsets()} instead
+ */
+ public Insets insets()
+ {
+ if (peer == null)
+ return new Insets (0, 0, 0, 0);
+
+ return ((ContainerPeer) peer).getInsets ();
+ }
+
+ /**
+ * Adds the specified component to this container at the end of the
+ * component list.
+ *
+ * @param comp The component to add to the container.
+ *
+ * @return The same component that was added.
+ */
+ public Component add(Component comp)
+ {
+ addImpl(comp, null, -1);
+ return comp;
+ }
+
+ /**
+ * Adds the specified component to the container at the end of the
+ * component list. This method should not be used. Instead, use
+ * <code>add(Component, Object)</code>.
+ *
+ * @param name The name of the component to be added.
+ * @param comp The component to be added.
+ *
+ * @return The same component that was added.
+ *
+ * @see #add(Component,Object)
+ */
+ public Component add(String name, Component comp)
+ {
+ addImpl(comp, name, -1);
+ return comp;
+ }
+
+ /**
+ * Adds the specified component to this container at the specified index
+ * in the component list.
+ *
+ * @param comp The component to be added.
+ * @param index The index in the component list to insert this child
+ * at, or -1 to add at the end of the list.
+ *
+ * @return The same component that was added.
+ *
+ * @throws ArrayIndexOutOfBoundsException If the specified index is invalid.
+ */
+ public Component add(Component comp, int index)
+ {
+ addImpl(comp, null, index);
+ return comp;
+ }
+
+ /**
+ * Adds the specified component to this container at the end of the
+ * component list. The layout manager will use the specified constraints
+ * when laying out this component.
+ *
+ * @param comp The component to be added to this container.
+ * @param constraints The layout constraints for this component.
+ */
+ public void add(Component comp, Object constraints)
+ {
+ addImpl(comp, constraints, -1);
+ }
+
+ /**
+ * Adds the specified component to this container at the specified index
+ * in the component list. The layout manager will use the specified
+ * constraints when layout out this component.
+ *
+ * @param comp The component to be added.
+ * @param constraints The layout constraints for this component.
+ * @param index The index in the component list to insert this child
+ * at, or -1 to add at the end of the list.
+ *
+ * @throws ArrayIndexOutOfBoundsException If the specified index is invalid.
+ */
+ public void add(Component comp, Object constraints, int index)
+ {
+ addImpl(comp, constraints, index);
+ }
+
+ /**
+ * This method is called by all the <code>add()</code> methods to perform
+ * the actual adding of the component. Subclasses who wish to perform
+ * their own processing when a component is added should override this
+ * method. Any subclass doing this must call the superclass version of
+ * this method in order to ensure proper functioning of the container.
+ *
+ * @param comp The component to be added.
+ * @param constraints The layout constraints for this component, or
+ * <code>null</code> if there are no constraints.
+ * @param index The index in the component list to insert this child
+ * at, or -1 to add at the end of the list.
+ *
+ * @throws ArrayIndexOutOfBoundsException If the specified index is invalid.
+ */
+ protected void addImpl(Component comp, Object constraints, int index)
+ {
+ synchronized (getTreeLock ())
+ {
+ if (index > ncomponents
+ || (index < 0 && index != -1)
+ || comp instanceof Window
+ || (comp instanceof Container
+ && ((Container) comp).isAncestorOf(this)))
+ throw new IllegalArgumentException();
+
+ // Reparent component, and make sure component is instantiated if
+ // we are.
+ if (comp.parent != null)
+ comp.parent.remove(comp);
+ comp.parent = this;
+ if (peer != null)
+ {
+ if (comp.isLightweight ())
+ {
+ enableEvents (comp.eventMask);
+ if (!isLightweight ())
+ enableEvents (AWTEvent.PAINT_EVENT_MASK);
+ }
+ }
+
+ invalidate();
+
+ if (component == null)
+ component = new Component[4]; // FIXME, better initial size?
+
+ // This isn't the most efficient implementation. We could do less
+ // copying when growing the array. It probably doesn't matter.
+ if (ncomponents >= component.length)
+ {
+ int nl = component.length * 2;
+ Component[] c = new Component[nl];
+ System.arraycopy(component, 0, c, 0, ncomponents);
+ component = c;
+ }
+
+ if (index == -1)
+ component[ncomponents++] = comp;
+ else
+ {
+ System.arraycopy(component, index, component, index + 1,
+ ncomponents - index);
+ component[index] = comp;
+ ++ncomponents;
+ }
+
+ // Notify the layout manager.
+ if (layoutMgr != null)
+ {
+ if (layoutMgr instanceof LayoutManager2)
+ {
+ LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
+ lm2.addLayoutComponent(comp, constraints);
+ }
+ else if (constraints instanceof String)
+ layoutMgr.addLayoutComponent((String) constraints, comp);
+ else
+ layoutMgr.addLayoutComponent(null, comp);
+ }
+
+ if (isShowing ())
+ {
+ // Post event to notify of adding the component.
+ ContainerEvent ce = new ContainerEvent(this,
+ ContainerEvent.COMPONENT_ADDED,
+ comp);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+ }
+
+ /**
+ * Removes the component at the specified index from this container.
+ *
+ * @param index The index of the component to remove.
+ */
+ public void remove(int index)
+ {
+ synchronized (getTreeLock ())
+ {
+ Component r = component[index];
+
+ r.removeNotify();
+
+ System.arraycopy(component, index + 1, component, index,
+ ncomponents - index - 1);
+ component[--ncomponents] = null;
+
+ invalidate();
+
+ if (layoutMgr != null)
+ layoutMgr.removeLayoutComponent(r);
+
+ r.parent = null;
+
+ if (isShowing ())
+ {
+ // Post event to notify of removing the component.
+ ContainerEvent ce = new ContainerEvent(this,
+ ContainerEvent.COMPONENT_REMOVED,
+ r);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+ }
+
+ /**
+ * Removes the specified component from this container.
+ *
+ * @param comp The component to remove from this container.
+ */
+ public void remove(Component comp)
+ {
+ synchronized (getTreeLock ())
+ {
+ for (int i = 0; i < ncomponents; ++i)
+ {
+ if (component[i] == comp)
+ {
+ remove(i);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes all components from this container.
+ */
+ public void removeAll()
+ {
+ synchronized (getTreeLock ())
+ {
+ while (ncomponents > 0)
+ remove(0);
+ }
+ }
+
+ /**
+ * Returns the current layout manager for this container.
+ *
+ * @return The layout manager for this container.
+ */
+ public LayoutManager getLayout()
+ {
+ return layoutMgr;
+ }
+
+ /**
+ * Sets the layout manager for this container to the specified layout
+ * manager.
+ *
+ * @param mgr The new layout manager for this container.
+ */
+ public void setLayout(LayoutManager mgr)
+ {
+ layoutMgr = mgr;
+ invalidate();
+ }
+
+ /**
+ * Layout the components in this container.
+ */
+ public void doLayout()
+ {
+ layout ();
+ }
+
+ /**
+ * Layout the components in this container.
+ *
+ * @deprecated use {@link #doLayout()} instead
+ */
+ public void layout()
+ {
+ if (layoutMgr != null)
+ layoutMgr.layoutContainer (this);
+ }
+
+ /**
+ * Invalidates this container to indicate that it (and all parent
+ * containers) need to be laid out.
+ */
+ public void invalidate()
+ {
+ super.invalidate();
+ }
+
+ /**
+ * Re-lays out the components in this container.
+ */
+ public void validate()
+ {
+ synchronized (getTreeLock ())
+ {
+ if (! isValid() && peer != null)
+ {
+ validateTree();
+ }
+ }
+ }
+
+ /**
+ * Recursively invalidates the container tree.
+ */
+ void invalidateTree()
+ {
+ for (int i = 0; i < ncomponents; i++)
+ {
+ Component comp = component[i];
+ comp.invalidate();
+ if (comp instanceof Container)
+ ((Container) comp).invalidateTree();
+ }
+ }
+
+ /**
+ * Recursively validates the container tree, recomputing any invalid
+ * layouts.
+ */
+ protected void validateTree()
+ {
+ if (valid)
+ return;
+
+ ContainerPeer cPeer = null;
+ if (peer != null && ! (peer instanceof LightweightPeer))
+ {
+ cPeer = (ContainerPeer) peer;
+ cPeer.beginValidate();
+ }
+
+ for (int i = 0; i < ncomponents; ++i)
+ {
+ Component comp = component[i];
+
+ if (comp.getPeer () == null)
+ comp.addNotify();
+ }
+
+ doLayout ();
+ for (int i = 0; i < ncomponents; ++i)
+ {
+ Component comp = component[i];
+
+ if (! comp.isValid())
+ {
+ if (comp instanceof Container)
+ {
+ ((Container) comp).validateTree();
+ }
+ else
+ {
+ component[i].validate();
+ }
+ }
+ }
+
+ /* children will call invalidate() when they are layed out. It
+ is therefore important that valid is not set to true
+ until after the children have been layed out. */
+ valid = true;
+
+ if (cPeer != null)
+ cPeer.endValidate();
+ }
+
+ public void setFont(Font f)
+ {
+ super.setFont(f);
+ // FIXME: Although it might make more sense to invalidate only
+ // those children whose font == null, Sun invalidates all children.
+ // So we'll do the same.
+ invalidateTree();
+ }
+
+ /**
+ * Returns the preferred size of this container.
+ *
+ * @return The preferred size of this container.
+ */
+ public Dimension getPreferredSize()
+ {
+ return preferredSize ();
+ }
+
+ /**
+ * Returns the preferred size of this container.
+ *
+ * @return The preferred size of this container.
+ *
+ * @deprecated use {@link #getPreferredSize()} instead
+ */
+ public Dimension preferredSize()
+ {
+ if (layoutMgr != null)
+ return layoutMgr.preferredLayoutSize (this);
+ else
+ return super.preferredSize ();
+ }
+
+ /**
+ * Returns the minimum size of this container.
+ *
+ * @return The minimum size of this container.
+ */
+ public Dimension getMinimumSize()
+ {
+ return minimumSize ();
+ }
+
+ /**
+ * Returns the minimum size of this container.
+ *
+ * @return The minimum size of this container.
+ *
+ * @deprecated use {@link #getMinimumSize()} instead
+ */
+ public Dimension minimumSize()
+ {
+ if (layoutMgr != null)
+ return layoutMgr.minimumLayoutSize (this);
+ else
+ return super.minimumSize ();
+ }
+
+ /**
+ * Returns the maximum size of this container.
+ *
+ * @return The maximum size of this container.
+ */
+ public Dimension getMaximumSize()
+ {
+ if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
+ {
+ LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
+ return lm2.maximumLayoutSize(this);
+ }
+ else
+ return super.getMaximumSize();
+ }
+
+ /**
+ * Returns the preferred alignment along the X axis. This is a value
+ * between 0 and 1 where 0 represents alignment flush left and
+ * 1 means alignment flush right, and 0.5 means centered.
+ *
+ * @return The preferred alignment along the X axis.
+ */
+ public float getAlignmentX()
+ {
+ if (layoutMgr instanceof LayoutManager2)
+ {
+ LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
+ return lm2.getLayoutAlignmentX(this);
+ }
+ else
+ return super.getAlignmentX();
+ }
+
+ /**
+ * Returns the preferred alignment along the Y axis. This is a value
+ * between 0 and 1 where 0 represents alignment flush top and
+ * 1 means alignment flush bottom, and 0.5 means centered.
+ *
+ * @return The preferred alignment along the Y axis.
+ */
+ public float getAlignmentY()
+ {
+ if (layoutMgr instanceof LayoutManager2)
+ {
+ LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
+ return lm2.getLayoutAlignmentY(this);
+ }
+ else
+ return super.getAlignmentY();
+ }
+
+ /**
+ * Paints this container. The implementation of this method in this
+ * class forwards to any lightweight components in this container. If
+ * this method is subclassed, this method should still be invoked as
+ * a superclass method so that lightweight components are properly
+ * drawn.
+ *
+ * @param g The graphics context for this paint job.
+ */
+ public void paint(Graphics g)
+ {
+ if (!isShowing())
+ return;
+ // Paint self first.
+ super.paint(g);
+ // Visit heavyweights as well, in case they were
+ // erased when we cleared the background for this container.
+ visitChildren(g, GfxPaintVisitor.INSTANCE, false);
+ }
+
+ /**
+ * Updates this container. The implementation of this method in this
+ * class forwards to any lightweight components in this container. If
+ * this method is subclassed, this method should still be invoked as
+ * a superclass method so that lightweight components are properly
+ * drawn.
+ *
+ * @param g The graphics context for this update.
+ */
+ public void update(Graphics g)
+ {
+ super.update(g);
+ }
+
+ /**
+ * Prints this container. The implementation of this method in this
+ * class forwards to any lightweight components in this container. If
+ * this method is subclassed, this method should still be invoked as
+ * a superclass method so that lightweight components are properly
+ * drawn.
+ *
+ * @param g The graphics context for this print job.
+ */
+ public void print(Graphics g)
+ {
+ super.print(g);
+ visitChildren(g, GfxPrintVisitor.INSTANCE, true);
+ }
+
+ /**
+ * Paints all of the components in this container.
+ *
+ * @param g The graphics context for this paint job.
+ */
+ public void paintComponents(Graphics g)
+ {
+ super.paint(g);
+ visitChildren(g, GfxPaintAllVisitor.INSTANCE, true);
+ }
+
+ /**
+ * Prints all of the components in this container.
+ *
+ * @param g The graphics context for this print job.
+ */
+ public void printComponents(Graphics g)
+ {
+ super.paint(g);
+ visitChildren(g, GfxPrintAllVisitor.INSTANCE, true);
+ }
+
+ /**
+ * Adds the specified container listener to this object's list of
+ * container listeners.
+ *
+ * @param listener The listener to add.
+ */
+ public synchronized void addContainerListener(ContainerListener listener)
+ {
+ containerListener = AWTEventMulticaster.add(containerListener, listener);
+ }
+
+ /**
+ * Removes the specified container listener from this object's list of
+ * container listeners.
+ *
+ * @param listener The listener to remove.
+ */
+ public synchronized void removeContainerListener(ContainerListener listener)
+ {
+ containerListener = AWTEventMulticaster.remove(containerListener, listener);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public synchronized ContainerListener[] getContainerListeners()
+ {
+ return (ContainerListener[])
+ AWTEventMulticaster.getListeners(containerListener,
+ ContainerListener.class);
+ }
+
+ /**
+ * Returns an array of all the objects currently registered as FooListeners
+ * upon this Container. FooListeners are registered using the addFooListener
+ * method.
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements @see java.util.EventListener.
+ *
+ * @since 1.3
+ */
+ public EventListener[] getListeners(Class listenerType)
+ {
+ if (listenerType == ContainerListener.class)
+ return getContainerListeners();
+ return super.getListeners(listenerType);
+ }
+
+ /**
+ * Processes the specified event. This method calls
+ * <code>processContainerEvent()</code> if this method is a
+ * <code>ContainerEvent</code>, otherwise it calls the superclass
+ * method.
+ *
+ * @param e The event to be processed.
+ */
+ protected void processEvent(AWTEvent e)
+ {
+ if (e instanceof ContainerEvent)
+ processContainerEvent((ContainerEvent) e);
+ else
+ super.processEvent(e);
+ }
+
+ /**
+ * Called when a container event occurs if container events are enabled.
+ * This method calls any registered listeners.
+ *
+ * @param e The event that occurred.
+ */
+ protected void processContainerEvent(ContainerEvent e)
+ {
+ if (containerListener == null)
+ return;
+ switch (e.id)
+ {
+ case ContainerEvent.COMPONENT_ADDED:
+ containerListener.componentAdded(e);
+ break;
+
+ case ContainerEvent.COMPONENT_REMOVED:
+ containerListener.componentRemoved(e);
+ break;
+ }
+ }
+
+ /**
+ * AWT 1.0 event processor.
+ *
+ * @param e The event that occurred.
+ *
+ * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
+ */
+ public void deliverEvent(Event e)
+ {
+ if (!handleEvent (e))
+ {
+ synchronized (getTreeLock ())
+ {
+ Component parent = getParent ();
+
+ if (parent != null)
+ parent.deliverEvent (e);
+ }
+ }
+ }
+
+ /**
+ * Returns the component located at the specified point. This is done
+ * by checking whether or not a child component claims to contain this
+ * point. The first child component that does is returned. If no
+ * child component claims the point, the container itself is returned,
+ * unless the point does not exist within this container, in which
+ * case <code>null</code> is returned.
+ *
+ * @param x The X coordinate of the point.
+ * @param y The Y coordinate of the point.
+ *
+ * @return The component containing the specified point, or
+ * <code>null</code> if there is no such point.
+ */
+ public Component getComponentAt(int x, int y)
+ {
+ return locate (x, y);
+ }
+
+ /**
+ * Returns the component located at the specified point. This is done
+ * by checking whether or not a child component claims to contain this
+ * point. The first child component that does is returned. If no
+ * child component claims the point, the container itself is returned,
+ * unless the point does not exist within this container, in which
+ * case <code>null</code> is returned.
+ *
+ * @param x The x position of the point to return the component at.
+ * @param y The y position of the point to return the component at.
+ *
+ * @return The component containing the specified point, or <code>null</code>
+ * if there is no such point.
+ *
+ * @deprecated use {@link #getComponentAt(int, int)} instead
+ */
+ public Component locate(int x, int y)
+ {
+ synchronized (getTreeLock ())
+ {
+ if (!contains (x, y))
+ return null;
+ for (int i = 0; i < ncomponents; ++i)
+ {
+ // Ignore invisible children...
+ if (!component[i].isVisible ())
+ continue;
+
+ int x2 = x - component[i].x;
+ int y2 = y - component[i].y;
+ if (component[i].contains (x2, y2))
+ return component[i];
+ }
+ return this;
+ }
+ }
+
+ /**
+ * Returns the component located at the specified point. This is done
+ * by checking whether or not a child component claims to contain this
+ * point. The first child component that does is returned. If no
+ * child component claims the point, the container itself is returned,
+ * unless the point does not exist within this container, in which
+ * case <code>null</code> is returned.
+ *
+ * @param p The point to return the component at.
+ * @return The component containing the specified point, or <code>null</code>
+ * if there is no such point.
+ */
+ public Component getComponentAt(Point p)
+ {
+ return getComponentAt (p.x, p.y);
+ }
+
+ public Component findComponentAt(int x, int y)
+ {
+ synchronized (getTreeLock ())
+ {
+ if (! contains(x, y))
+ return null;
+
+ for (int i = 0; i < ncomponents; ++i)
+ {
+ // Ignore invisible children...
+ if (!component[i].isVisible())
+ continue;
+
+ int x2 = x - component[i].x;
+ int y2 = y - component[i].y;
+ // We don't do the contains() check right away because
+ // findComponentAt would redundantly do it first thing.
+ if (component[i] instanceof Container)
+ {
+ Container k = (Container) component[i];
+ Component r = k.findComponentAt(x2, y2);
+ if (r != null)
+ return r;
+ }
+ else if (component[i].contains(x2, y2))
+ return component[i];
+ }
+
+ return this;
+ }
+ }
+
+ public Component findComponentAt(Point p)
+ {
+ return findComponentAt(p.x, p.y);
+ }
+
+ /**
+ * Called when this container is added to another container to inform it
+ * to create its peer. Peers for any child components will also be
+ * created.
+ */
+ public void addNotify()
+ {
+ super.addNotify();
+ addNotifyContainerChildren();
+ }
+
+ /**
+ * Called when this container is removed from its parent container to
+ * inform it to destroy its peer. This causes the peers of all child
+ * component to be destroyed as well.
+ */
+ public void removeNotify()
+ {
+ synchronized (getTreeLock ())
+ {
+ for (int i = 0; i < ncomponents; ++i)
+ component[i].removeNotify();
+ super.removeNotify();
+ }
+ }
+
+ /**
+ * Tests whether or not the specified component is contained within
+ * this components subtree.
+ *
+ * @param comp The component to test.
+ *
+ * @return <code>true</code> if this container is an ancestor of the
+ * specified component, <code>false</code> otherwise.
+ */
+ public boolean isAncestorOf(Component comp)
+ {
+ synchronized (getTreeLock ())
+ {
+ while (true)
+ {
+ if (comp == null)
+ return false;
+ if (comp == this)
+ return true;
+ comp = comp.getParent();
+ }
+ }
+ }
+
+ /**
+ * Returns a string representing the state of this container for
+ * debugging purposes.
+ *
+ * @return A string representing the state of this container.
+ */
+ protected String paramString()
+ {
+ if (layoutMgr == null)
+ return super.paramString();
+
+ StringBuffer sb = new StringBuffer();
+ sb.append(super.paramString());
+ sb.append(",layout=");
+ sb.append(layoutMgr.getClass().getName());
+ return sb.toString();
+ }
+
+ /**
+ * Writes a listing of this container to the specified stream starting
+ * at the specified indentation point.
+ *
+ * @param out The <code>PrintStream</code> to write to.
+ * @param indent The indentation point.
+ */
+ public void list(PrintStream out, int indent)
+ {
+ synchronized (getTreeLock ())
+ {
+ super.list(out, indent);
+ for (int i = 0; i < ncomponents; ++i)
+ component[i].list(out, indent + 2);
+ }
+ }
+
+ /**
+ * Writes a listing of this container to the specified stream starting
+ * at the specified indentation point.
+ *
+ * @param out The <code>PrintWriter</code> to write to.
+ * @param indent The indentation point.
+ */
+ public void list(PrintWriter out, int indent)
+ {
+ synchronized (getTreeLock ())
+ {
+ super.list(out, indent);
+ for (int i = 0; i < ncomponents; ++i)
+ component[i].list(out, indent + 2);
+ }
+ }
+
+ /**
+ * Sets the focus traversal keys for a given traversal operation for this
+ * Container.
+ *
+ * @exception IllegalArgumentException If id is not one of
+ * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
+ * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS,
+ * or if keystrokes contains null, or if any Object in keystrokes is not an
+ * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event, or if any
+ * keystroke already maps to another focus traversal operation for this
+ * Container.
+ *
+ * @since 1.4
+ */
+ public void setFocusTraversalKeys(int id, Set keystrokes)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+
+ if (keystrokes == null)
+ {
+ Container parent = getParent ();
+
+ while (parent != null)
+ {
+ if (parent.areFocusTraversalKeysSet (id))
+ {
+ keystrokes = parent.getFocusTraversalKeys (id);
+ break;
+ }
+ parent = parent.getParent ();
+ }
+
+ if (keystrokes == null)
+ keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
+ getDefaultFocusTraversalKeys (id);
+ }
+
+ Set sa;
+ Set sb;
+ Set sc;
+ String name;
+ switch (id)
+ {
+ case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ sc = getFocusTraversalKeys
+ (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+ name = "forwardFocusTraversalKeys";
+ break;
+ case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ sc = getFocusTraversalKeys
+ (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+ name = "backwardFocusTraversalKeys";
+ break;
+ case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ sc = getFocusTraversalKeys
+ (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+ name = "upCycleFocusTraversalKeys";
+ break;
+ case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ sc = getFocusTraversalKeys
+ (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ name = "downCycleFocusTraversalKeys";
+ break;
+ default:
+ throw new IllegalArgumentException ();
+ }
+
+ int i = keystrokes.size ();
+ Iterator iter = keystrokes.iterator ();
+
+ while (--i >= 0)
+ {
+ Object o = iter.next ();
+ if (!(o instanceof AWTKeyStroke)
+ || sa.contains (o) || sb.contains (o) || sc.contains (o)
+ || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
+ throw new IllegalArgumentException ();
+ }
+
+ if (focusTraversalKeys == null)
+ focusTraversalKeys = new Set[3];
+
+ keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
+ firePropertyChange (name, focusTraversalKeys[id], keystrokes);
+
+ focusTraversalKeys[id] = keystrokes;
+ }
+
+ /**
+ * Returns the Set of focus traversal keys for a given traversal operation for
+ * this Container.
+ *
+ * @exception IllegalArgumentException If id is not one of
+ * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
+ * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS.
+ *
+ * @since 1.4
+ */
+ public Set getFocusTraversalKeys (int id)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+
+ Set s = null;
+
+ if (focusTraversalKeys != null)
+ s = focusTraversalKeys[id];
+
+ if (s == null && parent != null)
+ s = parent.getFocusTraversalKeys (id);
+
+ return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
+ .getDefaultFocusTraversalKeys(id)) : s;
+ }
+
+ /**
+ * Returns whether the Set of focus traversal keys for the given focus
+ * traversal operation has been explicitly defined for this Container.
+ * If this method returns false, this Container is inheriting the Set from
+ * an ancestor, or from the current KeyboardFocusManager.
+ *
+ * @exception IllegalArgumentException If id is not one of
+ * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
+ * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS.
+ *
+ * @since 1.4
+ */
+ public boolean areFocusTraversalKeysSet (int id)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+
+ return focusTraversalKeys != null && focusTraversalKeys[id] != null;
+ }
+
+ /**
+ * Check whether the given Container is the focus cycle root of this
+ * Container's focus traversal cycle. If this Container is a focus
+ * cycle root itself, then it will be in two different focus cycles
+ * -- it's own, and that of its ancestor focus cycle root's. In
+ * that case, if <code>c</code> is either of those containers, this
+ * method will return true.
+ *
+ * @param c the candidate Container
+ *
+ * @return true if c is the focus cycle root of the focus traversal
+ * cycle to which this Container belongs, false otherwise
+ *
+ * @since 1.4
+ */
+ public boolean isFocusCycleRoot (Container c)
+ {
+ if (this == c
+ && isFocusCycleRoot ())
+ return true;
+
+ Container ancestor = getFocusCycleRootAncestor ();
+
+ if (c == ancestor)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * If this Container is a focus cycle root, set the focus traversal
+ * policy that determines the focus traversal order for its
+ * children. If non-null, this policy will be inherited by all
+ * inferior focus cycle roots. If <code>policy</code> is null, this
+ * Container will inherit its policy from the closest ancestor focus
+ * cycle root that's had its policy set.
+ *
+ * @param policy the new focus traversal policy for this Container or null
+ *
+ * @since 1.4
+ */
+ public void setFocusTraversalPolicy (FocusTraversalPolicy policy)
+ {
+ focusTraversalPolicy = policy;
+ }
+
+ /**
+ * Return the focus traversal policy that determines the focus
+ * traversal order for this Container's children. This method
+ * returns null if this Container is not a focus cycle root. If the
+ * focus traversal policy has not been set explicitly, then this
+ * method will return an ancestor focus cycle root's policy instead.
+ *
+ * @return this Container's focus traversal policy or null
+ *
+ * @since 1.4
+ */
+ public FocusTraversalPolicy getFocusTraversalPolicy ()
+ {
+ if (!isFocusCycleRoot ())
+ return null;
+
+ if (focusTraversalPolicy == null)
+ {
+ Container ancestor = getFocusCycleRootAncestor ();
+
+ if (ancestor != this)
+ return ancestor.getFocusTraversalPolicy ();
+ else
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ return manager.getDefaultFocusTraversalPolicy ();
+ }
+ }
+ else
+ return focusTraversalPolicy;
+ }
+
+ /**
+ * Check whether this Container's focus traversal policy has been
+ * explicitly set. If it has not, then this Container will inherit
+ * its focus traversal policy from one of its ancestor focus cycle
+ * roots.
+ *
+ * @return true if focus traversal policy is set, false otherwise
+ */
+ public boolean isFocusTraversalPolicySet ()
+ {
+ return focusTraversalPolicy == null;
+ }
+
+ /**
+ * Set whether or not this Container is the root of a focus
+ * traversal cycle. This Container's focus traversal policy
+ * determines the order of focus traversal. Some policies prevent
+ * the focus from being transferred between two traversal cycles
+ * until an up or down traversal operation is performed. In that
+ * case, normal traversal (not up or down) is limited to this
+ * Container and all of this Container's descendents that are not
+ * descendents of inferior focus cycle roots. In the default case
+ * however, ContainerOrderFocusTraversalPolicy is in effect, and it
+ * supports implicit down-cycle traversal operations.
+ *
+ * @param focusCycleRoot true if this is a focus cycle root, false otherwise
+ *
+ * @since 1.4
+ */
+ public void setFocusCycleRoot (boolean focusCycleRoot)
+ {
+ this.focusCycleRoot = focusCycleRoot;
+ }
+
+ /**
+ * Check whether this Container is a focus cycle root.
+ *
+ * @return true if this is a focus cycle root, false otherwise
+ *
+ * @since 1.4
+ */
+ public boolean isFocusCycleRoot ()
+ {
+ return focusCycleRoot;
+ }
+
+ /**
+ * Transfer focus down one focus traversal cycle. If this Container
+ * is a focus cycle root, then its default component becomes the
+ * focus owner, and this Container becomes the current focus cycle
+ * root. No traversal will occur if this Container is not a focus
+ * cycle root.
+ *
+ * @since 1.4
+ */
+ public void transferFocusDownCycle ()
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ manager.downFocusCycle (this);
+ }
+
+ /**
+ * Sets the ComponentOrientation property of this container and all components
+ * contained within it.
+ *
+ * @exception NullPointerException If orientation is null
+ *
+ * @since 1.4
+ */
+ public void applyComponentOrientation (ComponentOrientation orientation)
+ {
+ if (orientation == null)
+ throw new NullPointerException ();
+ }
+
+ public void addPropertyChangeListener (PropertyChangeListener listener)
+ {
+ if (listener == null)
+ return;
+
+ if (changeSupport == null)
+ changeSupport = new PropertyChangeSupport (this);
+
+ changeSupport.addPropertyChangeListener (listener);
+ }
+
+ public void addPropertyChangeListener (String name,
+ PropertyChangeListener listener)
+ {
+ if (listener == null)
+ return;
+
+ if (changeSupport == null)
+ changeSupport = new PropertyChangeSupport (this);
+
+ changeSupport.addPropertyChangeListener (name, listener);
+ }
+
+ // Hidden helper methods.
+
+ /**
+ * Perform a graphics operation on the children of this container.
+ * For each applicable child, the visitChild() method will be called
+ * to perform the graphics operation.
+ *
+ * @param gfx The graphics object that will be used to derive new
+ * graphics objects for the children.
+ *
+ * @param visitor Object encapsulating the graphics operation that
+ * should be performed.
+ *
+ * @param lightweightOnly If true, only lightweight components will
+ * be visited.
+ */
+ private void visitChildren(Graphics gfx, GfxVisitor visitor,
+ boolean lightweightOnly)
+ {
+ synchronized (getTreeLock ())
+ {
+ for (int i = ncomponents - 1; i >= 0; --i)
+ {
+ Component comp = component[i];
+ // If we're visiting heavyweights as well,
+ // don't recurse into Containers here. This avoids
+ // painting the same nested child multiple times.
+ boolean applicable = comp.isVisible()
+ && (comp.isLightweight()
+ || !lightweightOnly && ! (comp instanceof Container));
+
+ if (applicable)
+ visitChild(gfx, visitor, comp);
+ }
+ }
+ }
+
+ /**
+ * Perform a graphics operation on a child. A translated and clipped
+ * graphics object will be created, and the visit() method of the
+ * visitor will be called to perform the operation.
+ *
+ * @param gfx The graphics object that will be used to derive new
+ * graphics objects for the child.
+ *
+ * @param visitor Object encapsulating the graphics operation that
+ * should be performed.
+ *
+ * @param comp The child component that should be visited.
+ */
+ private void visitChild(Graphics gfx, GfxVisitor visitor,
+ Component comp)
+ {
+ Rectangle bounds = comp.getBounds();
+ Rectangle oldClip = gfx.getClipBounds();
+ if (oldClip == null)
+ oldClip = bounds;
+
+ Rectangle clip = oldClip.intersection(bounds);
+
+ if (clip.isEmpty()) return;
+
+ boolean clipped = false;
+ boolean translated = false;
+ try
+ {
+ gfx.setClip(clip.x, clip.y, clip.width, clip.height);
+ clipped = true;
+ gfx.translate(bounds.x, bounds.y);
+ translated = true;
+ visitor.visit(comp, gfx);
+ }
+ finally
+ {
+ if (translated)
+ gfx.translate (-bounds.x, -bounds.y);
+ if (clipped)
+ gfx.setClip (oldClip.x, oldClip.y, oldClip.width, oldClip.height);
+ }
+ }
+
+ void dispatchEventImpl(AWTEvent e)
+ {
+ // Give lightweight dispatcher a chance to handle it.
+ if (eventTypeEnabled (e.id)
+ && dispatcher != null
+ && dispatcher.handleEvent (e))
+ return;
+
+ if ((e.id <= ContainerEvent.CONTAINER_LAST
+ && e.id >= ContainerEvent.CONTAINER_FIRST)
+ && (containerListener != null
+ || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+ }
+
+ // This is used to implement Component.transferFocus.
+ Component findNextFocusComponent(Component child)
+ {
+ synchronized (getTreeLock ())
+ {
+ int start, end;
+ if (child != null)
+ {
+ for (start = 0; start < ncomponents; ++start)
+ {
+ if (component[start] == child)
+ break;
+ }
+ end = start;
+ // This special case lets us be sure to terminate.
+ if (end == 0)
+ end = ncomponents;
+ ++start;
+ }
+ else
+ {
+ start = 0;
+ end = ncomponents;
+ }
+
+ for (int j = start; j != end; ++j)
+ {
+ if (j >= ncomponents)
+ {
+ // The JCL says that we should wrap here. However, that
+ // seems wrong. To me it seems that focus order should be
+ // global within in given window. So instead if we reach
+ // the end we try to look in our parent, if we have one.
+ if (parent != null)
+ return parent.findNextFocusComponent(this);
+ j -= ncomponents;
+ }
+ if (component[j] instanceof Container)
+ {
+ Component c = component[j];
+ c = c.findNextFocusComponent(null);
+ if (c != null)
+ return c;
+ }
+ else if (component[j].isFocusTraversable())
+ return component[j];
+ }
+
+ return null;
+ }
+ }
+
+ private void addNotifyContainerChildren()
+ {
+ synchronized (getTreeLock ())
+ {
+ for (int i = ncomponents; --i >= 0; )
+ {
+ component[i].addNotify();
+ if (component[i].isLightweight ())
+ {
+
+ // If we're not lightweight, and we just got a lightweight
+ // child, we need a lightweight dispatcher to feed it events.
+ if (! this.isLightweight())
+ {
+ if (dispatcher == null)
+ dispatcher = new LightweightDispatcher (this);
+ }
+
+
+ enableEvents(component[i].eventMask);
+ if (peer != null && !isLightweight ())
+ enableEvents (AWTEvent.PAINT_EVENT_MASK);
+ }
+ }
+ }
+ }
+
+ /**
+ * Deserialize this Container:
+ * <ol>
+ * <li>Read from the stream the default serializable fields.</li>
+ * <li>Read a list of serializable ContainerListeners as optional
+ * data. If the list is null, no listeners will be registered.</li>
+ * <li>Read this Container's FocusTraversalPolicy as optional data.
+ * If this is null, then this Container will use a
+ * DefaultFocusTraversalPolicy.</li>
+ * </ol>
+ *
+ * @param s the stream to read from
+ * @throws ClassNotFoundException if deserialization fails
+ * @throws IOException if the stream fails
+ */
+ private void readObject (ObjectInputStream s)
+ throws ClassNotFoundException, IOException
+ {
+ s.defaultReadObject ();
+ String key = (String) s.readObject ();
+ while (key != null)
+ {
+ Object object = s.readObject ();
+ if ("containerL".equals (key))
+ addContainerListener((ContainerListener) object);
+ // FIXME: under what key is the focus traversal policy stored?
+ else if ("focusTraversalPolicy".equals (key))
+ setFocusTraversalPolicy ((FocusTraversalPolicy) object);
+
+ key = (String) s.readObject();
+ }
+ }
+
+ /**
+ * Serialize this Container:
+ * <ol>
+ * <li>Write to the stream the default serializable fields.</li>
+ * <li>Write the list of serializable ContainerListeners as optional
+ * data.</li>
+ * <li>Write this Container's FocusTraversalPolicy as optional data.</li>
+ * </ol>
+ *
+ * @param s the stream to write to
+ * @throws IOException if the stream fails
+ */
+ private void writeObject (ObjectOutputStream s) throws IOException
+ {
+ s.defaultWriteObject ();
+ AWTEventMulticaster.save (s, "containerL", containerListener);
+ if (focusTraversalPolicy instanceof Serializable)
+ s.writeObject (focusTraversalPolicy);
+ else
+ s.writeObject (null);
+ }
+
+ // Nested classes.
+
+ /* The following classes are used in concert with the
+ visitChildren() method to implement all the graphics operations
+ that requires traversal of the containment hierarchy. */
+
+ abstract static class GfxVisitor
+ {
+ public abstract void visit(Component c, Graphics gfx);
+ }
+
+ static class GfxPaintVisitor extends GfxVisitor
+ {
+ public static final GfxVisitor INSTANCE = new GfxPaintVisitor();
+
+ public void visit(Component c, Graphics gfx)
+ {
+ c.paint(gfx);
+ }
+ }
+
+ static class GfxPrintVisitor extends GfxVisitor
+ {
+ public static final GfxVisitor INSTANCE = new GfxPrintVisitor();
+
+ public void visit(Component c, Graphics gfx)
+ {
+ c.print(gfx);
+ }
+ }
+
+ static class GfxPaintAllVisitor extends GfxVisitor
+ {
+ public static final GfxVisitor INSTANCE = new GfxPaintAllVisitor();
+
+ public void visit(Component c, Graphics gfx)
+ {
+ c.paintAll(gfx);
+ }
+ }
+
+ static class GfxPrintAllVisitor extends GfxVisitor
+ {
+ public static final GfxVisitor INSTANCE = new GfxPrintAllVisitor();
+
+ public void visit(Component c, Graphics gfx)
+ {
+ c.printAll(gfx);
+ }
+ }
+
+ /**
+ * This class provides accessibility support for subclasses of container.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ *
+ * @since 1.3
+ */
+ protected class AccessibleAWTContainer extends AccessibleAWTComponent
+ {
+ /**
+ * Compatible with JDK 1.4+.
+ */
+ private static final long serialVersionUID = 5081320404842566097L;
+
+ /**
+ * The handler to fire PropertyChange when children are added or removed.
+ *
+ * @serial the handler for property changes
+ */
+ protected ContainerListener accessibleContainerHandler
+ = new AccessibleContainerHandler();
+
+ /**
+ * The default constructor.
+ */
+ protected AccessibleAWTContainer()
+ {
+ Container.this.addContainerListener(accessibleContainerHandler);
+ }
+
+ /**
+ * Return the number of accessible children of the containing accessible
+ * object (at most the total number of its children).
+ *
+ * @return the number of accessible children
+ */
+ public int getAccessibleChildrenCount()
+ {
+ synchronized (getTreeLock ())
+ {
+ int count = 0;
+ int i = component == null ? 0 : component.length;
+ while (--i >= 0)
+ if (component[i] instanceof Accessible)
+ count++;
+ return count;
+ }
+ }
+
+ /**
+ * Return the nth accessible child of the containing accessible object.
+ *
+ * @param i the child to grab, zero-based
+ * @return the accessible child, or null
+ */
+ public Accessible getAccessibleChild(int i)
+ {
+ synchronized (getTreeLock ())
+ {
+ if (component == null)
+ return null;
+ int index = -1;
+ while (i >= 0 && ++index < component.length)
+ if (component[index] instanceof Accessible)
+ i--;
+ if (i < 0)
+ return (Accessible) component[index];
+ return null;
+ }
+ }
+
+ /**
+ * Return the accessible child located at point (in the parent's
+ * coordinates), if one exists.
+ *
+ * @param p the point to look at
+ *
+ * @return an accessible object at that point, or null
+ *
+ * @throws NullPointerException if p is null
+ */
+ public Accessible getAccessibleAt(Point p)
+ {
+ Component c = getComponentAt(p.x, p.y);
+ return c != Container.this && c instanceof Accessible ? (Accessible) c
+ : null;
+ }
+
+ /**
+ * This class fires a <code>PropertyChange</code> listener, if registered,
+ * when children are added or removed from the enclosing accessible object.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ *
+ * @since 1.3
+ */
+ protected class AccessibleContainerHandler implements ContainerListener
+ {
+ /**
+ * Default constructor.
+ */
+ protected AccessibleContainerHandler()
+ {
+ }
+
+ /**
+ * Fired when a component is added; forwards to the PropertyChange
+ * listener.
+ *
+ * @param e the container event for adding
+ */
+ public void componentAdded(ContainerEvent e)
+ {
+ AccessibleAWTContainer.this.firePropertyChange
+ (ACCESSIBLE_CHILD_PROPERTY, null, e.getChild());
+ }
+
+ /**
+ * Fired when a component is removed; forwards to the PropertyChange
+ * listener.
+ *
+ * @param e the container event for removing
+ */
+ public void componentRemoved(ContainerEvent e)
+ {
+ AccessibleAWTContainer.this.firePropertyChange
+ (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null);
+ }
+ } // class AccessibleContainerHandler
+ } // class AccessibleAWTContainer
+} // class Container
+
+/**
+ * There is a helper class implied from stack traces called
+ * LightweightDispatcher, but since it is not part of the public API,
+ * rather than mimic it exactly we write something which does "roughly
+ * the same thing".
+ */
+
+class LightweightDispatcher implements Serializable
+{
+ private static final long serialVersionUID = 5184291520170872969L;
+ private Container nativeContainer;
+ private Cursor nativeCursor;
+ private long eventMask;
+
+ private transient Component mouseEventTarget;
+ private transient Component pressedComponent;
+ private transient Component lastComponentEntered;
+ private transient Component tempComponent;
+ private transient int pressCount;
+
+ LightweightDispatcher(Container c)
+ {
+ nativeContainer = c;
+ }
+
+ void acquireComponentForMouseEvent(MouseEvent me)
+ {
+ int x = me.getX ();
+ int y = me.getY ();
+
+ // Find the candidate which should receive this event.
+ Component parent = nativeContainer;
+ Component candidate = null;
+ Point p = me.getPoint();
+ while (candidate == null && parent != null)
+ {
+ candidate =
+ SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
+ if (candidate == null || (candidate.eventMask & me.getID()) == 0)
+ {
+ candidate = null;
+ p = SwingUtilities.convertPoint(parent, p.x, p.y, parent.parent);
+ parent = parent.parent;
+ }
+ }
+
+ // If the only candidate we found was the native container itself,
+ // don't dispatch any event at all. We only care about the lightweight
+ // children here.
+ if (candidate == nativeContainer)
+ candidate = null;
+
+ // If our candidate is new, inform the old target we're leaving.
+ if (lastComponentEntered != null
+ && lastComponentEntered.isShowing()
+ && lastComponentEntered != candidate)
+ {
+ // Old candidate could have been removed from
+ // the nativeContainer so we check first.
+ if (SwingUtilities.isDescendingFrom(lastComponentEntered, nativeContainer))
+ {
+ Point tp =
+ SwingUtilities.convertPoint(nativeContainer,
+ x, y, lastComponentEntered);
+ MouseEvent exited = new MouseEvent (lastComponentEntered,
+ MouseEvent.MOUSE_EXITED,
+ me.getWhen (),
+ me.getModifiersEx (),
+ tp.x, tp.y,
+ me.getClickCount (),
+ me.isPopupTrigger (),
+ me.getButton ());
+ tempComponent = lastComponentEntered;
+ lastComponentEntered = null;
+ tempComponent.dispatchEvent(exited);
+ }
+ lastComponentEntered = null;
+ }
+ // If we have a candidate, maybe enter it.
+ if (candidate != null)
+ {
+ mouseEventTarget = candidate;
+ if (candidate.isLightweight()
+ && candidate.isShowing()
+ && candidate != nativeContainer
+ && candidate != lastComponentEntered)
+ {
+ lastComponentEntered = mouseEventTarget;
+ Point cp = SwingUtilities.convertPoint(nativeContainer,
+ x, y, lastComponentEntered);
+ MouseEvent entered = new MouseEvent (lastComponentEntered,
+ MouseEvent.MOUSE_ENTERED,
+ me.getWhen (),
+ me.getModifiersEx (),
+ cp.x, cp.y,
+ me.getClickCount (),
+ me.isPopupTrigger (),
+ me.getButton ());
+ lastComponentEntered.dispatchEvent (entered);
+ }
+ }
+
+ if (me.getID() == MouseEvent.MOUSE_RELEASED
+ || me.getID() == MouseEvent.MOUSE_PRESSED && pressCount > 0
+ || me.getID() == MouseEvent.MOUSE_DRAGGED)
+ // If any of the following events occur while a button is held down,
+ // they should be dispatched to the same component to which the
+ // original MOUSE_PRESSED event was dispatched:
+ // - MOUSE_RELEASED
+ // - MOUSE_PRESSED: another button pressed while the first is held down
+ // - MOUSE_DRAGGED
+ if (SwingUtilities.isDescendingFrom(pressedComponent, nativeContainer))
+ mouseEventTarget = pressedComponent;
+ else if (me.getID() == MouseEvent.MOUSE_CLICKED)
+ {
+ // Don't dispatch CLICKED events whose target is not the same as the
+ // target for the original PRESSED event.
+ if (candidate != pressedComponent)
+ mouseEventTarget = null;
+ else if (pressCount == 0)
+ pressedComponent = null;
+ }
+ }
+
+ boolean handleEvent(AWTEvent e)
+ {
+ if (e instanceof MouseEvent)
+ {
+ MouseEvent me = (MouseEvent) e;
+
+ acquireComponentForMouseEvent(me);
+
+ // Avoid dispatching ENTERED and EXITED events twice.
+ if (mouseEventTarget != null
+ && mouseEventTarget.isShowing()
+ && e.getID() != MouseEvent.MOUSE_ENTERED
+ && e.getID() != MouseEvent.MOUSE_EXITED)
+ {
+ MouseEvent newEvt =
+ SwingUtilities.convertMouseEvent(nativeContainer, me,
+ mouseEventTarget);
+ mouseEventTarget.dispatchEvent(newEvt);
+
+ switch (e.getID())
+ {
+ case MouseEvent.MOUSE_PRESSED:
+ if (pressCount++ == 0)
+ pressedComponent = mouseEventTarget;
+ break;
+
+ case MouseEvent.MOUSE_RELEASED:
+ // Clear our memory of the original PRESSED event, only if
+ // we're not expecting a CLICKED event after this. If
+ // there is a CLICKED event after this, it will do clean up.
+ if (--pressCount == 0
+ && mouseEventTarget != pressedComponent)
+ pressedComponent = null;
+ break;
+ }
+ if (newEvt.isConsumed())
+ e.consume();
+ }
+ }
+
+ return e.isConsumed();
+ }
+
+} // class LightweightDispatcher
diff --git a/libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java b/libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java
new file mode 100644
index 0000000..152482c
--- /dev/null
+++ b/libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java
@@ -0,0 +1,413 @@
+/* ContainerOrderFocusTraversalPolicy.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * ContainerOrderFocusTraversalPolicy defines a focus traversal order
+ * based on the order in which Components were packed in a Container.
+ * This policy performs a pre-order traversal of the Component
+ * hierarchy starting from a given focus cycle root. Portions of the
+ * hierarchy that are not visible and displayable are skipped.
+ *
+ * By default, this policy transfers focus down-cycle implicitly.
+ * That is, if a forward traversal is requested on a focus cycle root
+ * and the focus cycle root has focusable children, the focus will
+ * automatically be transfered down to the lower focus cycle.
+ *
+ * The default implementation of accept accepts only Components that
+ * are visible, displayable, enabled and focusable. Derived classes
+ * can override these acceptance criteria by overriding accept.
+ *
+ * @author Michael Koch
+ * @author Thomas Fitzsimmons (fitzsim@redhat.com)
+ * @since 1.4
+ */
+public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
+ implements Serializable
+{
+ /**
+ * Compatible to JDK 1.4+
+ */
+ static final long serialVersionUID = 486933713763926351L;
+
+ /**
+ * True if implicit down cycling is enabled.
+ */
+ private boolean implicitDownCycleTraversal = true;
+
+ /**
+ * Creates the <code>ContainerOrderFocusTraversalPolicy</code> object.
+ */
+ public ContainerOrderFocusTraversalPolicy ()
+ {
+ // Nothing to do here
+ }
+
+ /**
+ * Returns the Component that should receive the focus after current.
+ * root must be a focus cycle root of current.
+ *
+ * @param root a focus cycle root of current
+ * @param current a (possibly indirect) child of root, or root itself
+ *
+ * @return the next Component in the focus traversal order for root,
+ * or null if no acceptable Component exists.
+ *
+ * @exception IllegalArgumentException If root is not a focus cycle
+ * root of current, or if either root or current is null.
+ */
+ public Component getComponentAfter (Container root, Component current)
+ {
+ if (root == null)
+ throw new IllegalArgumentException ("focus cycle root is null");
+ if (current == null)
+ throw new IllegalArgumentException ("current component is null");
+
+ if (!root.isFocusCycleRoot ())
+ throw new IllegalArgumentException ("root is not a focus cycle root");
+
+ Container ancestor = current.getFocusCycleRootAncestor ();
+ Container prevAncestor = ancestor;
+ while (ancestor != root)
+ {
+ ancestor = current.getFocusCycleRootAncestor ();
+ if (ancestor == prevAncestor)
+ {
+ // We've reached the top focus cycle root ancestor. Check
+ // if it is root.
+ if (ancestor != root)
+ throw new IllegalArgumentException ("the given container is not"
+ + " a focus cycle root of the"
+ + " current component");
+ else
+ break;
+ }
+ prevAncestor = ancestor;
+ }
+
+ // FIXME: is this the right thing to do here? It moves the context
+ // for traversal up one focus traversal cycle. We'll need a test
+ // for this.
+ if ((Component) root == current)
+ root = current.getFocusCycleRootAncestor ();
+
+ // Check if we've reached the top of the component hierarchy. If
+ // so then we want to loop around to the first component in the
+ // focus traversal cycle.
+ if (current instanceof Window)
+ return getFirstComponent ((Container) current);
+
+ Container parent = current.getParent ();
+
+ synchronized (parent.getTreeLock ())
+ {
+ Component[] components = parent.getComponents ();
+ int componentIndex = 0;
+ int numComponents = parent.getComponentCount ();
+
+ // Find component's index.
+ for (int i = 0; i < numComponents; i++)
+ {
+ if (components[i] == current)
+ componentIndex = i;
+ }
+
+ // Search forward for the next acceptable component.
+ for (int i = componentIndex + 1; i < numComponents; i++)
+ {
+ if (accept (components[i]))
+ return components[i];
+
+ if (components[i] instanceof Container)
+ {
+ Component result = getFirstComponent ((Container) components[i]);
+
+ if (result != null
+ && implicitDownCycleTraversal)
+ return result;
+ }
+ }
+
+ // No focusable components after current in its Container. So go
+ // to the next Component after current's Container (parent).
+ Component result = getComponentAfter (root, parent);
+
+ return result;
+ }
+ }
+
+ /**
+ * Returns the Component that should receive the focus before
+ * <code>current</code>. <code>root</code> must be a focus cycle
+ * root of current.
+ *
+ * @param root a focus cycle root of current
+ * @param current a (possibly indirect) child of root, or root itself
+ *
+ * @return the previous Component in the focus traversal order for
+ * root, or null if no acceptable Component exists.
+ *
+ * @exception IllegalArgumentException If root is not a focus cycle
+ * root of current, or if either root or current is null.
+ */
+ public Component getComponentBefore (Container root, Component current)
+ {
+ if (root == null)
+ throw new IllegalArgumentException ("focus cycle root is null");
+ if (current == null)
+ throw new IllegalArgumentException ("current component is null");
+
+ if (!root.isFocusCycleRoot ())
+ throw new IllegalArgumentException ("root is not a focus cycle root");
+
+ Container ancestor = current.getFocusCycleRootAncestor ();
+ Container prevAncestor = ancestor;
+ while (ancestor != root)
+ {
+ ancestor = current.getFocusCycleRootAncestor ();
+ if (ancestor == prevAncestor)
+ {
+ // We've reached the top focus cycle root ancestor. Check
+ // if it is root.
+ if (ancestor != root)
+ throw new IllegalArgumentException ("the given container is not"
+ + " a focus cycle root of the"
+ + " current component");
+ else
+ break;
+ }
+ prevAncestor = ancestor;
+ }
+
+ // FIXME: is this the right thing to do here? It moves the context
+ // for traversal up one focus traversal cycle. We'll need a test
+ // for this.
+ if ((Component) root == current)
+ root = current.getFocusCycleRootAncestor ();
+
+ // Check if we've reached the top of the component hierarchy. If
+ // so then we want to loop around to the last component in the
+ // focus traversal cycle.
+ if (current instanceof Window)
+ return getLastComponent ((Container) current);
+
+ Container parent = current.getParent ();
+
+ synchronized (parent.getTreeLock ())
+ {
+ Component[] components = parent.getComponents ();
+ int componentIndex = 0;
+ int numComponents = parent.getComponentCount ();
+
+ // Find component's index.
+ for (int i = 0; i < numComponents; i++)
+ {
+ if (components[i] == current)
+ componentIndex = i;
+ }
+
+ // Search backward for the next acceptable component.
+ for (int i = componentIndex - 1; i >= 0; i--)
+ {
+ if (accept (components[i]))
+ return components[i];
+
+ if (components[i] instanceof Container)
+ {
+ Component result = getLastComponent ((Container) components[i]);
+
+ if (result != null)
+ return result;
+ }
+ }
+
+ // No focusable components before current in its Container. So go
+ // to the previous Component before current's Container (parent).
+ Component result = getComponentBefore (root, parent);
+
+ return result;
+ }
+ }
+
+ /**
+ * Returns the first Component of root that should receive the focus.
+ *
+ * @param root a focus cycle root
+ *
+ * @return the first Component in the focus traversal order for
+ * root, or null if no acceptable Component exists.
+ *
+ * @exception IllegalArgumentException If root is null.
+ */
+ public Component getFirstComponent(Container root)
+ {
+ if (root == null)
+ throw new IllegalArgumentException ();
+
+ if (!root.isVisible ()
+ || !root.isDisplayable ())
+ return null;
+
+ if (accept (root))
+ return root;
+
+ Component[] componentArray = root.getComponents ();
+
+ for (int i = 0; i < componentArray.length; i++)
+ {
+ Component component = componentArray [i];
+
+ if (accept (component))
+ return component;
+
+ if (component instanceof Container)
+ {
+ Component result = getFirstComponent ((Container) component);
+
+ if (result != null)
+ return result;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the last Component of root that should receive the focus.
+ *
+ * @param root a focus cycle root
+ *
+ * @return the last Component in the focus traversal order for
+ * root, or null if no acceptable Component exists.
+ *
+ * @exception IllegalArgumentException If root is null.
+ */
+ public Component getLastComponent (Container root)
+ {
+ if (root == null)
+ throw new IllegalArgumentException ();
+
+ if (!root.isVisible ()
+ || !root.isDisplayable ())
+ return null;
+
+ if (accept (root))
+ return root;
+
+ Component[] componentArray = root.getComponents ();
+
+ for (int i = componentArray.length - 1; i >= 0; i--)
+ {
+ Component component = componentArray [i];
+
+ if (accept (component))
+ return component;
+
+ if (component instanceof Container)
+ {
+ Component result = getLastComponent ((Container) component);
+
+ if (result != null)
+ return result;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the default Component of root that should receive the focus.
+ *
+ * @param root a focus cycle root
+ *
+ * @return the default Component in the focus traversal order for
+ * root, or null if no acceptable Component exists.
+ *
+ * @exception IllegalArgumentException If root is null.
+ */
+ public Component getDefaultComponent (Container root)
+ {
+ return getFirstComponent (root);
+ }
+
+ /**
+ * Set whether or not implicit down cycling is enabled. If it is,
+ * then initiating a forward focus traversal operation onto a focus
+ * cycle root, the focus will be implicitly transferred into the
+ * root container's focus cycle.
+ *
+ * @param value the setting for implicit down cycling
+ */
+ public void setImplicitDownCycleTraversal (boolean value)
+ {
+ implicitDownCycleTraversal = value;
+ }
+
+ /**
+ * Check whether or not implicit down cycling is enabled. If it is,
+ * then initiating a forward focus traversal operation onto a focus
+ * cycle root, the focus will be implicitly transferred into the
+ * root container's focus cycle.
+ *
+ * @return true if the focus will be transferred down-cycle
+ * implicitly
+ */
+ public boolean getImplicitDownCycleTraversal ()
+ {
+ return implicitDownCycleTraversal;
+ }
+
+ /**
+ * Check whether the given Component is an acceptable target for the
+ * keyboard input focus.
+ *
+ * @param current the Component to check
+ *
+ * @return true if current is acceptable, false otherwise
+ */
+ protected boolean accept (Component current)
+ {
+ return (current.visible
+ && current.isDisplayable ()
+ && current.enabled
+ && current.focusable);
+ }
+}
diff --git a/libjava/classpath/java/awt/Cursor.java b/libjava/classpath/java/awt/Cursor.java
new file mode 100644
index 0000000..48a63f0
--- /dev/null
+++ b/libjava/classpath/java/awt/Cursor.java
@@ -0,0 +1,224 @@
+/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This class represents various predefined cursor types.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class Cursor implements java.io.Serializable
+{
+ static final long serialVersionUID = 8028237497568985504L;
+
+ /**
+ * Constant for the system default cursor type
+ */
+ public static final int DEFAULT_CURSOR = 0;
+
+ /**
+ * Constant for a cross-hair cursor.
+ */
+ public static final int CROSSHAIR_CURSOR = 1;
+
+ /**
+ * Constant for a cursor over a text field.
+ */
+ public static final int TEXT_CURSOR = 2;
+
+ /**
+ * Constant for a cursor to display while waiting for an action to complete.
+ */
+ public static final int WAIT_CURSOR = 3;
+
+ /**
+ * Cursor used over SW corner of window decorations.
+ */
+ public static final int SW_RESIZE_CURSOR = 4;
+
+ /**
+ * Cursor used over SE corner of window decorations.
+ */
+ public static final int SE_RESIZE_CURSOR = 5;
+
+ /**
+ * Cursor used over NW corner of window decorations.
+ */
+ public static final int NW_RESIZE_CURSOR = 6;
+
+ /**
+ * Cursor used over NE corner of window decorations.
+ */
+ public static final int NE_RESIZE_CURSOR = 7;
+
+ /**
+ * Cursor used over N edge of window decorations.
+ */
+ public static final int N_RESIZE_CURSOR = 8;
+
+ /**
+ * Cursor used over S edge of window decorations.
+ */
+ public static final int S_RESIZE_CURSOR = 9;
+
+ /**
+ * Cursor used over W edge of window decorations.
+ */
+ public static final int W_RESIZE_CURSOR = 10;
+
+ /**
+ * Cursor used over E edge of window decorations.
+ */
+ public static final int E_RESIZE_CURSOR = 11;
+
+ /**
+ * Constant for a hand cursor.
+ */
+ public static final int HAND_CURSOR = 12;
+
+ /**
+ * Constant for a cursor used during window move operations.
+ */
+ public static final int MOVE_CURSOR = 13;
+
+ public static final int CUSTOM_CURSOR = 0xFFFFFFFF;
+
+ private static final int PREDEFINED_COUNT = 14;
+
+ protected static Cursor[] predefined = new Cursor[PREDEFINED_COUNT];
+ protected String name;
+
+ /**
+ * @serial The numeric id of this cursor.
+ */
+ int type;
+
+ /**
+ * Initializes a new instance of <code>Cursor</code> with the specified
+ * type.
+ *
+ * @param type The cursor type.
+ *
+ * @exception IllegalArgumentException If the specified cursor type is invalid
+ */
+ public Cursor(int type)
+ {
+ if (type < 0 || type >= PREDEFINED_COUNT)
+ throw new IllegalArgumentException ("invalid cursor " + type);
+
+ this.type = type;
+ // FIXME: lookup and set name?
+ }
+
+ /** This constructor is used internally only.
+ * Application code should call Toolkit.createCustomCursor().
+ */
+ protected Cursor(String name)
+ {
+ this.name = name;
+ this.type = CUSTOM_CURSOR;
+ }
+
+ /**
+ * Returns an instance of <code>Cursor</code> for one of the specified
+ * predetermined types.
+ *
+ * @param type The type contant from this class.
+ *
+ * @return The requested predefined cursor.
+ *
+ * @exception IllegalArgumentException If the constant is not one of the
+ * predefined cursor type constants from this class.
+ */
+ public static Cursor getPredefinedCursor(int type)
+ {
+ if (type < 0 || type >= PREDEFINED_COUNT)
+ throw new IllegalArgumentException ("invalid cursor " + type);
+ if (predefined[type] == null)
+ predefined[type] = new Cursor(type);
+ return predefined[type];
+ }
+
+ /**
+ * Retrieves the system specific custom Cursor named Cursor names are,
+ * for example: "Invalid.16x16".
+ *
+ * @exception AWTException
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+ public static Cursor getSystemCustomCursor(String name)
+ throws AWTException
+ {
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+
+ // FIXME
+ return null;
+ }
+
+ /**
+ * Returns an instance of the system default cursor type.
+ *
+ * @return The system default cursor.
+ */
+ public static Cursor getDefaultCursor()
+ {
+ return getPredefinedCursor(DEFAULT_CURSOR);
+ }
+
+ /**
+ * Returns the numeric type identifier for this cursor.
+ *
+ * @return The cursor id.
+ */
+ public int getType()
+ {
+ return type;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String toString()
+ {
+ return (this.getClass() + "[" + getName() + "]");
+ }
+}
diff --git a/libjava/classpath/java/awt/DefaultFocusTraversalPolicy.java b/libjava/classpath/java/awt/DefaultFocusTraversalPolicy.java
new file mode 100644
index 0000000..46b56d3
--- /dev/null
+++ b/libjava/classpath/java/awt/DefaultFocusTraversalPolicy.java
@@ -0,0 +1,109 @@
+/* DefaultFocusTraversalPolicy.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * DefaultFocusTraversalPolicy is the default focus traversal policy
+ * used by Containers.
+ *
+ * This policy sharpens ContainerOrderFocusTraversalPolicy's
+ * acceptance criteria, to reject those Components that have
+ * unfocusable peers. Despite this extra strictness, this policy will
+ * always accept a Component that has explicitly been set focusable by
+ * any means.
+ *
+ * This AWT implementation assumes that the peers of the following
+ * Components are not focusable: Canvas, Panel, Label, ScrollPane,
+ * Scrollbar, Window, and any lightweight Component.
+ *
+ * A Component's focusability is independent of the focusability of
+ * its peer.
+ *
+ * @author Thomas Fitzsimmons (fitzsim@redhat.com)
+ * @since 1.4
+ */
+public class DefaultFocusTraversalPolicy
+ extends ContainerOrderFocusTraversalPolicy
+{
+ /**
+ * Construct a default focus traversal policy.
+ */
+ public DefaultFocusTraversalPolicy ()
+ {
+ }
+
+ /**
+ * Check whether a given Component would be acceptable as a focus
+ * owner. The Component must be displayable, visible and enabled to
+ * be acceptable. If the Component's focus traversability has been
+ * overridden, by overriding Component.isFocusTraversable or
+ * Component.isFocusable, or by calling Component.setFocusable, then
+ * the Component will be accepted if it is focusable. If the
+ * Component uses the default focus traversable behaviour, then
+ * <code>comp</code> will always be rejected if it is a Canvas,
+ * Panel, Label, ScrollPane, Scrollbar, Window or lightweight
+ * Component.
+ *
+ * @param comp the Component to check
+ *
+ * @return true if the Component is an acceptable target for
+ * keyboard input focus, false otherwise
+ */
+ protected boolean accept (Component comp)
+ {
+ if (comp.visible
+ && comp.isDisplayable ()
+ && comp.enabled)
+ {
+ if (comp.isFocusTraversableOverridden != 0
+ && (comp.isFocusTraversable () || comp.isFocusable()))
+ return true;
+
+ if (!(comp instanceof Canvas
+ || comp instanceof Panel
+ || comp instanceof Label
+ || comp instanceof ScrollPane
+ || comp instanceof Scrollbar
+ || comp instanceof Window
+ || comp.isLightweight ()))
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/libjava/classpath/java/awt/DefaultKeyboardFocusManager.java b/libjava/classpath/java/awt/DefaultKeyboardFocusManager.java
new file mode 100644
index 0000000..f53cc5e
--- /dev/null
+++ b/libjava/classpath/java/awt/DefaultKeyboardFocusManager.java
@@ -0,0 +1,536 @@
+/* DefaultKeyboardFocusManager.java --
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowEvent;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+// FIXME: finish documentation
+public class DefaultKeyboardFocusManager extends KeyboardFocusManager
+{
+ /**
+ * This class models a request to delay the dispatch of events that
+ * arrive after a certain time, until a certain component becomes
+ * the focus owner.
+ */
+ private class EventDelayRequest implements Comparable
+ {
+ /** A {@link java.util.List} of {@link java.awt.event.KeyEvent}s
+ that are being delayed, pending this request's {@link
+ Component} receiving the keyboard focus. */
+ private LinkedList enqueuedKeyEvents = new LinkedList ();
+
+ /** An event timestamp. All events that arrive after this time
+ should be queued in the {@link #enqueuedKeyEvents} {@link
+ java.util.List}. */
+ public long timestamp;
+ /** When this {@link Component} becomes focused, all events
+ between this EventDelayRequest and the next one in will be
+ dispatched from {@link #enqueuedKeyEvents}. */
+ public Component focusedComp;
+
+ /**
+ * Construct a new EventDelayRequest.
+ *
+ * @param timestamp events that arrive after this time will be
+ * delayed
+ * @param focusedComp the Component that needs to receive focus
+ * before events are dispatched
+ */
+ public EventDelayRequest (long timestamp, Component focusedComp)
+ {
+ this.timestamp = timestamp;
+ this.focusedComp = focusedComp;
+ }
+
+ public int compareTo (Object o)
+ {
+ if (!(o instanceof EventDelayRequest))
+ throw new ClassCastException ();
+
+ EventDelayRequest request = (EventDelayRequest) o;
+
+ if (request.timestamp < timestamp)
+ return -1;
+ else if (request.timestamp == timestamp)
+ return 0;
+ else
+ return 1;
+ }
+
+ public boolean equals (Object o)
+ {
+ if (!(o instanceof EventDelayRequest) || o == null)
+ return false;
+
+ EventDelayRequest request = (EventDelayRequest) o;
+
+ return (request.timestamp == timestamp
+ && request.focusedComp == focusedComp);
+ }
+
+ public void enqueueEvent (KeyEvent e)
+ {
+ KeyEvent last = (KeyEvent) enqueuedKeyEvents.getLast ();
+ if (last != null && e.getWhen () < last.getWhen ())
+ throw new RuntimeException ("KeyEvents enqueued out-of-order");
+
+ if (e.getWhen () <= timestamp)
+ throw new RuntimeException ("KeyEvents enqueued before starting timestamp");
+
+ enqueuedKeyEvents.add (e);
+ }
+
+ public void dispatchEvents ()
+ {
+ int size = enqueuedKeyEvents.size ();
+ for (int i = 0; i < size; i++)
+ {
+ KeyEvent e = (KeyEvent) enqueuedKeyEvents.remove (0);
+ dispatchKeyEvent (e);
+ }
+ }
+
+ public void discardEvents ()
+ {
+ enqueuedKeyEvents.clear ();
+ }
+ }
+
+ /**
+ * This flag indicates for which focus traversal key release event we
+ * possibly wait, before letting any more KEY_TYPED events through.
+ */
+ private AWTKeyStroke waitForKeyStroke = null;
+
+ /** The {@link java.util.SortedSet} of current {@link
+ #EventDelayRequest}s. */
+ private SortedSet delayRequests = new TreeSet ();
+
+ public DefaultKeyboardFocusManager ()
+ {
+ }
+
+ public boolean dispatchEvent (AWTEvent e)
+ {
+ if (e instanceof WindowEvent)
+ {
+ Window target = (Window) e.getSource ();
+
+ if (e.id == WindowEvent.WINDOW_ACTIVATED)
+ setGlobalActiveWindow (target);
+ else if (e.id == WindowEvent.WINDOW_GAINED_FOCUS)
+ setGlobalFocusedWindow (target);
+ else if (e.id != WindowEvent.WINDOW_LOST_FOCUS
+ && e.id != WindowEvent.WINDOW_DEACTIVATED)
+ return false;
+
+ redispatchEvent(target, e);
+ return true;
+ }
+ else if (e instanceof FocusEvent)
+ {
+ Component target = (Component) e.getSource ();
+
+ if (e.id == FocusEvent.FOCUS_GAINED)
+ {
+ if (! (target instanceof Window))
+ {
+ if (((FocusEvent) e).isTemporary ())
+ setGlobalFocusOwner (target);
+ else
+ setGlobalPermanentFocusOwner (target);
+ }
+
+ // Keep track of this window's focus owner.
+
+ // Find the target Component's top-level ancestor. target
+ // may be a window.
+ Container parent = target.getParent ();
+
+ while (parent != null
+ && !(parent instanceof Window))
+ parent = parent.getParent ();
+
+ // If the parent is null and target is not a window, then target is an
+ // unanchored component and so we don't want to set the focus owner.
+ if (! (parent == null && ! (target instanceof Window)))
+ {
+ Window toplevel = parent == null ?
+ (Window) target : (Window) parent;
+
+ Component focusOwner = getFocusOwner ();
+ if (focusOwner != null
+ && ! (focusOwner instanceof Window))
+ toplevel.setFocusOwner (focusOwner);
+ }
+ }
+ else if (e.id == FocusEvent.FOCUS_LOST)
+ {
+ if (((FocusEvent) e).isTemporary ())
+ setGlobalFocusOwner (null);
+ else
+ setGlobalPermanentFocusOwner (null);
+ }
+
+ redispatchEvent(target, e);
+
+ return true;
+ }
+ else if (e instanceof KeyEvent)
+ {
+ // Loop through all registered KeyEventDispatchers, giving
+ // each a chance to handle this event.
+ Iterator i = getKeyEventDispatchers().iterator();
+
+ while (i.hasNext ())
+ {
+ KeyEventDispatcher dispatcher = (KeyEventDispatcher) i.next ();
+ if (dispatcher.dispatchKeyEvent ((KeyEvent) e))
+ return true;
+ }
+
+ // processKeyEvent checks if this event represents a focus
+ // traversal key stroke.
+ Component focusOwner = getGlobalPermanentFocusOwner ();
+
+ if (focusOwner != null)
+ processKeyEvent (focusOwner, (KeyEvent) e);
+
+ if (e.isConsumed ())
+ return true;
+
+ if (enqueueKeyEvent ((KeyEvent) e))
+ // This event was enqueued for dispatch at a later time.
+ return true;
+ else
+ // This event wasn't handled by any of the registered
+ // KeyEventDispatchers, and wasn't enqueued for dispatch
+ // later, so send it to the default dispatcher.
+ return dispatchKeyEvent ((KeyEvent) e);
+ }
+
+ return false;
+ }
+
+ private boolean enqueueKeyEvent (KeyEvent e)
+ {
+ Iterator i = delayRequests.iterator ();
+ boolean oneEnqueued = false;
+ while (i.hasNext ())
+ {
+ EventDelayRequest request = (EventDelayRequest) i.next ();
+ if (e.getWhen () > request.timestamp)
+ {
+ request.enqueueEvent (e);
+ oneEnqueued = true;
+ }
+ }
+ return oneEnqueued;
+ }
+
+ public boolean dispatchKeyEvent (KeyEvent e)
+ {
+ Component focusOwner = getGlobalPermanentFocusOwner ();
+
+ if (focusOwner != null)
+ redispatchEvent(focusOwner, e);
+
+ // Loop through all registered KeyEventPostProcessors, giving
+ // each a chance to process this event.
+ Iterator i = getKeyEventPostProcessors().iterator();
+
+ while (i.hasNext ())
+ {
+ KeyEventPostProcessor processor = (KeyEventPostProcessor) i.next ();
+ if (processor.postProcessKeyEvent ((KeyEvent) e))
+ return true;
+ }
+
+ // The event hasn't been consumed yet. Check if it is an
+ // MenuShortcut.
+ if (postProcessKeyEvent (e))
+ return true;
+
+ // Always return true.
+ return true;
+ }
+
+ public boolean postProcessKeyEvent (KeyEvent e)
+ {
+ // Check if this event represents a menu shortcut.
+
+ // MenuShortcuts are activated by Ctrl- KeyEvents, only on KEY_PRESSED.
+ int modifiers = e.getModifiersEx ();
+ if (e.getID() == KeyEvent.KEY_PRESSED
+ && (modifiers & KeyEvent.CTRL_DOWN_MASK) != 0)
+ {
+ Window focusedWindow = getGlobalFocusedWindow ();
+ if (focusedWindow instanceof Frame)
+ {
+ MenuBar menubar = ((Frame) focusedWindow).getMenuBar ();
+
+ if (menubar != null)
+ {
+ // If there's a menubar, loop through all menu items,
+ // checking whether each one has a shortcut, and if
+ // so, whether this key event should activate it.
+ int numMenus = menubar.getMenuCount ();
+
+ for (int i = 0; i < numMenus; i++)
+ {
+ Menu menu = menubar.getMenu (i);
+ int numItems = menu.getItemCount ();
+
+ for (int j = 0; j < numItems; j++)
+ {
+ MenuItem item = menu.getItem (j);
+ MenuShortcut shortcut = item.getShortcut ();
+
+ if (item.isEnabled() && shortcut != null)
+ {
+ // Dispatch a new ActionEvent if:
+ //
+ // a) this is a Shift- KeyEvent, and the
+ // shortcut requires the Shift modifier
+ //
+ // or, b) this is not a Shift- KeyEvent, and the
+ // shortcut does not require the Shift
+ // modifier.
+ if (shortcut.getKey () == e.getKeyCode ()
+ && ((shortcut.usesShiftModifier ()
+ && (modifiers & KeyEvent.SHIFT_DOWN_MASK) != 0)
+ || (! shortcut.usesShiftModifier ()
+ && (modifiers & KeyEvent.SHIFT_DOWN_MASK) == 0)))
+ {
+ item.dispatchEvent (new ActionEvent (item,
+ ActionEvent.ACTION_PERFORMED,
+ item.getActionCommand (),
+ modifiers));
+ // The event was dispatched.
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public void processKeyEvent (Component comp, KeyEvent e)
+ {
+ AWTKeyStroke eventKeystroke = AWTKeyStroke.getAWTKeyStrokeForEvent (e);
+ // For every focus traversal keystroke, we need to also consume
+ // the other two key event types for the same key (e.g. if
+ // KEY_PRESSED TAB is a focus traversal keystroke, we also need to
+ // consume KEY_RELEASED and KEY_TYPED TAB key events).
+ // consuming KEY_RELEASED is easy, because their keyCodes matches
+ // the KEY_PRESSED event. Consuming the intermediate KEY_TYPED is
+ // very difficult because their is no clean way that we can know
+ // which KEY_TYPED belongs to a focusTraversalKey and which not.
+ // To address this problem we swallow every KEY_TYPE between the
+ // KEY_PRESSED event that matches a focusTraversalKey and the
+ // corresponding KEY_RELEASED.
+ AWTKeyStroke oppositeKeystroke = AWTKeyStroke.getAWTKeyStroke (e.getKeyCode (),
+ e.getModifiersEx (),
+ !(e.id == KeyEvent.KEY_RELEASED));
+
+ // Here we check if we are currently waiting for a KEY_RELEASED and
+ // swallow all KeyEvents that are to be delivered in between. This
+ // should only be the KEY_TYPED events that correspond to the
+ // focusTraversalKey's KEY_PRESSED event
+ if (waitForKeyStroke != null)
+ {
+ if (eventKeystroke.equals(waitForKeyStroke))
+ // release this lock
+ waitForKeyStroke = null;
+
+ // as long as we are waiting for the KEY_RELEASED, we swallow every
+ // KeyEvent, including the KEY_RELEASED
+ e.consume();
+ return;
+ }
+
+ Set forwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ Set backwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ Set upKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ Set downKeystrokes = null;
+ if (comp instanceof Container)
+ downKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+
+ if (forwardKeystrokes.contains (eventKeystroke))
+ {
+ waitForKeyStroke = oppositeKeystroke;
+ focusNextComponent (comp);
+ e.consume ();
+ }
+ else if (backwardKeystrokes.contains (eventKeystroke))
+ {
+ waitForKeyStroke = oppositeKeystroke;
+ focusPreviousComponent (comp);
+ e.consume ();
+ }
+ else if (upKeystrokes.contains (eventKeystroke))
+ {
+ waitForKeyStroke = oppositeKeystroke;
+ upFocusCycle (comp);
+ e.consume ();
+ }
+ else if (comp instanceof Container
+ && downKeystrokes.contains (eventKeystroke))
+ {
+ waitForKeyStroke = oppositeKeystroke;
+ downFocusCycle ((Container) comp);
+ e.consume ();
+ }
+ }
+
+ protected void enqueueKeyEvents (long after, Component untilFocused)
+ {
+ delayRequests.add (new EventDelayRequest (after, untilFocused));
+ }
+
+ protected void dequeueKeyEvents (long after, Component untilFocused)
+ {
+ // FIXME: need synchronization on delayRequests and enqueuedKeyEvents.
+
+ // Remove the KeyEvent with the oldest timestamp, which should be
+ // the first element in the SortedSet.
+ if (after < 0)
+ {
+ int size = delayRequests.size ();
+ if (size > 0)
+ delayRequests.remove (delayRequests.first ());
+ }
+ else
+ {
+ EventDelayRequest template = new EventDelayRequest (after, untilFocused);
+ if (delayRequests.contains (template))
+ {
+ EventDelayRequest actual = (EventDelayRequest) delayRequests.tailSet (template).first ();
+ delayRequests.remove (actual);
+ actual.dispatchEvents ();
+ }
+ }
+ }
+
+ protected void discardKeyEvents (Component comp)
+ {
+ // FIXME: need synchronization on delayRequests and enqueuedKeyEvents.
+
+ Iterator i = delayRequests.iterator ();
+
+ while (i.hasNext ())
+ {
+ EventDelayRequest request = (EventDelayRequest) i.next ();
+
+ if (request.focusedComp == comp
+ || (comp instanceof Container
+ && ((Container) comp).isAncestorOf (request.focusedComp)))
+ request.discardEvents ();
+ }
+ }
+
+ public void focusPreviousComponent (Component comp)
+ {
+ Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
+ Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
+ FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
+
+ Component previous = policy.getComponentBefore (focusCycleRoot, focusComp);
+ if (previous != null)
+ previous.requestFocusInWindow ();
+ }
+
+ public void focusNextComponent (Component comp)
+ {
+ Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
+ Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
+ FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
+
+ Component next = policy.getComponentAfter (focusCycleRoot, focusComp);
+ if (next != null)
+ next.requestFocusInWindow ();
+ }
+
+ public void upFocusCycle (Component comp)
+ {
+ Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
+ Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
+
+ if (focusCycleRoot instanceof Window)
+ {
+ FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
+ Component defaultComponent = policy.getDefaultComponent (focusCycleRoot);
+ if (defaultComponent != null)
+ defaultComponent.requestFocusInWindow ();
+ }
+ else
+ {
+ Container parentFocusCycleRoot = focusCycleRoot.getFocusCycleRootAncestor ();
+
+ focusCycleRoot.requestFocusInWindow ();
+ setGlobalCurrentFocusCycleRoot (parentFocusCycleRoot);
+ }
+ }
+
+ public void downFocusCycle (Container cont)
+ {
+ if (cont == null)
+ return;
+
+ if (cont.isFocusCycleRoot (cont))
+ {
+ FocusTraversalPolicy policy = cont.getFocusTraversalPolicy ();
+ Component defaultComponent = policy.getDefaultComponent (cont);
+ if (defaultComponent != null)
+ defaultComponent.requestFocusInWindow ();
+ setGlobalCurrentFocusCycleRoot (cont);
+ }
+ }
+} // class DefaultKeyboardFocusManager
diff --git a/libjava/classpath/java/awt/Dialog.java b/libjava/classpath/java/awt/Dialog.java
new file mode 100644
index 0000000..d3eb975
--- /dev/null
+++ b/libjava/classpath/java/awt/Dialog.java
@@ -0,0 +1,553 @@
+/* Dialog.java -- An AWT dialog box
+ Copyright (C) 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.peer.DialogPeer;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+
+/**
+ * A dialog box widget class.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@redhat.com)
+ */
+public class Dialog extends Window
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization constant
+private static final long serialVersionUID = 5920926903803293709L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial Indicates whether or not this dialog box is modal.
+ */
+private boolean modal;
+
+/**
+ * @serial Indicates whether or not this dialog box is resizable.
+ */
+private boolean resizable = true;
+
+/**
+ * @serial The title string for this dialog box, which can be
+ * <code>null</code>.
+ */
+private String title;
+
+/**
+ * This field indicates whether the dialog is undecorated or not.
+ */
+private boolean undecorated = false;
+
+/**
+ * Indicates that we are blocked for modality in show
+ */
+private boolean blocked = false;
+
+/**
+ * Secondary EventQueue to handle AWT events while
+ * we are blocked for modality in show
+ */
+private EventQueue eq2 = null;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified
+ * parent, that is resizable and not modal, and which has no title.
+ *
+ * @param parent The parent frame of this dialog box.
+ *
+ * @exception IllegalArgumentException If the owner's GraphicsConfiguration
+ * is not from a screen device, or if owner is null. This exception is always
+ * thrown when GraphicsEnvironment.isHeadless() returns true.
+ */
+public
+Dialog(Frame parent)
+{
+ this(parent, "", false);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified
+ * parent and modality, that is resizable and which has no title.
+ *
+ * @param parent The parent frame of this dialog box.
+ * @param modal <code>true</code> if this dialog box is modal,
+ * <code>false</code> otherwise.
+ *
+ * @exception IllegalArgumentException If the owner's GraphicsConfiguration
+ * is not from a screen device, or if owner is null. This exception is always
+ * thrown when GraphicsEnvironment.isHeadless() returns true.
+ */
+public
+Dialog(Frame parent, boolean modal)
+{
+ this(parent, "", modal);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified
+ * parent, that is resizable and not modal, and which has the specified
+ * title.
+ *
+ * @param parent The parent frame of this dialog box.
+ * @param title The title string for this dialog box.
+ *
+ * @exception IllegalArgumentException If the owner's GraphicsConfiguration
+ * is not from a screen device, or if owner is null. This exception is always
+ * thrown when GraphicsEnvironment.isHeadless() returns true.
+ */
+public
+Dialog(Frame parent, String title)
+{
+ this(parent, title, false);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified,
+ * parent, title, and modality, that is resizable.
+ *
+ * @param parent The parent frame of this dialog box.
+ * @param title The title string for this dialog box.
+ * @param modal <code>true</code> if this dialog box is modal,
+ * <code>false</code> otherwise.
+ *
+ * @exception IllegalArgumentException If owner is null or
+ * GraphicsEnvironment.isHeadless() returns true.
+ */
+public
+Dialog(Frame parent, String title, boolean modal)
+{
+ this (parent, title, modal, parent.getGraphicsConfiguration ());
+}
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified,
+ * parent, title, modality and <code>GraphicsConfiguration</code>,
+ * that is resizable.
+ *
+ * @param parent The parent frame of this dialog box.
+ * @param title The title string for this dialog box.
+ * @param modal <code>true</code> if this dialog box is modal,
+ * <code>false</code> otherwise.
+ * @param gc The <code>GraphicsConfiguration</code> object to use.
+ *
+ * @exception IllegalArgumentException If owner is null, the
+ * GraphicsConfiguration is not a screen device or
+ * GraphicsEnvironment.isHeadless() returns true.
+ *
+ * @since 1.4
+ */
+public
+Dialog (Frame parent, String title, boolean modal, GraphicsConfiguration gc)
+{
+ super (parent, gc);
+
+ // A null title is equivalent to an empty title
+ this.title = (title != null) ? title : "";
+ this.modal = modal;
+ visible = false;
+
+ setLayout(new BorderLayout());
+}
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified,
+ * parent, that is resizable.
+ *
+ * @exception IllegalArgumentException If parent is null. This exception is
+ * always thrown when GraphicsEnvironment.isHeadless() returns true.
+ *
+ * @since 1.2
+ */
+public
+Dialog (Dialog owner)
+{
+ this (owner, "", false, owner.getGraphicsConfiguration ());
+}
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified,
+ * parent and title, that is resizable.
+ *
+ * @exception IllegalArgumentException If parent is null. This exception is
+ * always thrown when GraphicsEnvironment.isHeadless() returns true.
+ *
+ * @since 1.2
+ */
+public
+Dialog (Dialog owner, String title)
+{
+ this (owner, title, false, owner.getGraphicsConfiguration ());
+}
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified,
+ * parent, title and modality, that is resizable.
+ *
+ * @exception IllegalArgumentException If parent is null. This exception is
+ * always thrown when GraphicsEnvironment.isHeadless() returns true.
+ *
+ * @since 1.2
+ */
+public
+Dialog (Dialog owner, String title, boolean modal)
+{
+ this (owner, title, modal, owner.getGraphicsConfiguration ());
+}
+
+/**
+ * Initializes a new instance of <code>Dialog</code> with the specified,
+ * parent, title, modality and <code>GraphicsConfiguration</code>,
+ * that is resizable.
+ *
+ * @exception IllegalArgumentException If parent is null, the
+ * GraphicsConfiguration is not a screen device or
+ * GraphicsEnvironment.isHeadless() returns true.
+ *
+ * @since 1.4
+ */
+public
+Dialog (Dialog parent, String title, boolean modal, GraphicsConfiguration gc)
+{
+ super (parent, parent.getGraphicsConfiguration ());
+
+ // A null title is equivalent to an empty title
+ this.title = (title != null) ? title : "";
+ this.modal = modal;
+ visible = false;
+
+ setLayout (new BorderLayout ());
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Returns the title of this dialog box.
+ *
+ * @return The title of this dialog box.
+ */
+public String
+getTitle()
+{
+ return(title);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the title of this dialog box to the specified string.
+ *
+ * @param title The new title.
+ */
+public synchronized void
+setTitle(String title)
+{
+ // A null title is equivalent to an empty title
+ this.title = (title != null) ? title : "";
+
+ if (peer != null)
+ {
+ DialogPeer d = (DialogPeer) peer;
+ d.setTitle (title);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this dialog box is modal.
+ *
+ * @return <code>true</code> if this dialog box is modal,
+ * <code>false</code> otherwise.
+ */
+public boolean
+isModal()
+{
+ return(modal);
+}
+
+/*************************************************************************/
+
+/**
+ * Changes the modality of this dialog box. This can only be done before
+ * the peer is created.
+ *
+ * @param modal <code>true</code> to make this dialog box modal,
+ * <code>false</code> to make it non-modal.
+ */
+public void
+setModal(boolean modal)
+{
+ this.modal = modal;
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this dialog box is resizable.
+ *
+ * @return <code>true</code> if this dialog is resizable, <code>false</code>,
+ * otherwise.
+ */
+public boolean
+isResizable()
+{
+ return(resizable);
+}
+
+/*************************************************************************/
+
+/**
+ * Changes the resizability of this dialog box.
+ *
+ * @param resizable <code>true</code> to make this dialog resizable,
+ * <code>false</code> to make it non-resizable.
+ */
+public synchronized void
+setResizable(boolean resizable)
+{
+ this.resizable = resizable;
+ if (peer != null)
+ {
+ DialogPeer d = (DialogPeer) peer;
+ d.setResizable (resizable);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Creates this object's native peer.
+ */
+public synchronized void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createDialog (this);
+ super.addNotify ();
+}
+
+/*************************************************************************/
+
+/**
+ * Makes this dialog visible and brings it to the front.
+ * If the dialog is modal and is not already visible, this call will not
+ * return until the dialog is hidden by someone calling hide or dispose.
+ * If this is the event dispatching thread we must ensure that another event
+ * thread runs while the one which invoked this method is blocked.
+ */
+public synchronized void
+show()
+{
+ super.show();
+
+ if (isModal())
+ {
+ // If already shown (and blocked) just return
+ if (blocked)
+ return;
+
+ /* If show is called in the dispatch thread for a modal dialog it will
+ block so we must run another thread so the events keep being
+ dispatched.*/
+ if (EventQueue.isDispatchThread ())
+ {
+ EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ eq2 = new EventQueue ();
+ eq.push (eq2);
+ }
+
+ try
+ {
+ blocked = true;
+ wait ();
+ blocked = false;
+ }
+ catch (InterruptedException e)
+ {
+ blocked = false;
+ }
+
+ if (eq2 != null)
+ {
+ eq2.pop ();
+ eq2 = null;
+ }
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Hides the Dialog and then
+ * causes show() to return if it is currently blocked.
+ */
+
+public synchronized void
+hide ()
+{
+ if (blocked)
+ {
+ notifyAll ();
+ }
+
+ super.hide();
+}
+
+/*************************************************************************/
+
+/**
+ * Disposes the Dialog and then causes show() to return
+ * if it is currently blocked.
+ */
+
+public synchronized void
+dispose ()
+{
+ if (blocked)
+ {
+ notifyAll ();
+ }
+
+ super.dispose();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this component.
+ *
+ * @return A debugging string for this component.
+ */
+protected String
+paramString()
+{
+ return ("title+" + title + ",modal=" + modal +
+ ",resizable=" + resizable + "," + super.paramString());
+}
+
+ /**
+ * Returns whether this frame is undecorated or not.
+ *
+ * @since 1.4
+ */
+ public boolean isUndecorated ()
+ {
+ return undecorated;
+ }
+
+ /**
+ * Disables or enables decorations for this frame. This method can only be
+ * called while the frame is not displayable.
+ *
+ * @exception IllegalComponentStateException If this frame is displayable.
+ *
+ * @since 1.4
+ */
+ public void setUndecorated (boolean undecorated)
+ {
+ if (isDisplayable ())
+ throw new IllegalComponentStateException ();
+
+ this.undecorated = undecorated;
+ }
+
+ protected class AccessibleAWTDialog extends AccessibleAWTWindow
+ {
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.DIALOG;
+ }
+
+ public AccessibleStateSet getAccessibleState()
+ {
+ AccessibleStateSet states = super.getAccessibleStateSet();
+ if (isResizable())
+ states.add(AccessibleState.RESIZABLE);
+ if (isModal())
+ states.add(AccessibleState.MODAL);
+ return states;
+ }
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>Dialog</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTDialog();
+ return accessibleContext;
+ }
+
+} // class Dialog
+
diff --git a/libjava/classpath/java/awt/Dimension.java b/libjava/classpath/java/awt/Dimension.java
new file mode 100644
index 0000000..4c1a07b
--- /dev/null
+++ b/libjava/classpath/java/awt/Dimension.java
@@ -0,0 +1,234 @@
+/* Dimension.java -- represents a 2-dimensional span
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.Dimension2D;
+import java.io.Serializable;
+
+/**
+ * This class holds a width and height value pair. This is used in plenty
+ * of windowing classes, but also has geometric meaning.
+ *
+ * <p>It is valid for a dimension to have negative width or height; but it
+ * is considered to have no area. Therefore, the behavior in various methods
+ * is undefined in such a case.
+ *
+ * <p>There are some public fields; if you mess with them in an inconsistent
+ * manner, it is your own fault when you get invalid results. Also, this
+ * class is not threadsafe.
+ *
+ * @author Per Bothner (bothner@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Component
+ * @see LayoutManager
+ * @since 1.0
+ * @status updated to 1.14
+ */
+public class Dimension extends Dimension2D implements Serializable
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 4723952579491349524L;
+
+ /**
+ * The width of this object.
+ *
+ * @see #getSize()
+ * @see #setSize(double, double)
+ * @serial the width
+ */
+ public int width;
+
+ /**
+ * The height of this object.
+ *
+ * @see #getSize()
+ * @see #setSize(double, double)
+ * @serial the height
+ */
+ public int height;
+
+ /**
+ * Create a new Dimension with a width and height of zero.
+ */
+ public Dimension()
+ {
+ }
+
+ /**
+ * Create a new Dimension with width and height identical to that of the
+ * specified dimension.
+ *
+ * @param d the Dimension to copy
+ * @throws NullPointerException if d is null
+ */
+ public Dimension(Dimension d)
+ {
+ width = d.width;
+ height = d.height;
+ }
+
+ /**
+ * Create a new Dimension with the specified width and height.
+ *
+ * @param w the width of this object
+ * @param h the height of this object
+ */
+ public Dimension(int w, int h)
+ {
+ width = w;
+ height = h;
+ }
+
+ /**
+ * Gets the width of this dimension.
+ *
+ * @return the width, as a double
+ */
+ public double getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Gets the height of this dimension.
+ *
+ * @return the height, as a double
+ */
+ public double getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Sets the size of this dimension. The values are rounded to int.
+ *
+ * @param w the new width
+ * @param h the new height
+ * @since 1.2
+ */
+ public void setSize(double w, double h)
+ {
+ width = (int) w;
+ height = (int) h;
+ }
+
+ /**
+ * Returns the size of this dimension. A pretty useless method, as this is
+ * already a dimension.
+ *
+ * @return a copy of this dimension
+ * @see #setSize(Dimension)
+ * @since 1.1
+ */
+ public Dimension getSize()
+ {
+ return new Dimension(width, height);
+ }
+
+ /**
+ * Sets the width and height of this object to match that of the
+ * specified object.
+ *
+ * @param d the Dimension to get the new width and height from
+ * @throws NullPointerException if d is null
+ * @see #getSize()
+ * @since 1.1
+ */
+ public void setSize(Dimension d)
+ {
+ width = d.width;
+ height = d.height;
+ }
+
+ /**
+ * Sets the width and height of this object to the specified values.
+ *
+ * @param w the new width value
+ * @param h the new height value
+ */
+ public void setSize(int w, int h)
+ {
+ width = w;
+ height = h;
+ }
+
+ /**
+ * Tests this object for equality against the specified object. This will
+ * be true if and only if the specified object is an instance of
+ * Dimension2D, and has the same width and height.
+ *
+ * @param obj the object to test against
+ * @return true if the object is equal to this
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof Dimension))
+ return false;
+ Dimension dim = (Dimension) obj;
+ return height == dim.height && width == dim.width;
+ }
+
+ /**
+ * Return the hashcode for this object. It is not documented, but appears
+ * to be <code>((width + height) * (width + height + 1) / 2) + width</code>.
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ // Reverse engineering this was fun!
+ return (width + height) * (width + height + 1) / 2 + width;
+ }
+
+ /**
+ * Returns a string representation of this object. The format is:
+ * <code>getClass().getName() + "[width=" + width + ",height=" + height
+ * + ']'</code>.
+ *
+ * @return a string representation of this object
+ */
+ public String toString()
+ {
+ return getClass().getName()
+ + "[width=" + width + ",height=" + height + ']';
+ }
+} // class Dimension
diff --git a/libjava/classpath/java/awt/DisplayMode.java b/libjava/classpath/java/awt/DisplayMode.java
new file mode 100644
index 0000000..d41d4a8
--- /dev/null
+++ b/libjava/classpath/java/awt/DisplayMode.java
@@ -0,0 +1,164 @@
+/* DisplayMode.java -- a description of display mode configurations
+ Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This encapsulates information about the display mode for a graphics
+ * device configuration. They are device dependent, and may not always be
+ * available.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see GraphicsDevice
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public final class DisplayMode
+{
+ /**
+ * Value of the bit depth if multiple depths are supported.
+ *
+ * @see #getBitDepth()
+ */
+ public static final int BIT_DEPTH_MULTI = -1;
+
+ /**
+ * Value of an unknown refresh rate.
+ *
+ * @see #getRefreshRate()
+ */
+ public static final int REFRESH_RATE_UNKNOWN = 0;
+
+ /** The width. */
+ private final int width;
+
+ /** The height. */
+ private final int height;
+
+ /** The bit depth. */
+ private final int bitDepth;
+
+ /** The refresh rate. */
+ private final int refreshRate;
+
+ /**
+ * Create a mode with the given parameters.
+ *
+ * @param width the width
+ * @param height the height
+ * @param bitDepth the bitDepth
+ * @param refreshRate the refreshRate
+ * @see #BIT_DEPTH_MULTI
+ * @see #REFRESH_RATE_UNKNOWN
+ */
+ public DisplayMode(int width, int height, int bitDepth, int refreshRate)
+ {
+ this.width = width;
+ this.height = height;
+ this.bitDepth = bitDepth;
+ this.refreshRate = refreshRate;
+ }
+
+ /**
+ * Returns the height, in pixels.
+ *
+ * @return the height
+ */
+ public int getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Returns the width, in pixels.
+ *
+ * @return the width
+ */
+ public int getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Returns the bit depth, in bits per pixel. This may be BIT_DEPTH_MULTI.
+ *
+ * @return the bit depth
+ * @see #BIT_DEPTH_MULTI
+ */
+ public int getBitDepth()
+ {
+ return bitDepth;
+ }
+
+ /**
+ * Returns the refresh rate, in hertz. This may be REFRESH_RATE_UNKNOWN.
+ *
+ * @return the refresh rate
+ * @see #REFRESH_RATE_UNKNOWN
+ */
+ public int getRefreshRate()
+ {
+ return refreshRate;
+ }
+
+ /**
+ * Test for equality. This returns true for two modes with identical
+ * parameters.
+ *
+ * @param dm The display mode to compare to
+ *
+ * @return true if it is equal
+ */
+ public boolean equals (DisplayMode dm)
+ {
+ return (width == dm.width
+ && height == dm.height
+ && bitDepth == dm.bitDepth
+ && refreshRate == dm.refreshRate);
+ }
+
+ /**
+ * Returns a hash code for the display mode.
+ *
+ * @return the hash code
+ */
+ public int hashCode()
+ {
+ return width + height + bitDepth + refreshRate;
+ }
+} // class DisplayMode
diff --git a/libjava/classpath/java/awt/Event.java b/libjava/classpath/java/awt/Event.java
new file mode 100644
index 0000000..648139c
--- /dev/null
+++ b/libjava/classpath/java/awt/Event.java
@@ -0,0 +1,185 @@
+/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public class Event implements java.io.Serializable
+{
+ static final long serialVersionUID = 5488922509400504703L;
+
+ public static final int SHIFT_MASK = 1;
+ public static final int CTRL_MASK = 2;
+ public static final int META_MASK = 4;
+ public static final int ALT_MASK = 8;
+
+ public static final int ACTION_EVENT = 1001;
+ public static final int BACK_SPACE = 8;
+ public static final int CAPS_LOCK = 1022;
+ public static final int DELETE = 127;
+ public static final int DOWN = 1005;
+ public static final int END = 1001;
+ public static final int ENTER = 10;
+ public static final int ESCAPE = 27;
+ public static final int F1 = 1008;
+ public static final int F10 = 1017;
+ public static final int F11 = 1018;
+ public static final int F12 = 1019;
+ public static final int F2 = 1009;
+ public static final int F3 = 1010;
+ public static final int F4 = 1011;
+ public static final int F5 = 1012;
+ public static final int F6 = 1013;
+ public static final int F7 = 1014;
+ public static final int F8 = 1015;
+ public static final int F9 = 1016;
+ public static final int GOT_FOCUS = 1004;
+ public static final int HOME = 1000;
+ public static final int INSERT = 1025;
+ public static final int KEY_ACTION = 403;
+ public static final int KEY_ACTION_RELEASE = 404;
+ public static final int KEY_PRESS = 401;
+ public static final int KEY_RELEASE = 402;
+ public static final int LEFT = 1006;
+ public static final int LIST_DESELECT = 702;
+ public static final int LIST_SELECT = 701;
+ public static final int LOAD_FILE = 1002;
+ public static final int LOST_FOCUS = 1005;
+ public static final int MOUSE_DOWN = 501;
+ public static final int MOUSE_DRAG = 506;
+ public static final int MOUSE_ENTER = 504;
+ public static final int MOUSE_EXIT = 505;
+ public static final int MOUSE_MOVE = 503;
+ public static final int MOUSE_UP = 502;
+ public static final int NUM_LOCK = 1023;
+ public static final int PAUSE = 1024;
+ public static final int PGDN = 1003;
+ public static final int PGUP = 1002;
+ public static final int PRINT_SCREEN = 1020;
+ public static final int RIGHT = 1007;
+ public static final int SAVE_FILE = 1003;
+ public static final int SCROLL_ABSOLUTE = 605;
+ public static final int SCROLL_BEGIN = 606;
+ public static final int SCROLL_END = 607;
+ public static final int SCROLL_LINE_DOWN = 602;
+ public static final int SCROLL_LINE_UP = 601;
+ public static final int SCROLL_LOCK = 1021;
+ public static final int SCROLL_PAGE_DOWN = 604;
+ public static final int SCROLL_PAGE_UP = 603;
+ public static final int TAB = 9;
+ public static final int UP = 1004;
+ public static final int WINDOW_DEICONIFY = 204;
+ public static final int WINDOW_DESTROY = 201;
+ public static final int WINDOW_EXPOSE = 202;
+ public static final int WINDOW_ICONIFY = 203;
+ public static final int WINDOW_MOVED = 205;
+
+ public Object arg;
+ public int clickCount;
+ boolean consumed; // Required by serialization spec.
+ public Event evt;
+ public int id;
+ public int key;
+ public int modifiers;
+ public Object target;
+ public long when;
+ public int x;
+ public int y;
+
+ public Event (Object target, int id, Object arg)
+ {
+ this.id = id;
+ this.target = target;
+ this.arg = arg;
+ }
+
+ public Event (Object target, long when, int id, int x, int y, int key,
+ int modifiers)
+ {
+ this.target = target;
+ this.when = when;
+ this.id = id;
+ this.x = x;
+ this.y = y;
+ this.key = key;
+ this.modifiers = modifiers;
+ }
+
+ public Event (Object target, long when, int id, int x, int y, int key,
+ int modifiers, Object arg)
+ {
+ this (target, when, id, x, y, key, modifiers);
+ this.arg = arg;
+ }
+
+ public boolean controlDown ()
+ {
+ return ((modifiers & CTRL_MASK) == 0 ? false : true);
+ }
+
+ public boolean metaDown ()
+ {
+ return ((modifiers & META_MASK) == 0 ? false : true);
+ }
+
+ protected String paramString ()
+ {
+ return "id=" + id + ",x=" + x + ",y=" + y
+ + ",target=" + target + ",arg=" + arg;
+ }
+
+ public boolean shiftDown()
+ {
+ return ((modifiers & SHIFT_MASK) == 0 ? false : true);
+ }
+
+ public String toString()
+ {
+ return getClass().getName() + "[" + paramString() + "]";
+ }
+
+ public void translate (int x, int y)
+ {
+ this.x += x;
+ this.y += y;
+ }
+}
diff --git a/libjava/classpath/java/awt/EventDispatchThread.java b/libjava/classpath/java/awt/EventDispatchThread.java
new file mode 100644
index 0000000..a64cdae
--- /dev/null
+++ b/libjava/classpath/java/awt/EventDispatchThread.java
@@ -0,0 +1,94 @@
+/* EventDispatchThread.java -
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt;
+
+/**
+ * @author Bryce McKinlay
+ * @status believed complete, but untested.
+ */
+class EventDispatchThread extends Thread
+{
+ private static int dispatchThreadNum;
+
+ private EventQueue queue;
+
+ EventDispatchThread(EventQueue queue)
+ {
+ super();
+ setName("AWT-EventQueue-" + ++dispatchThreadNum);
+ this.queue = queue;
+ setPriority(NORM_PRIORITY + 1);
+ }
+
+ public void run()
+ {
+ while (true)
+ {
+ try
+ {
+ AWTEvent evt = queue.getNextEvent();
+
+ KeyboardFocusManager manager;
+ manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ // Try to dispatch this event to the current keyboard focus
+ // manager. It will dispatch all FocusEvents, all
+ // WindowEvents related to focus, and all KeyEvents,
+ // returning true. Otherwise, it returns false and we
+ // dispatch the event normally.
+ if (!manager.dispatchEvent (evt))
+ queue.dispatchEvent(evt);
+ }
+ catch (ThreadDeath death)
+ {
+ // If someone wants to kill us, let them.
+ return;
+ }
+ catch (InterruptedException ie)
+ {
+ // We are interrupted when we should finish executing
+ return;
+ }
+ catch (Throwable x)
+ {
+ System.err.println("Exception during event dispatch:");
+ x.printStackTrace(System.err);
+ }
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/EventQueue.java b/libjava/classpath/java/awt/EventQueue.java
new file mode 100644
index 0000000..a8b0078
--- /dev/null
+++ b/libjava/classpath/java/awt/EventQueue.java
@@ -0,0 +1,552 @@
+/* EventQueue.java --
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import gnu.java.awt.ClasspathToolkit;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InvocationEvent;
+import java.awt.event.WindowEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EmptyStackException;
+
+/* Written using on-line Java 2 Platform Standard Edition v1.3 API
+ * Specification, as well as "The Java Class Libraries", 2nd edition
+ * (Addison-Wesley, 1998).
+ * Status: Believed complete, but untested.
+ */
+
+/**
+ * This class manages a queue of <code>AWTEvent</code> objects that
+ * are posted to it. The AWT system uses only one event queue for all
+ * events.
+ *
+ * @author Bryce McKinlay
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class EventQueue
+{
+ private static final int INITIAL_QUEUE_DEPTH = 8;
+ private AWTEvent[] queue = new AWTEvent[INITIAL_QUEUE_DEPTH];
+
+ private int next_in = 0; // Index where next event will be added to queue
+ private int next_out = 0; // Index of next event to be removed from queue
+
+ private EventQueue next;
+ private EventQueue prev;
+ private AWTEvent currentEvent;
+ private long lastWhen = System.currentTimeMillis();
+
+ private EventDispatchThread dispatchThread = new EventDispatchThread(this);
+ private boolean shutdown = false;
+
+ private long lastNativeQueueAccess = 0;
+ private long humanLatencyThreshold = 100;
+
+ synchronized void setShutdown (boolean b)
+ {
+ shutdown = b;
+ }
+
+ synchronized boolean isShutdown ()
+ {
+ if (shutdown)
+ return true;
+
+ // This is the exact self-shutdown condition specified in J2SE:
+ // http://java.sun.com/j2se/1.4.2/docs/api/java/awt/doc-files/AWTThreadIssues.html
+
+ if (peekEvent() == null
+ && ((ClasspathToolkit) Toolkit.getDefaultToolkit()).nativeQueueEmpty())
+ {
+ Frame[] frames = Frame.getFrames();
+ for (int i = 0; i < frames.length; ++i)
+ if (frames[i].isDisplayable())
+ return false;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Initializes a new instance of <code>EventQueue</code>.
+ */
+ public EventQueue()
+ {
+ }
+
+ /**
+ * Returns the next event in the queue. This method will block until
+ * an event is available or until the thread is interrupted.
+ *
+ * @return The next event in the queue.
+ *
+ * @exception InterruptedException If this thread is interrupted while
+ * waiting for an event to be posted to the queue.
+ */
+ public synchronized AWTEvent getNextEvent()
+ throws InterruptedException
+ {
+ if (next != null)
+ return next.getNextEvent();
+
+ ClasspathToolkit tk = ((ClasspathToolkit) Toolkit.getDefaultToolkit());
+ long curr = System.currentTimeMillis();
+
+ if (! tk.nativeQueueEmpty() &&
+ (curr - lastNativeQueueAccess > humanLatencyThreshold))
+ {
+ tk.iterateNativeQueue(this, false);
+ lastNativeQueueAccess = curr;
+ }
+
+ while (next_in == next_out)
+ {
+ // Only the EventDispatchThread associated with the top of the stack is
+ // allowed to get events from the native source; everyone else just
+ // waits on the head of the queue.
+
+ if (isDispatchThread())
+ {
+ // We are not allowed to return null from this method, yet it
+ // is possible that we actually have run out of native events
+ // in the enclosing while() loop, and none of the native events
+ // happened to cause AWT events. We therefore ought to check
+ // the isShutdown() condition here, before risking a "native
+ // wait". If we check it before entering this function we may
+ // wait forever for events after the shutdown condition has
+ // arisen.
+
+ if (isShutdown())
+ throw new InterruptedException();
+
+ tk.iterateNativeQueue(this, true);
+ lastNativeQueueAccess = System.currentTimeMillis();
+ }
+ else
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ie)
+ {
+ }
+ }
+ }
+
+ AWTEvent res = queue[next_out];
+
+ if (++next_out == queue.length)
+ next_out = 0;
+ return res;
+ }
+
+ /**
+ * Returns the next event in the queue without removing it from the queue.
+ * This method will block until an event is available or until the thread
+ * is interrupted.
+ *
+ * @return The next event in the queue.
+ * @specnote Does not block. Returns null if there are no events on the
+ * queue.
+ */
+ public synchronized AWTEvent peekEvent()
+ {
+ if (next != null)
+ return next.peekEvent();
+
+ if (next_in != next_out)
+ return queue[next_out];
+ else
+ return null;
+ }
+
+ /**
+ * Returns the next event in the queue that has the specified id
+ * without removing it from the queue.
+ * This method will block until an event is available or until the thread
+ * is interrupted.
+ *
+ * @param id The event id to return.
+ *
+ * @return The next event in the queue.
+ *
+ * @specnote Does not block. Returns null if there are no matching events
+ * on the queue.
+ */
+ public synchronized AWTEvent peekEvent(int id)
+ {
+ if (next != null)
+ return next.peekEvent(id);
+
+ int i = next_out;
+ while (i != next_in)
+ {
+ AWTEvent qevt = queue[i];
+ if (qevt.id == id)
+ return qevt;
+ }
+ return null;
+ }
+
+ /**
+ * Posts a new event to the queue.
+ *
+ * @param evt The event to post to the queue.
+ *
+ * @exception NullPointerException If event is null.
+ */
+ public synchronized void postEvent(AWTEvent evt)
+ {
+ if (evt == null)
+ throw new NullPointerException();
+
+ if (next != null)
+ {
+ next.postEvent(evt);
+ return;
+ }
+
+ /* Check for any events already on the queue with the same source
+ and ID. */
+ int i = next_out;
+ while (i != next_in)
+ {
+ AWTEvent qevt = queue[i];
+ Object src;
+ if (qevt.id == evt.id
+ && (src = qevt.getSource()) == evt.getSource()
+ && src instanceof Component)
+ {
+ /* If there are, call coalesceEvents on the source component
+ to see if they can be combined. */
+ Component srccmp = (Component) src;
+ AWTEvent coalesced_evt = srccmp.coalesceEvents(qevt, evt);
+ if (coalesced_evt != null)
+ {
+ /* Yes. Replace the existing event with the combined event. */
+ queue[i] = coalesced_evt;
+ return;
+ }
+ break;
+ }
+ if (++i == queue.length)
+ i = 0;
+ }
+
+ queue[next_in] = evt;
+ if (++next_in == queue.length)
+ next_in = 0;
+
+ if (next_in == next_out)
+ {
+ /* Queue is full. Extend it. */
+ AWTEvent[] oldQueue = queue;
+ queue = new AWTEvent[queue.length * 2];
+
+ int len = oldQueue.length - next_out;
+ System.arraycopy(oldQueue, next_out, queue, 0, len);
+ if (next_out != 0)
+ System.arraycopy(oldQueue, 0, queue, len, next_out);
+
+ next_out = 0;
+ next_in = oldQueue.length;
+ }
+
+ if (dispatchThread == null || !dispatchThread.isAlive())
+ {
+ dispatchThread = new EventDispatchThread(this);
+ dispatchThread.start();
+ }
+
+ // Window events might represent the closing of a window, which
+ // might cause the end of the dispatch thread's life, so we'll wake
+ // it up here to give it a chance to check for shutdown.
+
+ if (!isDispatchThread()
+ || (evt.getID() == WindowEvent.WINDOW_CLOSED)
+ || (evt.getID() == WindowEvent.WINDOW_CLOSING))
+ ((ClasspathToolkit) Toolkit.getDefaultToolkit()).wakeNativeQueue();
+
+ notify();
+ }
+
+ /**
+ * Causes runnable to have its run method called in the dispatch thread of the
+ * EventQueue. This will happen after all pending events are processed. The
+ * call blocks until this has happened. This method will throw an Error if
+ * called from the event dispatcher thread.
+ *
+ * @exception InterruptedException If another thread has interrupted
+ * this thread.
+ * @exception InvocationTargetException If an exception is thrown when running
+ * runnable.
+ *
+ * @since 1.2
+ */
+ public static void invokeAndWait(Runnable runnable)
+ throws InterruptedException, InvocationTargetException
+ {
+ if (isDispatchThread ())
+ throw new Error("Can't call invokeAndWait from event dispatch thread");
+
+ EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ Thread current = Thread.currentThread();
+
+ InvocationEvent ie =
+ new InvocationEvent(eq, runnable, current, true);
+
+ synchronized (current)
+ {
+ eq.postEvent(ie);
+ current.wait();
+ }
+
+ Exception exception;
+
+ if ((exception = ie.getException()) != null)
+ throw new InvocationTargetException(exception);
+ }
+
+ /**
+ * This arranges for runnable to have its run method called in the
+ * dispatch thread of the EventQueue. This will happen after all
+ * pending events are processed.
+ *
+ * @since 1.2
+ */
+ public static void invokeLater(Runnable runnable)
+ {
+ EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+
+ InvocationEvent ie =
+ new InvocationEvent(eq, runnable, null, false);
+
+ eq.postEvent(ie);
+ }
+
+ /**
+ * Return true if the current thread is the current AWT event dispatch
+ * thread.
+ */
+ public static boolean isDispatchThread()
+ {
+ EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+
+ /* Find last EventQueue in chain */
+ while (eq.next != null)
+ eq = eq.next;
+
+ return (Thread.currentThread() == eq.dispatchThread);
+ }
+
+ /**
+ * Return the event currently being dispatched by the event
+ * dispatch thread. If the current thread is not the event
+ * dispatch thread, this method returns null.
+ *
+ * @since 1.4
+ */
+ public static AWTEvent getCurrentEvent()
+ {
+ EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ Thread ct = Thread.currentThread();
+
+ /* Find out if this thread is the dispatch thread for any of the
+ EventQueues in the chain */
+ while (ct != eq.dispatchThread)
+ {
+ // Try next EventQueue, if any
+ if (eq.next == null)
+ return null; // Not an event dispatch thread
+ eq = eq.next;
+ }
+
+ return eq.currentEvent;
+ }
+
+ /**
+ * Allows a custom EventQueue implementation to replace this one.
+ * All pending events are transferred to the new queue. Calls to postEvent,
+ * getNextEvent, and peekEvent and others are forwarded to the pushed queue
+ * until it is removed with a pop().
+ *
+ * @exception NullPointerException if newEventQueue is null.
+ */
+ public synchronized void push(EventQueue newEventQueue)
+ {
+ if (newEventQueue == null)
+ throw new NullPointerException ();
+
+ /* Make sure we are at the top of the stack because callers can
+ only get a reference to the one at the bottom using
+ Toolkit.getDefaultToolkit().getSystemEventQueue() */
+ if (next != null)
+ {
+ next.push (newEventQueue);
+ return;
+ }
+
+ /* Make sure we have a live dispatch thread to drive the queue */
+ if (dispatchThread == null)
+ dispatchThread = new EventDispatchThread(this);
+
+ int i = next_out;
+ while (i != next_in)
+ {
+ newEventQueue.postEvent(queue[i]);
+ next_out = i;
+ if (++i == queue.length)
+ i = 0;
+ }
+
+ next = newEventQueue;
+ newEventQueue.prev = this;
+ }
+
+ /** Transfer any pending events from this queue back to the parent queue that
+ * was previously push()ed. Event dispatch from this queue is suspended.
+ *
+ * @exception EmptyStackException If no previous push was made on this
+ * EventQueue.
+ */
+ protected void pop() throws EmptyStackException
+ {
+ if (prev == null)
+ throw new EmptyStackException();
+
+ /* The order is important here, we must get the prev lock first,
+ or deadlock could occur as callers usually get here following
+ prev's next pointer, and thus obtain prev's lock before trying
+ to get this lock. */
+ synchronized (prev)
+ {
+ prev.next = next;
+ if (next != null)
+ next.prev = prev;
+
+ synchronized (this)
+ {
+ int i = next_out;
+ while (i != next_in)
+ {
+ prev.postEvent(queue[i]);
+ next_out = i;
+ if (++i == queue.length)
+ i = 0;
+ }
+ // Empty the queue so it can be reused
+ next_in = 0;
+ next_out = 0;
+
+ ((ClasspathToolkit) Toolkit.getDefaultToolkit()).wakeNativeQueue();
+ setShutdown(true);
+ dispatchThread = null;
+ this.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Dispatches an event. The manner in which the event is dispatched depends
+ * upon the type of the event and the type of the event's source object.
+ *
+ * @exception NullPointerException If event is null.
+ */
+ protected void dispatchEvent(AWTEvent evt)
+ {
+ currentEvent = evt;
+
+ if (evt instanceof InputEvent)
+ lastWhen = ((InputEvent) evt).getWhen();
+ else if (evt instanceof ActionEvent)
+ lastWhen = ((ActionEvent) evt).getWhen();
+ else if (evt instanceof InvocationEvent)
+ lastWhen = ((InvocationEvent) evt).getWhen();
+
+ if (evt instanceof ActiveEvent)
+ {
+ ActiveEvent active_evt = (ActiveEvent) evt;
+ active_evt.dispatch();
+ }
+ else
+ {
+ Object source = evt.getSource();
+
+ if (source instanceof Component)
+ {
+ Component srccmp = (Component) source;
+ srccmp.dispatchEvent(evt);
+ }
+ else if (source instanceof MenuComponent)
+ {
+ MenuComponent srccmp = (MenuComponent) source;
+ srccmp.dispatchEvent(evt);
+ }
+ }
+ }
+
+ /**
+ * Returns the timestamp of the most recent event that had a timestamp, or
+ * the initialization time of the event queue if no events have been fired.
+ * At present, only <code>InputEvent</code>s, <code>ActionEvent</code>s,
+ * <code>InputMethodEvent</code>s, and <code>InvocationEvent</code>s have
+ * timestamps, but this may be added to other events in future versions.
+ * If this is called by the event dispatching thread, it can be any
+ * (sequential) value, but to other threads, the safest bet is to return
+ * System.currentTimeMillis().
+ *
+ * @return the most recent timestamp
+ * @see InputEvent#getWhen()
+ * @see ActionEvent#getWhen()
+ * @see InvocationEvent#getWhen()
+ * @see InputMethodEvent#getWhen()
+ * @since 1.4
+ */
+ public static long getMostRecentEventTime()
+ {
+ EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ if (Thread.currentThread() != eq.dispatchThread)
+ return System.currentTimeMillis();
+ return eq.lastWhen;
+ }
+}
diff --git a/libjava/classpath/java/awt/FileDialog.java b/libjava/classpath/java/awt/FileDialog.java
new file mode 100644
index 0000000..7f2723e
--- /dev/null
+++ b/libjava/classpath/java/awt/FileDialog.java
@@ -0,0 +1,318 @@
+/* FileDialog.java -- A filename selection dialog box
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.peer.FileDialogPeer;
+import java.io.FilenameFilter;
+import java.io.Serializable;
+
+/**
+ * This class implements a file selection dialog box widget.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@redhat.com)
+ */
+public class FileDialog extends Dialog implements Serializable
+{
+
+/*
+ * Static Variables
+ */
+
+/**
+ * Indicates that the purpose of the dialog is for opening a file.
+ */
+public static final int LOAD = 0;
+
+/**
+ * Indicates that the purpose of the dialog is for saving a file.
+ */
+public static final int SAVE = 1;
+
+// Serialization constant
+private static final long serialVersionUID = 5035145889651310422L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The directory for this file dialog.
+ */
+private String dir;
+
+/**
+ * @serial The filename for this file dialog
+ */
+private String file;
+
+/**
+ * @serial The filter for selecting filenames to display
+ */
+private FilenameFilter filter;
+
+/**
+ * @serial The mode of this dialog, either <code>LOAD</code> or
+ * <code>SAVE</code>.
+ */
+private int mode;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>FileDialog</code> with the
+ * specified parent. This dialog will have no title and will be for
+ * loading a file.
+ *
+ * @param parent The parent frame for this dialog.
+ */
+public
+FileDialog(Frame parent)
+{
+ this(parent, "", LOAD);
+}
+
+/*************************************************************************/
+
+/**
+ * Initialized a new instance of <code>FileDialog</code> with the
+ * specified parent and title. This dialog will be for opening a file.
+ *
+ * @param parent The parent frame for this dialog.
+ * @param title The title for this dialog.
+ */
+public
+FileDialog(Frame parent, String title)
+{
+ this(parent, title, LOAD);
+}
+
+/*************************************************************************/
+
+/**
+ * Initialized a new instance of <code>FileDialog</code> with the
+ * specified parent, title, and mode.
+ *
+ * @param parent The parent frame for this dialog.
+ * @param title The title for this dialog.
+ * @param mode The mode of the dialog, either <code>LOAD</code> or
+ * <code>SAVE</code>.
+ *
+ * @exception IllegalArgumentException If an illegal file dialog mode
+ * is supplied.
+ */
+public
+FileDialog(Frame parent, String title, int mode)
+{
+ super(parent, title, true);
+
+ if ((mode != LOAD) && (mode != SAVE))
+ throw new IllegalArgumentException (
+ "Mode argument must be either LOAD or SAVE");
+
+ setMode (mode);
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the mode of this dialog, either <code>LOAD</code> or
+ * <code>SAVE</code>.
+ *
+ * @return The mode of this dialog.
+ */
+public int
+getMode()
+{
+ return(mode);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the mode of this dialog to either <code>LOAD</code> or
+ * <code>SAVE</code>. This method is only effective before the native
+ * peer is created.
+ *
+ * @param mode The new mode of this file dialog.
+ *
+ * @exception IllegalArgumentException If an illegal file dialog mode
+ * is supplied.
+ */
+public void
+setMode(int mode)
+{
+ if ((mode != LOAD) && (mode != SAVE))
+ throw new IllegalArgumentException("Bad mode: " + mode);
+
+ this.mode = mode;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the directory for this file dialog.
+ *
+ * @return The directory for this file dialog.
+ */
+public String
+getDirectory()
+{
+ return(dir);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the directory for this file dialog.
+ *
+ * @param dir The new directory for this file dialog.
+ */
+public synchronized void
+setDirectory(String dir)
+{
+ this.dir = dir;
+ if (peer != null)
+ {
+ FileDialogPeer f = (FileDialogPeer) peer;
+ f.setDirectory (dir);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the file that is selected in this dialog.
+ *
+ * @return The file that is selected in this dialog.
+ */
+public String
+getFile()
+{
+ return(file);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the selected file for this dialog.
+ *
+ * @param file The selected file for this dialog.
+ */
+public synchronized void
+setFile(String file)
+{
+ this.file = file;
+ if (peer != null)
+ {
+ FileDialogPeer f = (FileDialogPeer) peer;
+ f.setFile (file);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the filename filter being used by this dialog.
+ *
+ * @return The filename filter being used by this dialog.
+ */
+public FilenameFilter
+getFilenameFilter()
+{
+ return(filter);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the filename filter used by this dialog.
+ *
+ * @param filter The new filename filter for this file dialog box.
+ */
+public synchronized void
+setFilenameFilter(FilenameFilter filter)
+{
+ this.filter = filter;
+ if (peer != null)
+ {
+ FileDialogPeer f = (FileDialogPeer) peer;
+ f.setFilenameFilter (filter);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Creates the native peer for this file dialog box.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createFileDialog (this);
+ super.addNotify ();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this object.
+ *
+ * @return A debugging string for this object.
+ */
+protected String
+paramString()
+{
+ return ("dir=" + dir + ",file=" + file +
+ ",mode=" + mode + "," + super.paramString());
+}
+
+} // class FileDialog
+
diff --git a/libjava/classpath/java/awt/FlowLayout.java b/libjava/classpath/java/awt/FlowLayout.java
new file mode 100644
index 0000000..4674990
--- /dev/null
+++ b/libjava/classpath/java/awt/FlowLayout.java
@@ -0,0 +1,364 @@
+/* FlowLayout.java -- Grid-based layout engine
+ Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+
+/** This class implements a flow-based layout. Components are laid
+ * out in order from left to right. When a component cannot be placed
+ * without horizontal clipping, a new row is started. This class
+ * supports horizontal and vertical gaps. These are used for spacing
+ * between components.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class FlowLayout implements LayoutManager, Serializable
+{
+ /** Constant that specifies left alignment. */
+ public static final int LEFT = 0;
+ /** Constant that specifies center alignment. */
+ public static final int CENTER = 1;
+ /** Constant that specifies right alignment. */
+ public static final int RIGHT = 2;
+
+ /** Constant that specifies alignment to leading edge of container's
+ * orientation. */
+ public static final int LEADING = 3;
+ /** Constant that specifies alignment to trailing edge of container's
+ * orientation. */
+ public static final int TRAILING = 4;
+
+ // Serialization constant
+ private static final long serialVersionUID = -7262534875583282631L;
+
+ /**
+ * Add a new component to the layout. This particular implementation
+ * does nothing.
+ *
+ * @param name the name
+ * @param comp the component
+ */
+ public void addLayoutComponent (String name, Component comp)
+ {
+ // Nothing.
+ }
+
+ /**
+ * Returns the current justification value for this object.
+ *
+ * @return The current justification value for this object.
+ */
+ public int getAlignment ()
+ {
+ return align;
+ }
+
+ /**
+ * Returns the horizontal gap between components.
+ *
+ * @return The horizontal gap between components.
+ */
+ public int getHgap ()
+ {
+ return hgap;
+ }
+
+ /**
+ * Returns the vertical gap between lines of components.
+ *
+ * @return The vertical gap between lines of components.
+ */
+ public int getVgap ()
+ {
+ return vgap;
+ }
+
+ /**
+ * Initializes a new instance of <code>FlowLayout</code> with a center
+ * justification and a default horizontal and vertical gap of 5.
+ */
+ public FlowLayout ()
+ {
+ this (CENTER, 5, 5);
+ }
+
+ /**
+ * Initializes a new instance of <code>FlowLayout</code> with the specified
+ * justification and a default horizontal and vertical gap of 5.
+ *
+ * @param align The justification setting, which should be one of the
+ * contants in this class.
+ */
+ public FlowLayout (int align)
+ {
+ this (align, 5, 5);
+ }
+
+ /**
+ * Initializes a new instance of <code>FlowLayout</code> with the specified
+ * justification and gap values
+ * @param align Alignment
+ * @param hgap The horizontal gap
+ * @param vgap The vertical gap
+ * @exception IllegalArgumentException If either gap is negative
+ */
+ public FlowLayout (int align, int hgap, int vgap)
+ {
+ // Use methods to set fields so that we can have all the checking
+ // in one place.
+ setVgap (vgap);
+ setHgap (hgap);
+ setAlignment (align);
+ }
+
+ /** Lay out the container's components based on current settings.
+ * @param parent The parent container
+ */
+ public void layoutContainer (Container parent)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int num = parent.getComponentCount ();
+ // This is more efficient than calling getComponents().
+ Component[] comps = parent.component;
+
+ Dimension d = parent.getSize ();
+ Insets ins = parent.getInsets ();
+
+ ComponentOrientation orient = parent.getComponentOrientation ();
+ boolean left_to_right = orient.isLeftToRight ();
+
+ int y = ins.top + vgap;
+ int i = 0;
+ while (i < num)
+ {
+ // Find the components which go in the current row.
+ int new_w = ins.left + hgap + ins.right;
+ int new_h = 0;
+ int j;
+ boolean found_one = false;
+ for (j = i; j < num; ++j)
+ {
+ // Skip invisible items.
+ if (! comps[j].visible)
+ continue;
+
+ Dimension c = comps[j].getPreferredSize ();
+
+ int next_w = new_w + hgap + c.width;
+ if (next_w <= d.width || ! found_one)
+ {
+ new_w = next_w;
+ new_h = Math.max (new_h, c.height);
+ found_one = true;
+ }
+ else
+ {
+ // Must start a new row, and we already found an item
+ break;
+ }
+ }
+
+ // Set the location of each component for this row.
+ int x;
+
+ int myalign = align;
+ if (align == LEADING)
+ myalign = left_to_right ? LEFT : RIGHT;
+ else if (align == TRAILING)
+ myalign = left_to_right ? RIGHT : LEFT;
+
+ if (myalign == LEFT)
+ x = ins.left + hgap;
+ else if (myalign == CENTER)
+ x = ins.left + (d.width - new_w) / 2 + hgap;
+ else
+ x = ins.left + (d.width - new_w) + hgap;
+
+ for (int k = i; k < j; ++k)
+ {
+ if (comps[k].visible)
+ {
+ Dimension c = comps[k].getPreferredSize ();
+ comps[k].setBounds (x, y + (new_h - c.height) / 2,
+ c.width, c.height);
+ x += c.width + hgap;
+ }
+ }
+
+ // Advance to next row.
+ i = j;
+ y += new_h + vgap;
+ }
+ }
+ }
+
+ /**
+ * Returns the minimum layout size for the specified container using
+ * this layout.
+ * @param cont The parent container
+ * @return The minimum layout size.
+ */
+ public Dimension minimumLayoutSize (Container cont)
+ {
+ return getSize (cont, true);
+ }
+
+ /**
+ * Returns the preferred layout size for the specified container using
+ * this layout.
+ * @param cont The parent container
+ * @return The preferred layout size.
+ */
+ public Dimension preferredLayoutSize (Container cont)
+ {
+ return getSize (cont, false);
+ }
+
+ /** Remove the indicated component from this layout manager.
+ * This particular implementation does nothing.
+ * @param comp The component to remove
+ */
+ public void removeLayoutComponent (Component comp)
+ {
+ // Nothing.
+ }
+
+ /**
+ * Sets the justification value for this object to the specified value.
+ *
+ * @param align The new justification value for this object, which must
+ * be one of the constants in this class.
+ */
+ public void setAlignment (int align)
+ {
+ if (align != LEFT && align != RIGHT && align != CENTER
+ && align != LEADING && align != TRAILING)
+ throw new IllegalArgumentException ("invalid alignment: " + align);
+ this.align = align;
+ }
+
+ /**
+ * Sets the horizontal gap between components to the specified value.
+ *
+ * @param hgap The new horizontal gap between components.
+ */
+ public void setHgap (int hgap)
+ {
+ if (hgap < 0)
+ throw new IllegalArgumentException ("horizontal gap must be nonnegative");
+ this.hgap = hgap;
+ }
+
+ /**
+ * Sets the vertical gap between lines of components to the specified value.
+ *
+ * @param vgap The new vertical gap.
+ */
+ public void setVgap (int vgap)
+ {
+ if (vgap < 0)
+ throw new IllegalArgumentException ("vertical gap must be nonnegative");
+ this.vgap = vgap;
+ }
+
+ /** Return String description of this object.
+ * @return A string representation of this object.
+ */
+ public String toString ()
+ {
+ return ("[" + getClass ().getName () + ",hgap=" + hgap + ",vgap=" + vgap
+ + ",align=" + align + "]");
+ }
+
+ // This method is used to compute the various sizes.
+ private Dimension getSize (Container parent, boolean is_min)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int w, h, num = parent.getComponentCount ();
+ // This is more efficient than calling getComponents().
+ Component[] comps = parent.component;
+
+ w = 0;
+ h = 0;
+ for (int i = 0; i < num; ++i)
+ {
+ if (! comps[i].visible)
+ continue;
+
+ // FIXME: can we just directly read the fields in Component?
+ // Or will that not work with subclassing?
+ Dimension d;
+
+ if (is_min)
+ d = comps[i].getMinimumSize ();
+ else
+ d = comps[i].getPreferredSize ();
+
+ w += d.width;
+ h = Math.max (d.height, h);
+ }
+
+ Insets ins = parent.getInsets ();
+
+ w += (num + 1) * hgap + ins.left + ins.right;
+ h += 2 * vgap + ins.top + ins.bottom;
+
+ return new Dimension (w, h);
+ }
+ }
+
+ /**
+ * @serial The justification alignment of the lines of components, which
+ * will be one of the constants defined in this class.
+ */
+ private int align;
+
+ /**
+ * @serial The horizontal gap between components.
+ */
+ private int hgap;
+
+ /**
+ * @serial The vertical gap between lines of components.
+ */
+ private int vgap;
+}
diff --git a/libjava/classpath/java/awt/FocusTraversalPolicy.java b/libjava/classpath/java/awt/FocusTraversalPolicy.java
new file mode 100644
index 0000000..a7f1558
--- /dev/null
+++ b/libjava/classpath/java/awt/FocusTraversalPolicy.java
@@ -0,0 +1,103 @@
+/* FocusTraversalPolicy.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * @since 1.4
+ */
+public abstract class FocusTraversalPolicy
+{
+ /**
+ * Creates a <code>FocusTraversalPolicy</code> object.
+ */
+ public FocusTraversalPolicy()
+ {
+ // Do nothing in here.
+ }
+
+ /**
+ * Returns the Component that should receive the focus after a Component.
+ *
+ * @exception IllegalArgumentException If root or current is null,
+ * or if root is not a focus cycle root of current.
+ */
+ public abstract Component getComponentAfter(Container root,
+ Component current);
+
+ /**
+ * Returns the Component that should receive the focus before a Component.
+ *
+ * @exception IllegalArgumentException If root or current is null,
+ * or if root is not a focus cycle root of current.
+ */
+ public abstract Component getComponentBefore(Container root,
+ Component current);
+
+ /**
+ * Returns the first Component in the traversal cycle.
+ *
+ * @exception IllegalArgumentException If root is null.
+ */
+ public abstract Component getFirstComponent(Container root);
+
+ /**
+ * Returns the last Component in the traversal cycle.
+ *
+ * @exception IllegalArgumentException If root is null.
+ */
+ public abstract Component getLastComponent(Container root);
+
+ /**
+ * Returns the default Component to focus.
+ *
+ * @exception IllegalArgumentException If root is null.
+ */
+ public abstract Component getDefaultComponent(Container root);
+
+ /**
+ * Returns the Component that should receive the focus when a Window is made
+ * visible for the first time.
+ *
+ * @exception IllegalArgumentException If window is null.
+ */
+ public Component getInitialComponent(Window window)
+ {
+ return getDefaultComponent(window);
+ }
+} // class FocusTraversalPolicy
diff --git a/libjava/classpath/java/awt/Font.java b/libjava/classpath/java/awt/Font.java
new file mode 100644
index 0000000..30961ab
--- /dev/null
+++ b/libjava/classpath/java/awt/Font.java
@@ -0,0 +1,1336 @@
+/* Font.java -- Font object
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import gnu.java.awt.ClasspathToolkit;
+import gnu.java.awt.peer.ClasspathFontPeer;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.peer.FontPeer;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.text.AttributedCharacterIterator;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * This class represents a windowing system font.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
+public class Font implements Serializable
+{
+
+/*
+ * Static Variables
+ */
+
+/**
+ * Constant indicating a "plain" font.
+ */
+public static final int PLAIN = 0;
+
+/**
+ * Constant indicating a "bold" font.
+ */
+public static final int BOLD = 1;
+
+/**
+ * Constant indicating an "italic" font.
+ */
+public static final int ITALIC = 2;
+
+/**
+ * Constant indicating the baseline mode characteristic of Roman.
+ */
+public static final int ROMAN_BASELINE = 0;
+
+/**
+ * Constant indicating the baseline mode characteristic of Chinese.
+ */
+public static final int CENTER_BASELINE = 1;
+
+/**
+ * Constant indicating the baseline mode characteristic of Devanigri.
+ */
+public static final int HANGING_BASELINE = 2;
+
+
+ /**
+ * Indicates to <code>createFont</code> that the supplied font data
+ * is in TrueType format.
+ *
+ * <p><em>Specification Note:</em> The Sun JavaDoc for J2SE 1.4 does
+ * not indicate whether this value also subsumes OpenType. OpenType
+ * is essentially the same format as TrueType, but allows to define
+ * glyph shapes in the same way as PostScript, using cubic bezier
+ * curves.
+ *
+ * @since 1.3
+ */
+ public static final int TRUETYPE_FONT = 0;
+
+
+ /**
+ * A flag for <code>layoutGlyphVector</code>, indicating that the
+ * orientation of a text run is from left to right.
+ *
+ * @since 1.4
+ */
+ public static final int LAYOUT_LEFT_TO_RIGHT = 0;
+
+
+ /**
+ * A flag for <code>layoutGlyphVector</code>, indicating that the
+ * orientation of a text run is from right to left.
+ *
+ * @since 1.4
+ */
+ public static final int LAYOUT_RIGHT_TO_LEFT = 1;
+
+
+ /**
+ * A flag for <code>layoutGlyphVector</code>, indicating that the
+ * text does not contain valid characters before the
+ * <code>start</code> position. If this flag is set,
+ * <code>layoutGlyphVector</code> does not examine the text before
+ * <code>start</code>, even if this would be necessary to select the
+ * correct glyphs (e.g., for Arabic text).
+ *
+ * @since 1.4
+ */
+ public static final int LAYOUT_NO_START_CONTEXT = 2;
+
+
+ /**
+ * A flag for <code>layoutGlyphVector</code>, indicating that the
+ * text does not contain valid characters after the
+ * <code>limit</code> position. If this flag is set,
+ * <code>layoutGlyphVector</code> does not examine the text after
+ * <code>limit</code>, even if this would be necessary to select the
+ * correct glyphs (e.g., for Arabic text).
+ *
+ * @since 1.4
+ */
+ public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
+
+ /**
+ * The logical name of this font.
+ *
+ * @since 1.0
+ */
+ protected String name;
+
+ /**
+ * The size of this font in pixels.
+ *
+ * @since 1.0
+ */
+ protected int size;
+
+ /**
+ * The style of this font -- PLAIN, BOLD, ITALIC or BOLD+ITALIC.
+ *
+ * @since 1.0
+ */
+ protected int style;
+
+// Serialization constant
+private static final long serialVersionUID = -4206021311591459213L;
+
+
+ // The ClasspathToolkit-provided peer which implements this font
+ private ClasspathFontPeer peer;
+
+/*************************************************************************/
+
+/*
+ * Static Methods
+ */
+
+/**
+ * Creates a <code>Font</code> object from the specified string, which
+ * is in one of the following formats:
+ * <p>
+ * <ul>
+ * <li>fontname-style-pointsize
+ * <li>fontname-style
+ * <li>fontname-pointsize
+ * <li>fontname
+ * </ul>
+ * <p>
+ * The style should be one of BOLD, ITALIC, or BOLDITALIC. The default
+ * style if none is specified is PLAIN. The default size if none
+ * is specified is 12.
+ *
+ * @param fontspec a string specifying the required font (<code>null</code>
+ * permitted, interpreted as 'Dialog-PLAIN-12').
+ *
+ * @return A font.
+ */
+ public static Font decode (String fontspec)
+{
+ if (fontspec == null)
+ fontspec = "Dialog-PLAIN-12";
+ String name = null;
+ int style = PLAIN;
+ int size = 12;
+
+ StringTokenizer st = new StringTokenizer(fontspec, "- ");
+ while (st.hasMoreTokens())
+ {
+ String token = st.nextToken();
+ if (name == null)
+ {
+ name = token;
+ continue;
+ }
+
+ if (token.toUpperCase().equals("BOLD"))
+ {
+ style = BOLD;
+ continue;
+ }
+ if (token.toUpperCase().equals("ITALIC"))
+ {
+ style = ITALIC;
+ continue;
+ }
+ if (token.toUpperCase().equals("BOLDITALIC"))
+ {
+ style = BOLD | ITALIC;
+ continue;
+ }
+
+ int tokenval = 0;
+ try
+ {
+ tokenval = Integer.parseInt(token);
+ }
+ catch(NumberFormatException e)
+ {
+ // Ignored.
+ }
+
+ if (tokenval != 0)
+ size = tokenval;
+ }
+
+ HashMap attrs = new HashMap();
+ ClasspathFontPeer.copyStyleToAttrs (style, attrs);
+ ClasspathFontPeer.copySizeToAttrs (size, attrs);
+
+ return getFontFromToolkit (name, attrs);
+}
+
+ /* These methods delegate to the toolkit. */
+
+ protected static ClasspathToolkit tk ()
+ {
+ return (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ }
+
+ /* Every factory method in Font should eventually call this. */
+ protected static Font getFontFromToolkit (String name, Map attribs)
+ {
+ return tk ().getFont (name, attribs);
+ }
+
+ /* Every Font constructor should eventually call this. */
+ protected static ClasspathFontPeer getPeerFromToolkit (String name, Map attrs)
+ {
+ return tk ().getClasspathFontPeer (name, attrs);
+ }
+
+
+/*************************************************************************/
+
+/**
+ * Returns a <code>Font</code> object from the passed property name.
+ *
+ * @param propname The name of the system property.
+ * @param defval Value to use if the property is not found.
+ *
+ * @return The requested font, or <code>default</code> if the property
+ * not exist or is malformed.
+ */
+ public static Font getFont (String propname, Font defval)
+{
+ String propval = System.getProperty(propname);
+ if (propval != null)
+ return decode (propval);
+ return defval;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a <code>Font</code> object from the passed property name.
+ *
+ * @param propname The name of the system property.
+ *
+ * @return The requested font, or <code>null</code> if the property
+ * not exist or is malformed.
+ */
+ public static Font getFont (String propname)
+{
+ return getFont (propname, (Font)null);
+}
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>Font</code> with the specified
+ * attributes.
+ *
+ * @param name The name of the font.
+ * @param style The font style.
+ * @param size The font point size.
+ */
+
+ public Font (String name, int style, int size)
+ {
+ HashMap attrs = new HashMap();
+ ClasspathFontPeer.copyStyleToAttrs (style, attrs);
+ ClasspathFontPeer.copySizeToAttrs (size, attrs);
+ this.peer = getPeerFromToolkit (name, attrs);
+ }
+
+ public Font (Map attrs)
+ {
+ this(null, attrs);
+ }
+
+ /* This extra constructor is here to permit ClasspathToolkit and to build
+ a font with a "logical name" as well as attrs. */
+ public Font (String name, Map attrs)
+ {
+ // If attrs is null, setting it to an empty HashMap will give this
+ // Font default attributes.
+ if (attrs == null)
+ attrs = new HashMap();
+ this.peer = getPeerFromToolkit (name, attrs);
+ }
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the logical name of the font. A logical name is the name the
+ * font was constructed with. It may be the name of a logical font (one
+ * of 6 required names in all java environments) or it may be a face
+ * name.
+ *
+ * @return The logical name of the font.
+ *
+ * @see #getFamily()
+ * @see #getFontName()
+ */
+ public String getName ()
+{
+ return peer.getName (this);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the style of the font.
+ *
+ * @return The font style.
+ */
+ public int getSize ()
+{
+ return (int) peer.getSize (this);
+}
+
+ public float getSize2D ()
+{
+ return peer.getSize (this);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this is a plain font. This will be true if
+ * and only if neither the bold nor the italics style is set.
+ *
+ * @return <code>true</code> if this is a plain font, <code>false</code>
+ * otherwise.
+ */
+ public boolean isPlain ()
+{
+ return peer.isPlain (this);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this font is bold.
+ *
+ * @return <code>true</code> if this font is bold, <code>false</code>
+ * otherwise.
+ */
+ public boolean isBold ()
+{
+ return peer.isBold (this);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this font is italic.
+ *
+ * @return <code>true</code> if this font is italic, <code>false</code>
+ * otherwise.
+ */
+ public boolean isItalic ()
+{
+ return peer.isItalic (this);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the family name of this font. A family name describes a design
+ * or "brand name" (such as Helvetica or Palatino). It is less specific
+ * than a font face name (such as Helvetica Bold).
+ *
+ * @return A string containing the font family name.
+ *
+ * @since 1.2
+ *
+ * @see #getName()
+ * @see #getFontName()
+ * @see GraphicsEnvironment#getAvailableFontFamilyNames()
+ */
+ public String getFamily ()
+{
+ return peer.getFamily (this);
+}
+
+/**
+ * Returns integer code representing the sum of style flags of this font, a
+ * combination of either {@link #PLAIN}, {@link #BOLD}, or {@link #ITALIC}.
+ *
+ * @return code representing the style of this font.
+ *
+ * @see #isPlain()
+ * @see #isBold()
+ * @see #isItalic()
+ */
+ public int getStyle ()
+{
+ return peer.getStyle (this);
+}
+
+/**
+ * Checks if specified character maps to a glyph in this font.
+ *
+ * @param c The character to check.
+ *
+ * @return Whether the character has a corresponding glyph in this font.
+ *
+ * @since 1.2
+ */
+ public boolean canDisplay (char c)
+{
+ return peer.canDisplay (this, c);
+}
+
+/**
+ * Checks how much of a given string can be mapped to glyphs in
+ * this font.
+ *
+ * @param s The string to check.
+ *
+ * @return The index of the first character in <code>s</code> which cannot
+ * be converted to a glyph by this font, or <code>-1</code> if all
+ * characters can be mapped to glyphs.
+ *
+ * @since 1.2
+ */
+ public int canDisplayUpTo (String s)
+{
+ return peer.canDisplayUpTo (this, new StringCharacterIterator (s),
+ 0, s.length () - 1);
+}
+
+/**
+ * Checks how much of a given sequence of text can be mapped to glyphs in
+ * this font.
+ *
+ * @param text Array containing the text to check.
+ * @param start Position of first character to check in <code>text</code>.
+ * @param limit Position of last character to check in <code>text</code>.
+ *
+ * @return The index of the first character in the indicated range which
+ * cannot be converted to a glyph by this font, or <code>-1</code> if all
+ * characters can be mapped to glyphs.
+ *
+ * @since 1.2
+ *
+ * @throws IndexOutOfBoundsException if the range [start, limit] is
+ * invalid in <code>text</code>.
+ */
+ public int canDisplayUpTo (char[] text, int start, int limit)
+{
+ return peer.canDisplayUpTo
+ (this, new StringCharacterIterator (new String (text)), start, limit);
+}
+
+/**
+ * Checks how much of a given sequence of text can be mapped to glyphs in
+ * this font.
+ *
+ * @param i Iterator over the text to check.
+ * @param start Position of first character to check in <code>i</code>.
+ * @param limit Position of last character to check in <code>i</code>.
+ *
+ * @return The index of the first character in the indicated range which
+ * cannot be converted to a glyph by this font, or <code>-1</code> if all
+ * characters can be mapped to glyphs.
+ *
+ * @since 1.2
+ *
+ * @throws IndexOutOfBoundsException if the range [start, limit] is
+ * invalid in <code>i</code>.
+ */
+ public int canDisplayUpTo (CharacterIterator i, int start, int limit)
+{
+ return peer.canDisplayUpTo (this, i, start, limit);
+}
+
+/**
+ * Creates a new font with point size 1 and {@link #PLAIN} style,
+ * reading font data from the provided input stream. The resulting font
+ * can have further fonts derived from it using its
+ * <code>deriveFont</code> method.
+ *
+ * @param fontFormat Integer code indicating the format the font data is
+ * in.Currently this can only be {@link #TRUETYPE_FONT}.
+ * @param is {@link InputStream} from which font data will be read. This
+ * stream is not closed after font data is extracted.
+ *
+ * @return A new {@link Font} of the format indicated.
+ *
+ * @throws IllegalArgumentException if <code>fontType</code> is not
+ * recognized.
+ * @throws FontFormatException if data in InputStream is not of format
+ * indicated.
+ * @throws IOException if insufficient data is present on InputStream.
+ *
+ * @since 1.3
+ */
+ public static Font createFont (int fontFormat, InputStream is)
+ throws FontFormatException, IOException
+{
+ return tk().createFont (fontFormat, is);
+}
+
+/**
+ * Maps characters to glyphs in a one-to-one relationship, returning a new
+ * {@link GlyphVector} with a mapped glyph for each input character. This
+ * sort of mapping is often sufficient for some scripts such as Roman, but
+ * is inappropriate for scripts with special shaping or contextual layout
+ * requirements such as Arabic, Indic, Hebrew or Thai.
+ *
+ * @param ctx The rendering context used for precise glyph placement.
+ * @param str The string to convert to Glyphs.
+ *
+ * @return A new {@link GlyphVector} containing glyphs mapped from str,
+ * through the font's cmap table.
+ *
+ * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
+ */
+ public GlyphVector createGlyphVector (FontRenderContext ctx, String str)
+{
+ return peer.createGlyphVector (this, ctx, new StringCharacterIterator (str));
+}
+
+/**
+ * Maps characters to glyphs in a one-to-one relationship, returning a new
+ * {@link GlyphVector} with a mapped glyph for each input character. This
+ * sort of mapping is often sufficient for some scripts such as Roman, but
+ * is inappropriate for scripts with special shaping or contextual layout
+ * requirements such as Arabic, Indic, Hebrew or Thai.
+ *
+ * @param ctx The rendering context used for precise glyph placement.
+ * @param i Iterator over the text to convert to glyphs.
+ *
+ * @return A new {@link GlyphVector} containing glyphs mapped from str,
+ * through the font's cmap table.
+ *
+ * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
+ */
+ public GlyphVector createGlyphVector (FontRenderContext ctx, CharacterIterator i)
+{
+ return peer.createGlyphVector (this, ctx, i);
+}
+
+/**
+ * Maps characters to glyphs in a one-to-one relationship, returning a new
+ * {@link GlyphVector} with a mapped glyph for each input character. This
+ * sort of mapping is often sufficient for some scripts such as Roman, but
+ * is inappropriate for scripts with special shaping or contextual layout
+ * requirements such as Arabic, Indic, Hebrew or Thai.
+ *
+ * @param ctx The rendering context used for precise glyph placement.
+ * @param chars Array of characters to convert to glyphs.
+ *
+ * @return A new {@link GlyphVector} containing glyphs mapped from str,
+ * through the font's cmap table.
+ *
+ * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
+ */
+ public GlyphVector createGlyphVector (FontRenderContext ctx, char[] chars)
+{
+ return peer.createGlyphVector
+ (this, ctx, new StringCharacterIterator (new String (chars)));
+}
+
+/**
+ * Extracts a sequence of glyphs from a font, returning a new {@link
+ * GlyphVector} with a mapped glyph for each input glyph code.
+ *
+ * @param ctx The rendering context used for precise glyph placement.
+ * @param glyphCodes Array of characters to convert to glyphs.
+ *
+ * @return A new {@link GlyphVector} containing glyphs mapped from str,
+ * through the font's cmap table.
+ *
+ * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
+ *
+ * @specnote This method is documented to perform character-to-glyph
+ * conversions, in the Sun documentation, but its second parameter name is
+ * "glyphCodes" and it is not clear to me why it would exist if its
+ * purpose was to transport character codes inside integers. I assume it
+ * is mis-documented in the Sun documentation.
+ */
+
+ public GlyphVector createGlyphVector (FontRenderContext ctx, int[] glyphCodes)
+{
+ return peer.createGlyphVector (this, ctx, glyphCodes);
+}
+
+/**
+ * Produces a new {@link Font} based on the current font, adjusted to a
+ * new size and style.
+ *
+ * @param style The style of the newly created font.
+ * @param size The size of the newly created font.
+ *
+ * @return A clone of the current font, with the specified size and style.
+ *
+ * @since 1.2
+ */
+ public Font deriveFont (int style, float size)
+{
+ return peer.deriveFont (this, style, size);
+}
+
+/**
+ * Produces a new {@link Font} based on the current font, adjusted to a
+ * new size.
+ *
+ * @param size The size of the newly created font.
+ *
+ * @return A clone of the current font, with the specified size.
+ *
+ * @since 1.2
+ */
+ public Font deriveFont (float size)
+{
+ return peer.deriveFont (this, size);
+}
+
+/**
+ * Produces a new {@link Font} based on the current font, adjusted to a
+ * new style.
+ *
+ * @param style The style of the newly created font.
+ *
+ * @return A clone of the current font, with the specified style.
+ *
+ * @since 1.2
+ */
+ public Font deriveFont (int style)
+{
+ return peer.deriveFont (this, style);
+}
+
+/**
+ * Produces a new {@link Font} based on the current font, adjusted to a
+ * new style and subjected to a new affine transformation.
+ *
+ * @param style The style of the newly created font.
+ * @param a The transformation to apply.
+ *
+ * @return A clone of the current font, with the specified style and
+ * transform.
+ *
+ * @throws IllegalArgumentException If transformation is
+ * <code>null</code>.
+ *
+ * @since 1.2
+ */
+ public Font deriveFont (int style, AffineTransform a)
+{
+ if (a == null)
+ throw new IllegalArgumentException ("Affine transformation is null");
+
+ return peer.deriveFont (this, style, a);
+}
+
+/**
+ * Produces a new {@link Font} based on the current font, subjected
+ * to a new affine transformation.
+ *
+ * @param a The transformation to apply.
+ *
+ * @return A clone of the current font, with the specified transform.
+ *
+ * @throws IllegalArgumentException If transformation is
+ * <code>null</code>.
+ *
+ * @since 1.2
+ */
+ public Font deriveFont (AffineTransform a)
+{
+ if (a == null)
+ throw new IllegalArgumentException ("Affine transformation is null");
+
+ return peer.deriveFont (this, a);
+}
+
+/**
+ * Produces a new {@link Font} based on the current font, adjusted to a
+ * new set of attributes.
+ *
+ * @param attributes Attributes of the newly created font.
+ *
+ * @return A clone of the current font, with the specified attributes.
+ *
+ * @since 1.2
+ */
+ public Font deriveFont (Map attributes)
+{
+ return peer.deriveFont (this, attributes);
+}
+
+/**
+ * Returns a map of chracter attributes which this font currently has set.
+ *
+ * @return A map of chracter attributes which this font currently has set.
+ *
+ * @see #getAvailableAttributes()
+ * @see java.text.AttributedCharacterIterator.Attribute
+ * @see java.awt.font.TextAttribute
+ */
+ public Map getAttributes ()
+{
+ return peer.getAttributes (this);
+}
+
+/**
+ * Returns an array of chracter attribute keys which this font understands.
+ *
+ * @return An array of chracter attribute keys which this font understands.
+ *
+ * @see #getAttributes()
+ * @see java.text.AttributedCharacterIterator.Attribute
+ * @see java.awt.font.TextAttribute
+ */
+ public AttributedCharacterIterator.Attribute[] getAvailableAttributes()
+{
+ return peer.getAvailableAttributes (this);
+}
+
+/**
+ * Returns a baseline code (one of {@link #ROMAN_BASELINE}, {@link
+ * #CENTER_BASELINE} or {@link #HANGING_BASELINE}) indicating which baseline
+ * this font will measure baseline offsets for, when presenting glyph
+ * metrics for a given character.
+ *
+ * Baseline offsets describe the position of a glyph relative to an
+ * invisible line drawn under, through the center of, or over a line of
+ * rendered text, respectively. Different scripts use different baseline
+ * modes, so clients should not assume all baseline offsets in a glyph
+ * vector are from a common baseline.
+ *
+ * @param c The character code to select a baseline mode for.
+ *
+ * @return The baseline mode which would be used in a glyph associated
+ * with the provided character.
+ *
+ * @since 1.2
+ *
+ * @see LineMetrics#getBaselineOffsets()
+ */
+ public byte getBaselineFor (char c)
+{
+ return peer.getBaselineFor (this, c);
+}
+
+/**
+ * Returns the family name of this font. A family name describes a
+ * typographic style (such as Helvetica or Palatino). It is more specific
+ * than a logical font name (such as Sans Serif) but less specific than a
+ * font face name (such as Helvetica Bold).
+ *
+ * @param lc The locale in which to describe the name of the font family.
+ *
+ * @return A string containing the font family name, localized for the
+ * provided locale.
+ *
+ * @since 1.2
+ *
+ * @see #getName()
+ * @see #getFontName()
+ * @see GraphicsEnvironment#getAvailableFontFamilyNames()
+ * @see Locale
+ */
+ public String getFamily (Locale lc)
+{
+ return peer.getFamily (this, lc);
+}
+
+/**
+ * Returns a font appropriate for the given attribute set.
+ *
+ * @param attributes The attributes required for the new font.
+ *
+ * @return A new Font with the given attributes.
+ *
+ * @since 1.2
+ *
+ * @see java.awt.font.TextAttribute
+ */
+ public static Font getFont (Map attributes)
+{
+ return getFontFromToolkit (null, attributes);
+}
+
+/**
+ * Returns the font face name of the font. A font face name describes a
+ * specific variant of a font family (such as Helvetica Bold). It is more
+ * specific than both a font family name (such as Helvetica) and a logical
+ * font name (such as Sans Serif).
+ *
+ * @return The font face name of the font.
+ *
+ * @since 1.2
+ *
+ * @see #getName()
+ * @see #getFamily()
+ */
+ public String getFontName ()
+{
+ return peer.getFontName (this);
+}
+
+/**
+ * Returns the font face name of the font. A font face name describes a
+ * specific variant of a font family (such as Helvetica Bold). It is more
+ * specific than both a font family name (such as Helvetica).
+ *
+ * @param lc The locale in which to describe the name of the font face.
+ *
+ * @return A string containing the font face name, localized for the
+ * provided locale.
+ *
+ * @since 1.2
+ *
+ * @see #getName()
+ * @see #getFamily()
+ */
+ public String getFontName (Locale lc)
+{
+ return peer.getFontName (this, lc);
+}
+
+/**
+ * Returns the italic angle of this font, a measurement of its slant when
+ * style is {@link #ITALIC}. The precise meaning is the inverse slope of a
+ * caret line which "best measures" the font's italic posture.
+ *
+ * @return The italic angle.
+ *
+ * @see java.awt.font.TextAttribute#POSTURE
+ */
+ public float getItalicAngle ()
+{
+ return peer.getItalicAngle (this);
+}
+
+/**
+ * Returns a {@link LineMetrics} object constructed with the specified
+ * text and {@link FontRenderContext}.
+ *
+ * @param text The string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param rc Context for calculating precise glyph placement and hints.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>text</code>.
+ */
+ public LineMetrics getLineMetrics(String text, int begin,
+ int limit, FontRenderContext rc)
+{
+ return peer.getLineMetrics (this, new StringCharacterIterator (text),
+ begin, limit, rc);
+}
+
+/**
+ * Returns a {@link LineMetrics} object constructed with the specified
+ * text and {@link FontRenderContext}.
+ *
+ * @param chars The string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param rc Context for calculating precise glyph placement and hints.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>chars</code>.
+ */
+ public LineMetrics getLineMetrics(char[] chars, int begin,
+ int limit, FontRenderContext rc)
+{
+ return peer.getLineMetrics (this, new StringCharacterIterator (new String(chars)),
+ begin, limit, rc);
+}
+
+/**
+ * Returns a {@link LineMetrics} object constructed with the specified
+ * text and {@link FontRenderContext}.
+ *
+ * @param ci The string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param rc Context for calculating precise glyph placement and hints.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>ci</code>.
+ */
+ public LineMetrics getLineMetrics (CharacterIterator ci, int begin,
+ int limit, FontRenderContext rc)
+{
+ return peer.getLineMetrics (this, ci, begin, limit, rc);
+}
+
+/**
+ * Returns the maximal bounding box of all the bounding boxes in this
+ * font, when the font's bounding boxes are evaluated in a given {@link
+ * FontRenderContext}
+ *
+ * @param rc Context in which to evaluate bounding boxes.
+ *
+ * @return The maximal bounding box.
+ */
+ public Rectangle2D getMaxCharBounds (FontRenderContext rc)
+{
+ return peer.getMaxCharBounds (this, rc);
+}
+
+/**
+ * Returns the glyph code this font uses to represent missing glyphs. This
+ * code will be present in glyph vectors when the font was unable to
+ * locate a glyph to represent a particular character code.
+ *
+ * @return The missing glyph code.
+ *
+ * @since 1.2
+ */
+ public int getMissingGlyphCode ()
+{
+ return peer.getMissingGlyphCode (this);
+}
+
+/**
+ * Returns the overall number of glyphs in this font. This number is one
+ * more than the greatest glyph code used in any glyph vectors this font
+ * produces. In other words, glyph codes are taken from the range
+ * <code>[ 0, getNumGlyphs() - 1 ]</code>.
+ *
+ * @return The number of glyphs in this font.
+ *
+ * @since 1.2
+ */
+ public int getNumGlyphs ()
+{
+ return peer.getMissingGlyphCode (this);
+}
+
+/**
+ * Returns the PostScript Name of this font.
+ *
+ * @return The PostScript Name of this font.
+ *
+ * @since 1.2
+ *
+ * @see #getName()
+ * @see #getFamily()
+ * @see #getFontName()
+ */
+ public String getPSName ()
+{
+ return peer.getPostScriptName (this);
+}
+
+/**
+ * Returns the logical bounds of the specified string when rendered with this
+ * font in the specified {@link FontRenderContext}. This box will include the
+ * glyph origin, ascent, advance, height, and leading, but may not include all
+ * diacritics or accents. To get the complete visual bounding box of all the
+ * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
+ * {@link TextLayout}.
+ *
+ * @param str The string to measure.
+ * @param frc The context in which to make the precise glyph measurements.
+ *
+ * @return A bounding box covering the logical bounds of the specified text.
+ *
+ * @see #createGlyphVector(FontRenderContext, String)
+ */
+ public Rectangle2D getStringBounds (String str, FontRenderContext frc)
+{
+ return getStringBounds (str, 0, str.length () - 1, frc);
+}
+
+/**
+ * Returns the logical bounds of the specified string when rendered with this
+ * font in the specified {@link FontRenderContext}. This box will include the
+ * glyph origin, ascent, advance, height, and leading, but may not include all
+ * diacritics or accents. To get the complete visual bounding box of all the
+ * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
+ * {@link TextLayout}.
+ *
+ * @param str The string to measure.
+ * @param begin Index of the first character in <code>str</code> to measure.
+ * @param limit Index of the last character in <code>str</code> to measure.
+ * @param frc The context in which to make the precise glyph measurements.
+ *
+ * @return A bounding box covering the logical bounds of the specified text.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>str</code>.
+ *
+ * @since 1.2
+ *
+ * @see #createGlyphVector(FontRenderContext, String)
+ */
+ public Rectangle2D getStringBounds (String str, int begin,
+ int limit, FontRenderContext frc)
+{
+ return peer.getStringBounds (this, new StringCharacterIterator(str), begin, limit, frc);
+}
+
+/**
+ * Returns the logical bounds of the specified string when rendered with this
+ * font in the specified {@link FontRenderContext}. This box will include the
+ * glyph origin, ascent, advance, height, and leading, but may not include all
+ * diacritics or accents. To get the complete visual bounding box of all the
+ * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
+ * {@link TextLayout}.
+ *
+ * @param ci The text to measure.
+ * @param begin Index of the first character in <code>ci</code> to measure.
+ * @param limit Index of the last character in <code>ci</code> to measure.
+ * @param frc The context in which to make the precise glyph measurements.
+ *
+ * @return A bounding box covering the logical bounds of the specified text.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>ci</code>.
+ *
+ * @since 1.2
+ *
+ * @see #createGlyphVector(FontRenderContext, CharacterIterator)
+ */
+ public Rectangle2D getStringBounds (CharacterIterator ci, int begin,
+ int limit, FontRenderContext frc)
+{
+ return peer.getStringBounds (this, ci, begin, limit, frc);
+}
+
+/**
+ * Returns the logical bounds of the specified string when rendered with this
+ * font in the specified {@link FontRenderContext}. This box will include the
+ * glyph origin, ascent, advance, height, and leading, but may not include all
+ * diacritics or accents. To get the complete visual bounding box of all the
+ * glyphs in a run of text, use the {@link TextLayout#getBounds} method of
+ * {@link TextLayout}.
+ *
+ * @param chars The text to measure.
+ * @param begin Index of the first character in <code>ci</code> to measure.
+ * @param limit Index of the last character in <code>ci</code> to measure.
+ * @param frc The context in which to make the precise glyph measurements.
+ *
+ * @return A bounding box covering the logical bounds of the specified text.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>chars</code>.
+ *
+ * @since 1.2
+ *
+ * @see #createGlyphVector(FontRenderContext, char[])
+ */
+ public Rectangle2D getStringBounds (char[] chars, int begin,
+ int limit, FontRenderContext frc)
+{
+ return peer.getStringBounds (this, new StringCharacterIterator (new String (chars)),
+ begin, limit, frc);
+}
+
+/**
+ * Returns a copy of the affine transformation this font is currently
+ * subject to, if any.
+ *
+ * @return The current transformation.
+ */
+ public AffineTransform getTransform ()
+{
+ return peer.getTransform (this);
+}
+
+/**
+ * Indicates whether this font's line metrics are uniform. A font may be
+ * composed of several "subfonts", each covering a different code range,
+ * and each with their own line metrics. A font with no subfonts, or
+ * subfonts with identical line metrics, is said to have "uniform" line
+ * metrics.
+ *
+ * @return Whether this font has uniform line metrics.
+ *
+ * @see LineMetrics
+ * @see #getLineMetrics(String, FontRenderContext)
+ */
+ public boolean hasUniformLineMetrics ()
+{
+ return peer.hasUniformLineMetrics (this);
+}
+
+/**
+ * Indicates whether this font is subject to a non-identity affine
+ * transformation.
+ *
+ * @return <code>true</code> iff the font has a non-identity affine
+ * transformation applied to it.
+ */
+ public boolean isTransformed ()
+{
+ return peer.isTransformed (this);
+}
+
+/**
+ * Produces a glyph vector representing a full layout fo the specified
+ * text in this font. Full layouts may include complex shaping and
+ * reordering operations, for scripts such as Arabic or Hindi.
+ *
+ * Bidirectional (bidi) layout is not performed in this method; text
+ * should have its bidi direction specified with one of the flags {@link
+ * #LAYOUT_LEFT_TO_RIGHT} or {@link #LAYOUT_RIGHT_TO_LEFT}.
+ *
+ * Some types of layout (notably Arabic glyph shaping) may examine context
+ * characters beyond the bounds of the indicated range, in order to select
+ * an appropriate shape. The flags {@link #LAYOUT_NO_START_CONTEXT} and
+ * {@link #LAYOUT_NO_LIMIT_CONTEXT} can be provided to prevent these extra
+ * context areas from being examined, for instance if they contain invalid
+ * characters.
+ *
+ * @param frc Context in which to perform the layout.
+ * @param chars Text to perform layout on.
+ * @param start Index of first character to perform layout on.
+ * @param limit Index of last character to perform layout on.
+ * @param flags Combination of flags controlling layout.
+ *
+ * @return A new {@link GlyphVector} representing the specified text.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>chars</code>.
+ */
+ public GlyphVector layoutGlyphVector (FontRenderContext frc,
+ char[] chars, int start,
+ int limit, int flags)
+{
+ return peer.layoutGlyphVector (this, frc, chars, start, limit, flags);
+}
+
+
+/**
+ * Returns a native peer object for this font.
+ *
+ * @return A native peer object for this font.
+ *
+ * @deprecated
+ */
+ public FontPeer getPeer ()
+{
+ return peer;
+}
+
+
+/**
+ * Returns a hash value for this font.
+ *
+ * @return A hash for this font.
+ */
+ public int hashCode()
+{
+ return this.toString().hashCode();
+}
+
+
+/**
+ * Tests whether or not the specified object is equal to this font. This
+ * will be true if and only if:
+ * <P>
+ * <ul>
+ * <li>The object is not <code>null</code>.
+ * <li>The object is an instance of <code>Font</code>.
+ * <li>The object has the same names, style, size, and transform as this object.
+ * </ul>
+ *
+ * @return <code>true</code> if the specified object is equal to this
+ * object, <code>false</code> otherwise.
+ */
+public boolean
+equals(Object obj)
+{
+ if (obj == null)
+ return(false);
+
+ if (!(obj instanceof Font))
+ return(false);
+
+ Font f = (Font)obj;
+
+ return (f.getName ().equals (this.getName ()) &&
+ f.getFamily ().equals (this.getFamily ()) &&
+ f.getFontName ().equals (this.getFontName ()) &&
+ f.getTransform ().equals (this.getTransform ()) &&
+ f.getSize() == this.getSize() &&
+ f.getStyle() == this.getStyle());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a string representation of this font.
+ *
+ * @return A string representation of this font.
+ */
+public String
+toString()
+{
+ String styleString = "";
+
+ switch (getStyle ())
+ {
+ case 0:
+ styleString = "plain";
+ break;
+ case 1:
+ styleString = "bold";
+ break;
+ case 2:
+ styleString = "italic";
+ break;
+ default:
+ styleString = "unknown";
+ }
+
+ return getClass ().getName ()
+ + "[family=" + getFamily ()
+ + ",name=" + getFontName ()
+ + ",style=" + styleString
+ + ",size=" + getSize () + "]";
+}
+
+
+ /**
+ * Determines the line metrics for a run of text.
+ *
+ * @param str the text run to be measured.
+ *
+ * @param frc the font rendering parameters that are used for the
+ * measurement. The exact placement and size of text slightly
+ * depends on device-specific characteristics, for instance
+ * the device resolution or anti-aliasing. For this reason,
+ * the returned measurement will only be accurate if the
+ * passed <code>FontRenderContext</code> correctly reflects
+ * the relevant parameters. Hence, <code>frc</code> should be
+ * obtained from the same <code>Graphics2D</code> that will
+ * be used for drawing, and any rendering hints should be set
+ * to the desired values before obtaining <code>frc</code>.
+ *
+ * @see java.awt.Graphics2D#getFontRenderContext()
+ */
+ public LineMetrics getLineMetrics(String str, FontRenderContext frc)
+ {
+ return getLineMetrics (str, 0, str.length () - 1, frc);
+ }
+
+} // class Font
+
diff --git a/libjava/classpath/java/awt/FontFormatException.java b/libjava/classpath/java/awt/FontFormatException.java
new file mode 100644
index 0000000..6ec8757
--- /dev/null
+++ b/libjava/classpath/java/awt/FontFormatException.java
@@ -0,0 +1,65 @@
+/* FontFormatException.java -- the specified font is bad
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * Thrown when a specified font is bad.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Font
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public class FontFormatException extends Exception
+{
+ /**
+ * Compatible with JDK 1.4+.
+ */
+ private static final long serialVersionUID = -4481290147811361272L;
+
+ /**
+ * Create a new instance with the specified detailed error message.
+ *
+ * @param message the detailed error message
+ */
+ public FontFormatException(String message)
+ {
+ super(message);
+ }
+} // class FontFormatException
diff --git a/libjava/classpath/java/awt/FontMetrics.java b/libjava/classpath/java/awt/FontMetrics.java
new file mode 100644
index 0000000..e702a62
--- /dev/null
+++ b/libjava/classpath/java/awt/FontMetrics.java
@@ -0,0 +1,425 @@
+/* FontMetrics.java -- Information about about a fonts display characteristics
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.Rectangle2D;
+import java.text.CharacterIterator;
+
+// FIXME: I leave many methods basically unimplemented. This
+// should be reviewed.
+
+/**
+ * This class returns information about the display characteristics of
+ * a font. It is abstract, and concrete subclasses should implement at
+ * least the following methods:
+ *
+ * <ul>
+ * <li>getAscent()</li>
+ * <li>getDescent()</li>
+ * <li>getLeading()</li>
+ * <li>getMaxAdvance()</li>
+ * <li>charWidth(char)</li>
+ * <li>charsWidth(char[], int, int)</li>
+ * </ul>
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract class FontMetrics implements java.io.Serializable
+{
+ // Serialization constant.
+ private static final long serialVersionUID = 1681126225205050147L;
+
+ /**
+ * This is the font for which metrics will be returned.
+ */
+ protected Font font;
+
+ /**
+ * Initializes a new instance of <code>FontMetrics</code> for the
+ * specified font.
+ *
+ * @param font The font to return metric information for.
+ */
+ protected FontMetrics(Font font)
+ {
+ this.font = font;
+ }
+
+ /**
+ * Returns the font that this object is creating metric information fo.
+ *
+ * @return The font for this object.
+ */
+ public Font getFont()
+ {
+ return font;
+ }
+
+ /**
+ * Returns the leading, or spacing between lines, for this font.
+ *
+ * @return The font leading.
+ */
+ public int getLeading()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the ascent of the font, which is the distance from the base
+ * to the top of the majority of characters in the set. Some characters
+ * can exceed this value however.
+ *
+ * @return The font ascent.
+ */
+ public int getAscent()
+ {
+ return 1;
+ }
+
+ /**
+ * Returns the descent of the font, which is the distance from the base
+ * to the bottom of the majority of characters in the set. Some characters
+ * can exceed this value however.
+ *
+ * @return The font descent.
+ */
+ public int getDescent()
+ {
+ return 1;
+ }
+
+ /**
+ * Returns the height of a line in this font. This will be the sum
+ * of the leading, the ascent, and the descent.
+ *
+ * @return The height of the font.
+ */
+ public int getHeight()
+ {
+ return getAscent() + getDescent() + getLeading();
+ }
+
+ /**
+ * Returns the maximum ascent value. This is the maximum distance any
+ * character in the font rised above the baseline.
+ *
+ * @return The maximum ascent for this font.
+ */
+ public int getMaxAscent()
+ {
+ return getAscent();
+ }
+
+ /**
+ * Returns the maximum descent value. This is the maximum distance any
+ * character in the font extends below the baseline.
+ *
+ * @return The maximum descent for this font.
+ */
+ public int getMaxDescent()
+ {
+ return getMaxDecent();
+ }
+
+ /**
+ * Returns the maximum descent value. This is the maximum distance any
+ * character in the font extends below the baseline.
+ *
+ * @return The maximum descent for this font.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMaxDescent()</code>.
+ */
+ public int getMaxDecent()
+ {
+ return getDescent();
+ }
+
+ /**
+ * Returns the width of the widest character in the font.
+ *
+ * @return The width of the widest character in the font.
+ */
+ public int getMaxAdvance()
+ {
+ return -1;
+ }
+
+ /**
+ * Returns the width of the specified character.
+ *
+ * @param ch The character to return the width of.
+ *
+ * @return The width of the specified character.
+ */
+ public int charWidth(int ch)
+ {
+ return charWidth((char) ch);
+ }
+
+ /**
+ * Returns the width of the specified character.
+ *
+ * @param ch The character to return the width of.
+ *
+ * @return The width of the specified character.
+ */
+ public int charWidth(char ch)
+ {
+ return 1;
+ }
+
+ /**
+ * Returns the total width of the specified string
+ *
+ * @param str The string to return the width of.
+ *
+ * @return The width of the string.
+ */
+ public int stringWidth(String str)
+ {
+ char[] buf = new char[str.length()];
+ str.getChars(0, str.length(), buf, 0);
+
+ return charsWidth(buf, 0, buf.length);
+ }
+
+ /**
+ * Returns the total width of the specified character array.
+ *
+ * @param buf The character array containing the data.
+ * @param offset The offset into the array to start calculating from.
+ * @param len The total number of bytes to process.
+ *
+ * @return The width of the requested characters.
+ */
+ public int charsWidth(char[] buf, int offset, int len)
+ {
+ int total_width = 0;
+ for (int i = offset; i < len; i++)
+ total_width += charWidth(buf[i]);
+ return total_width;
+ }
+
+ /**
+ * Returns the total width of the specified byte array.
+ *
+ * @param buf The byte array containing the data.
+ * @param offset The offset into the array to start calculating from.
+ * @param len The total number of bytes to process.
+ *
+ * @return The width of the requested characters.
+ */
+ public int bytesWidth(byte[] buf, int offset, int len)
+ {
+ int total_width = 0;
+ for (int i = offset; i < len; i++)
+ total_width = charWidth((char) buf[i]);
+
+ return total_width;
+ }
+
+ /**
+ * Returns the widths of the first 256 characters in the font.
+ *
+ * @return The widths of the first 256 characters in the font.
+ */
+ public int[] getWidths()
+ {
+ int[] result = new int[256];
+ for (char i = 0; i < 256; i++)
+ result[i] = charWidth(i);
+ return result;
+ }
+
+ /**
+ * Returns a string representation of this object.
+ *
+ * @return A string representation of this object.
+ */
+ public String toString()
+ {
+ return (this.getClass() + "[font=" + font + ",ascent=" + getAscent()
+ + ",descent=" + getDescent() + ",height=" + getHeight() + "]");
+ }
+
+ // Generic FontRenderContext used when getLineMetrics is called with a
+ // plain Graphics object.
+ private static final FontRenderContext gRC = new FontRenderContext(null,
+ false,
+ false);
+
+ /**
+ * Returns a {@link LineMetrics} object constructed with the
+ * specified text and the {@link FontRenderContext} of the Graphics
+ * object when it is an instance of Graphics2D or a generic
+ * FontRenderContext with a null transform, not anti-aliased and not
+ * using fractional metrics.
+ *
+ * @param text The string to calculate metrics from.
+ * @param g The Graphics object that will be used.
+ *
+ * @return A new {@link LineMetrics} object.
+ */
+ public LineMetrics getLineMetrics(String text, Graphics g)
+ {
+ return getLineMetrics(text, 0, text.length(), g);
+ }
+
+ /**
+ * Returns a {@link LineMetrics} object constructed with the
+ * specified text and the {@link FontRenderContext} of the Graphics
+ * object when it is an instance of Graphics2D or a generic
+ * FontRenderContext with a null transform, not anti-aliased and not
+ * using fractional metrics.
+ *
+ * @param text The string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param g The Graphics object that will be used.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>text</code>.
+ */
+ public LineMetrics getLineMetrics(String text, int begin, int limit,
+ Graphics g)
+ {
+ FontRenderContext rc;
+ if (g instanceof Graphics2D)
+ rc = ((Graphics2D) g).getFontRenderContext();
+ else
+ rc = gRC;
+ return font.getLineMetrics(text, begin, limit, rc);
+ }
+
+ /**
+ * Returns a {@link LineMetrics} object constructed with the
+ * specified text and the {@link FontRenderContext} of the Graphics
+ * object when it is an instance of Graphics2D or a generic
+ * FontRenderContext with a null transform, not anti-aliased and not
+ * using fractional metrics.
+ *
+ * @param chars The string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param g The Graphics object that will be used.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>text</code>.
+ */
+ public LineMetrics getLineMetrics(char[] chars, int begin, int limit,
+ Graphics g)
+ {
+ FontRenderContext rc;
+ if (g instanceof Graphics2D)
+ rc = ((Graphics2D) g).getFontRenderContext();
+ else
+ rc = gRC;
+ return font.getLineMetrics(chars, begin, limit, rc);
+ }
+
+ /**
+ * Returns a {@link LineMetrics} object constructed with the
+ * specified text and the {@link FontRenderContext} of the Graphics
+ * object when it is an instance of Graphics2D or a generic
+ * FontRenderContext with a null transform, not anti-aliased and not
+ * using fractional metrics.
+ *
+ * @param ci An iterator over the string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param g The Graphics object that will be used.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>text</code>.
+ */
+ public LineMetrics getLineMetrics(CharacterIterator ci, int begin,
+ int limit, Graphics g)
+ {
+ FontRenderContext rc;
+ if (g instanceof Graphics2D)
+ rc = ((Graphics2D) g).getFontRenderContext();
+ else
+ rc = gRC;
+ return font.getLineMetrics(ci, begin, limit, rc);
+ }
+
+ public Rectangle2D getStringBounds(String str, Graphics context)
+ {
+ return font.getStringBounds(str, getFontRenderContext(context));
+ }
+
+ public Rectangle2D getStringBounds(String str, int beginIndex, int limit,
+ Graphics context)
+ {
+ return font.getStringBounds(str, beginIndex, limit,
+ getFontRenderContext(context));
+ }
+
+ public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit,
+ Graphics context)
+ {
+ return font.getStringBounds(chars, beginIndex, limit,
+ getFontRenderContext(context));
+ }
+
+ public Rectangle2D getStringBounds(CharacterIterator ci, int beginIndex,
+ int limit, Graphics context)
+ {
+ return font.getStringBounds(ci, beginIndex, limit,
+ getFontRenderContext(context));
+ }
+
+ private FontRenderContext getFontRenderContext(Graphics context)
+ {
+ if (context instanceof Graphics2D)
+ return ((Graphics2D) context).getFontRenderContext();
+
+ return gRC;
+ }
+}
diff --git a/libjava/classpath/java/awt/Frame.java b/libjava/classpath/java/awt/Frame.java
new file mode 100644
index 0000000..0cb97f8
--- /dev/null
+++ b/libjava/classpath/java/awt/Frame.java
@@ -0,0 +1,649 @@
+/* Frame.java -- AWT toplevel window
+ Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.peer.FramePeer;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+
+/**
+ * This class is a top-level window with a title bar and window
+ * decorations.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class Frame extends Window implements MenuContainer
+{
+/**
+ * Constant for the default cursor.
+ * @deprecated Replaced by <code>Cursor.DEFAULT_CURSOR</code> instead.
+ */
+public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR;
+
+/**
+ * Constant for a cross-hair cursor.
+ * @deprecated Use <code>Cursor.CROSSHAIR_CURSOR</code> instead.
+ */
+public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR;
+
+/**
+ * Constant for a cursor over a text field.
+ * @deprecated Use <code>Cursor.TEXT_CURSOR</code> instead.
+ */
+public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR;
+
+/**
+ * Constant for a cursor to display while waiting for an action to complete.
+ * @deprecated Use <code>Cursor.WAIT_CURSOR</code>.
+ */
+public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR;
+
+/**
+ * Cursor used over SW corner of window decorations.
+ * @deprecated Use <code>Cursor.SW_RESIZE_CURSOR</code> instead.
+ */
+public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR;
+
+/**
+ * Cursor used over SE corner of window decorations.
+ * @deprecated Use <code>Cursor.SE_RESIZE_CURSOR</code> instead.
+ */
+public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR;
+
+/**
+ * Cursor used over NW corner of window decorations.
+ * @deprecated Use <code>Cursor.NW_RESIZE_CURSOR</code> instead.
+ */
+public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR;
+
+/**
+ * Cursor used over NE corner of window decorations.
+ * @deprecated Use <code>Cursor.NE_RESIZE_CURSOR</code> instead.
+ */
+public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR;
+
+/**
+ * Cursor used over N edge of window decorations.
+ * @deprecated Use <code>Cursor.N_RESIZE_CURSOR</code> instead.
+ */
+public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR;
+
+/**
+ * Cursor used over S edge of window decorations.
+ * @deprecated Use <code>Cursor.S_RESIZE_CURSOR</code> instead.
+ */
+public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR;
+
+/**
+ * Cursor used over E edge of window decorations.
+ * @deprecated Use <code>Cursor.E_RESIZE_CURSOR</code> instead.
+ */
+public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR;
+
+/**
+ * Cursor used over W edge of window decorations.
+ * @deprecated Use <code>Cursor.W_RESIZE_CURSOR</code> instead.
+ */
+public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR;
+
+/**
+ * Constant for a hand cursor.
+ * @deprecated Use <code>Cursor.HAND_CURSOR</code> instead.
+ */
+public static final int HAND_CURSOR = Cursor.HAND_CURSOR;
+
+/**
+ * Constant for a cursor used during window move operations.
+ * @deprecated Use <code>Cursor.MOVE_CURSOR</code> instead.
+ */
+public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR;
+
+public static final int ICONIFIED = 1;
+public static final int MAXIMIZED_BOTH = 6;
+public static final int MAXIMIZED_HORIZ = 2;
+public static final int MAXIMIZED_VERT = 4;
+public static final int NORMAL = 0;
+
+// Serialization version constant
+private static final long serialVersionUID = 2673458971256075116L;
+
+/**
+ * @serial The version of the class data being serialized
+ * // FIXME: what is this value?
+ */
+private int frameSerializedDataVersion;
+
+/**
+ * @serial Image used as the icon when this frame is minimized.
+ */
+private Image icon;
+
+/**
+ * @serial Constant used by the JDK Motif peer set. Not used in
+ * this implementation.
+ */
+private boolean mbManagement;
+
+/**
+ * @serial The menu bar for this frame.
+ */
+//private MenuBar menuBar = new MenuBar();
+private MenuBar menuBar;
+
+/**
+ * @serial A list of other top-level windows owned by this window.
+ */
+Vector ownedWindows = new Vector();
+
+/**
+ * @serial Indicates whether or not this frame is resizable.
+ */
+private boolean resizable = true;
+
+/**
+ * @serial The state of this frame.
+ * // FIXME: What are the values here?
+ * This is package-private to avoid an accessor method.
+ */
+int state;
+
+/**
+ * @serial The title of the frame.
+ */
+private String title = "";
+
+ /**
+ * Maximized bounds for this frame.
+ */
+ private Rectangle maximizedBounds;
+
+ /**
+ * This field indicates whether the frame is undecorated or not.
+ */
+ private boolean undecorated = false;
+
+ /*
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_frame_number;
+
+/**
+ * Initializes a new instance of <code>Frame</code> that is not visible
+ * and has no title.
+ */
+public
+Frame()
+{
+ this("");
+ noteFrame(this);
+}
+
+/**
+ * Initializes a new instance of <code>Frame</code> that is not visible
+ * and has the specified title.
+ *
+ * @param title The title of this frame.
+ */
+public
+Frame(String title)
+{
+ super();
+ this.title = title;
+ // Top-level frames are initially invisible.
+ visible = false;
+ noteFrame(this);
+}
+
+public
+Frame(GraphicsConfiguration gc)
+{
+ super(gc);
+ visible = false;
+ noteFrame(this);
+}
+
+public
+Frame(String title, GraphicsConfiguration gc)
+{
+ super(gc);
+ setTitle(title);
+ visible = false;
+ noteFrame(this);
+}
+
+/**
+ * Returns this frame's title string.
+ *
+ * @return This frame's title string.
+ */
+public String
+getTitle()
+{
+ return(title);
+}
+
+/*
+ * Sets this frame's title to the specified value.
+ *
+ * @param title The new frame title.
+ */
+public synchronized void
+setTitle(String title)
+{
+ this.title = title;
+ if (peer != null)
+ ((FramePeer) peer).setTitle(title);
+}
+
+/**
+ * Returns this frame's icon.
+ *
+ * @return This frame's icon, or <code>null</code> if this frame does not
+ * have an icon.
+ */
+public Image
+getIconImage()
+{
+ return(icon);
+}
+
+/**
+ * Sets this frame's icon to the specified value.
+ *
+ * @icon The new icon for this frame.
+ */
+public synchronized void
+setIconImage(Image icon)
+{
+ this.icon = icon;
+ if (peer != null)
+ ((FramePeer) peer).setIconImage(icon);
+}
+
+/**
+ * Returns this frame's menu bar.
+ *
+ * @return This frame's menu bar, or <code>null</code> if this frame
+ * does not have a menu bar.
+ */
+public MenuBar
+getMenuBar()
+{
+ return(menuBar);
+}
+
+/**
+ * Sets this frame's menu bar.
+ *
+ * @param menuBar The new menu bar for this frame.
+ */
+public synchronized void
+setMenuBar(MenuBar menuBar)
+{
+ if (peer != null)
+ {
+ if (this.menuBar != null)
+ this.menuBar.removeNotify();
+ if (menuBar != null)
+ menuBar.addNotify();
+ invalidateTree ();
+ ((FramePeer) peer).setMenuBar(menuBar);
+ }
+ this.menuBar = menuBar;
+}
+
+/**
+ * Tests whether or not this frame is resizable. This will be
+ * <code>true</code> by default.
+ *
+ * @return <code>true</code> if this frame is resizable, <code>false</code>
+ * otherwise.
+ */
+public boolean
+isResizable()
+{
+ return(resizable);
+}
+
+/**
+ * Sets the resizability of this frame to the specified value.
+ *
+ * @param resizable <code>true</code> to make the frame resizable,
+ * <code>false</code> to make it non-resizable.
+ */
+public synchronized void
+setResizable(boolean resizable)
+{
+ this.resizable = resizable;
+ if (peer != null)
+ ((FramePeer) peer).setResizable(resizable);
+}
+
+/**
+ * Returns the cursor type of the cursor for this window. This will
+ * be one of the constants in this class.
+ *
+ * @return The cursor type for this frame.
+ *
+ * @deprecated Use <code>Component.getCursor()</code> instead.
+ */
+public int
+getCursorType()
+{
+ return(getCursor().getType());
+}
+
+/**
+ * Sets the cursor for this window to the specified type. The specified
+ * type should be one of the constants in this class.
+ *
+ * @param type The cursor type.
+ *
+ * @deprecated Use <code>Component.setCursor(Cursor)</code> instead.
+ */
+public void
+setCursor(int type)
+{
+ setCursor(new Cursor(type));
+}
+
+/**
+ * Removes the specified component from this frame's menu.
+ *
+ * @param menu The menu component to remove.
+ */
+public void
+remove(MenuComponent menu)
+{
+ menuBar.remove(menu);
+}
+
+/**
+ * Notifies this frame that it should create its native peer.
+ */
+private static void fireDummyEvent()
+{
+ EventQueue.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ // Do nothing here.
+ }
+ });
+}
+
+public void
+addNotify()
+{
+ if (menuBar != null)
+ menuBar.addNotify();
+ if (peer == null)
+ peer = getToolkit ().createFrame (this);
+
+ // We now know there's a Frame (us) with a live peer, so we can start the
+ // fundamental queue and dispatch thread, by inserting a dummy event.
+ if (parent != null && parent.isDisplayable())
+ fireDummyEvent();
+
+ super.addNotify();
+}
+
+public void removeNotify()
+{
+ if (menuBar != null)
+ menuBar.removeNotify();
+ super.removeNotify();
+
+ // By now we've been disconnected from the peer, and the peer set to
+ // null. This is formally the same as saying "we just became
+ // un-displayable", so we wake up the event queue with a dummy event to
+ // see if it's time to shut down.
+ fireDummyEvent();
+}
+
+ /**
+ * Returns a debugging string describing this window.
+ *
+ * @return A debugging string describing this window.
+ */
+ protected String paramString ()
+ {
+ String title = getTitle ();
+
+ String resizable = "";
+ if (isResizable ())
+ resizable = ",resizable";
+
+ String state = "";
+ switch (getState ())
+ {
+ case NORMAL:
+ state = ",normal";
+ break;
+ case ICONIFIED:
+ state = ",iconified";
+ break;
+ case MAXIMIZED_BOTH:
+ state = ",maximized-both";
+ break;
+ case MAXIMIZED_HORIZ:
+ state = ",maximized-horiz";
+ break;
+ case MAXIMIZED_VERT:
+ state = ",maximized-vert";
+ break;
+ }
+
+ return super.paramString () + ",title=" + title + resizable + state;
+ }
+
+private static ArrayList weakFrames = new ArrayList();
+
+private static void noteFrame(Frame f)
+{
+ weakFrames.add(new WeakReference(f));
+}
+
+public static Frame[] getFrames()
+{
+ int n = 0;
+ synchronized (weakFrames)
+ {
+ Iterator i = weakFrames.iterator();
+ while (i.hasNext())
+ {
+ WeakReference wr = (WeakReference) i.next();
+ if (wr.get() != null)
+ ++n;
+ }
+ if (n == 0)
+ return new Frame[0];
+ else
+ {
+ Frame[] frames = new Frame[n];
+ n = 0;
+ i = weakFrames.iterator();
+ while (i.hasNext())
+ {
+ WeakReference wr = (WeakReference) i.next();
+ if (wr.get() != null)
+ frames[n++] = (Frame) wr.get();
+ }
+ return frames;
+ }
+ }
+}
+
+ public void setState (int state)
+ {
+ int current_state = getExtendedState ();
+
+ if (state == NORMAL
+ && (current_state & ICONIFIED) != 0)
+ setExtendedState (current_state | ICONIFIED);
+
+ if (state == ICONIFIED
+ && (current_state & ~ICONIFIED) == 0)
+ setExtendedState (current_state & ~ICONIFIED);
+ }
+
+ public int getState ()
+ {
+ /* FIXME: State might have changed in the peer... Must check. */
+
+ return (state & ICONIFIED) != 0 ? ICONIFIED : NORMAL;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void setExtendedState (int state)
+ {
+ this.state = state;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public int getExtendedState ()
+ {
+ return state;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void setMaximizedBounds (Rectangle maximizedBounds)
+ {
+ this.maximizedBounds = maximizedBounds;
+ }
+
+ /**
+ * Returns the maximized bounds of this frame.
+ *
+ * @return the maximized rectangle, may be null.
+ *
+ * @since 1.4
+ */
+ public Rectangle getMaximizedBounds ()
+ {
+ return maximizedBounds;
+ }
+
+ /**
+ * Returns whether this frame is undecorated or not.
+ *
+ * @since 1.4
+ */
+ public boolean isUndecorated ()
+ {
+ return undecorated;
+ }
+
+ /**
+ * Disables or enables decorations for this frame. This method can only be
+ * called while the frame is not displayable.
+ *
+ * @exception IllegalComponentStateException If this frame is displayable.
+ *
+ * @since 1.4
+ */
+ public void setUndecorated (boolean undecorated)
+ {
+ if (isDisplayable ())
+ throw new IllegalComponentStateException ();
+
+ this.undecorated = undecorated;
+ }
+
+ /**
+ * Generate a unique name for this frame.
+ *
+ * @return A unique name for this frame.
+ */
+ String generateName ()
+ {
+ return "frame" + getUniqueLong ();
+ }
+
+ private static synchronized long getUniqueLong ()
+ {
+ return next_frame_number++;
+ }
+
+ protected class AccessibleAWTFrame extends AccessibleAWTWindow
+ {
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.FRAME;
+ }
+
+ public AccessibleStateSet getAccessibleState()
+ {
+ AccessibleStateSet states = super.getAccessibleStateSet();
+ if (isResizable())
+ states.add(AccessibleState.RESIZABLE);
+ if ((state & ICONIFIED) != 0)
+ states.add(AccessibleState.ICONIFIED);
+ return states;
+ }
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>Frame</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTFrame();
+ return accessibleContext;
+ }
+
+}
diff --git a/libjava/classpath/java/awt/GradientPaint.java b/libjava/classpath/java/awt/GradientPaint.java
new file mode 100644
index 0000000..74067f4
--- /dev/null
+++ b/libjava/classpath/java/awt/GradientPaint.java
@@ -0,0 +1,229 @@
+/* GradientPaint.java --
+ Copyright (C) 2002, 2005, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import gnu.java.awt.GradientPaintContext;
+
+/**
+ * A paint object that can be used to color a region by blending two colors.
+ * Instances of this class are immutable.
+ */
+public class GradientPaint implements Paint
+{
+ private final float x1;
+ private final float y1;
+ private final Color c1;
+ private final float x2;
+ private final float y2;
+ private final Color c2;
+ private final boolean cyclic;
+
+ /**
+ * Creates a new acyclic <code>GradientPaint</code>.
+ *
+ * @param x1 the x-coordinate of the anchor point for color 1.
+ * @param y1 the y-coordinate of the anchor point for color 1.
+ * @param c1 color 1 (<code>null</code> not permitted).
+ * @param x2 the x-coordinate of the anchor point for color 2.
+ * @param y2 the y-coordinate of the anchor point for color 2.
+ * @param c2 the second color (<code>null</code> not permitted).
+ */
+ public GradientPaint(float x1, float y1, Color c1,
+ float x2, float y2, Color c2)
+ {
+ this(x1, y1, c1, x2, y2, c2, false);
+ }
+
+ /**
+ * Creates a new acyclic <code>GradientPaint</code>.
+ *
+ * @param p1 anchor point 1 (<code>null</code> not permitted).
+ * @param c1 color 1 (<code>null</code> not permitted).
+ * @param p2 anchor point 2 (<code>null</code> not permitted).
+ * @param c2 color 2 (<code>null</code> not permitted).
+ */
+ public GradientPaint(Point2D p1, Color c1, Point2D p2, Color c2)
+ {
+ this((float) p1.getX(), (float) p1.getY(), c1,
+ (float) p2.getX(), (float) p2.getY(), c2, false);
+ }
+
+ /**
+ * Creates a new cyclic or acyclic <code>GradientPaint</code>.
+ *
+ * @param x1 the x-coordinate of the anchor point for color 1.
+ * @param y1 the y-coordinate of the anchor point for color 1.
+ * @param c1 color 1 (<code>null</code> not permitted).
+ * @param x2 the x-coordinate of the anchor point for color 2.
+ * @param y2 the y-coordinate of the anchor point for color 2.
+ * @param c2 the second color (<code>null</code> not permitted).
+ * @param cyclic a flag that controls whether the gradient is cyclic or
+ * acyclic.
+ */
+ public GradientPaint(float x1, float y1, Color c1,
+ float x2, float y2, Color c2, boolean cyclic)
+ {
+ if (c1 == null || c2 == null)
+ throw new NullPointerException();
+ this.x1 = x1;
+ this.y1 = y1;
+ this.c1 = c1;
+ this.x2 = x2;
+ this.y2 = y2;
+ this.c2 = c2;
+ this.cyclic = cyclic;
+ }
+
+ /**
+ * Creates a new cyclic or acyclic <code>GradientPaint</code>.
+ *
+ * @param p1 anchor point 1 (<code>null</code> not permitted).
+ * @param c1 color 1 (<code>null</code> not permitted).
+ * @param p2 anchor point 2 (<code>null</code> not permitted).
+ * @param c2 color 2 (<code>null</code> not permitted).
+ * @param cyclic a flag that controls whether the gradient is cyclic or
+ * acyclic.
+ */
+ public GradientPaint(Point2D p1, Color c1, Point2D p2, Color c2,
+ boolean cyclic)
+ {
+ this((float) p1.getX(), (float) p1.getY(), c1,
+ (float) p2.getX(), (float) p2.getY(), c2, cyclic);
+ }
+
+ /**
+ * Returns a point with the same coordinates as the anchor point for color 1.
+ * Note that if you modify this point, the <code>GradientPaint</code> remains
+ * unchanged.
+ *
+ * @return A point with the same coordinates as the anchor point for color 1.
+ */
+ public Point2D getPoint1()
+ {
+ return new Point2D.Float(x1, y1);
+ }
+
+ /**
+ * Returns the first color.
+ *
+ * @return The color (never <code>null</code>).
+ */
+ public Color getColor1()
+ {
+ return c1;
+ }
+
+ /**
+ * Returns a point with the same coordinates as the anchor point for color 2.
+ * Note that if you modify this point, the <code>GradientPaint</code> remains
+ * unchanged.
+ *
+ * @return A point with the same coordinates as the anchor point for color 2.
+ */
+ public Point2D getPoint2()
+ {
+ return new Point2D.Float(x2, y2);
+ }
+
+ /**
+ * Returns the second color.
+ *
+ * @return The color (never <code>null</code>).
+ */
+ public Color getColor2()
+ {
+ return c2;
+ }
+
+ /**
+ * Returns <code>true</code> if this <code>GradientPaint</code> instance is
+ * cyclic, and <code>false</code> otherwise.
+ *
+ * @return A boolean.
+ */
+ public boolean isCyclic()
+ {
+ return cyclic;
+ }
+
+ /**
+ * Returns the {@link PaintContext} used to generate the color pattern.
+ *
+ * @param cm the color model, used as a hint (ignored in this
+ * implementation).
+ * @param deviceBounds the device space bounding box of the painted area.
+ * @param userBounds the user space bounding box of the painted area.
+ * @param xform the transformation from user space to device space.
+ * @param hints any hints for choosing between rendering alternatives.
+ *
+ * @return The context for performing the paint
+ */
+ public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+ Rectangle2D userBounds,
+ AffineTransform xform,
+ RenderingHints hints)
+ {
+ Point2D xp1 = xform.transform(getPoint1(), null);
+ Point2D xp2 = xform.transform(getPoint2(), null);
+ return new GradientPaintContext((float) xp1.getX(), (float) xp1.getY(), c1,
+ (float) xp2.getX(), (float) xp2.getY(), c2, cyclic);
+ }
+
+ /**
+ * Returns the transparency code for this <code>GradientPaint</code> instance.
+ * This is derived from the two {@link Color} objects used in creating this
+ * object: if both colors are opaque, this method returns
+ * {@link Transparency#OPAQUE}, otherwise it returns
+ * {@link Transparency#TRANSLUCENT}.
+ *
+ * @return {@link Transparency#OPAQUE} or {@link Transparency#TRANSLUCENT}.
+ */
+ public int getTransparency()
+ {
+ if (c1.getAlpha() == 255 && c2.getAlpha() == 255)
+ return Transparency.OPAQUE;
+ else
+ return Transparency.TRANSLUCENT;
+ }
+
+} // class GradientPaint
diff --git a/libjava/classpath/java/awt/Graphics.java b/libjava/classpath/java/awt/Graphics.java
new file mode 100644
index 0000000..ff26190
--- /dev/null
+++ b/libjava/classpath/java/awt/Graphics.java
@@ -0,0 +1,767 @@
+/* Graphics.java -- Abstract Java drawing class
+ Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.ImageObserver;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * This is the abstract superclass of classes for drawing to graphics
+ * devices such as the screen or printers.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ */
+public abstract class Graphics
+{
+
+/*
+ * Instance Variables
+ */
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Default constructor for subclasses.
+ */
+protected
+Graphics()
+{
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns a copy of this <code>Graphics</code> object.
+ *
+ * @return A copy of this object.
+ */
+public abstract Graphics
+create();
+
+/*************************************************************************/
+
+/**
+ * Returns a copy of this <code>Graphics</code> object. The origin point
+ * will be translated to the point (x, y) and the cliping rectangle set
+ * to the intersection of the clipping rectangle in this object and the
+ * rectangle specified by the parameters to this method.
+ *
+ * @param x The new X coordinate of the clipping region rect.
+ * @param y The new Y coordinate of the clipping region rect.
+ * @param width The width of the clipping region intersect rectangle.
+ * @param height The height of the clipping region intersect rectangle.
+ *
+ * @return A copy of this object, modified as specified.
+ */
+public Graphics
+create(int x, int y, int width, int height)
+{
+ Graphics g = create();
+
+ g.translate(x, y);
+ // FIXME: I'm not sure if this will work. Are the old clip rect bounds
+ // translated above?
+ g.clipRect(0, 0, width, height);
+
+ return(g);
+}
+
+/*************************************************************************/
+
+/**
+ * Translates this context so that its new origin point is the point
+ * (x, y).
+ *
+ * @param x The new X coordinate of the origin.
+ * @param y The new Y coordinate of the origin.
+ */
+public abstract void
+translate(int x, int y);
+
+/*************************************************************************/
+
+/**
+ * Returns the current color for this object.
+ *
+ * @return The color for this object.
+ */
+public abstract Color
+getColor();
+
+/*************************************************************************/
+
+/**
+ * Sets the current color for this object.
+ *
+ * @param color The new color.
+ */
+public abstract void
+setColor(Color color);
+
+/*************************************************************************/
+
+/**
+ * Sets this context into "paint" mode, where the target pixels are
+ * completely overwritten when drawn on.
+ */
+public abstract void
+setPaintMode();
+
+/*************************************************************************/
+
+/**
+ * Sets this context info "XOR" mode, where the targe pixles are
+ * XOR-ed when drawn on.
+ *
+ * @param color The color to XOR against.
+ */
+public abstract void
+setXORMode(Color color);
+
+/*************************************************************************/
+
+/**
+ * Returns the current font for this graphics context.
+ *
+ * @return The current font.
+ */
+public abstract Font
+getFont();
+
+/*************************************************************************/
+
+/**
+ * Sets the font for this graphics context to the specified value.
+ *
+ * @param font The new font.
+ */
+public abstract void
+setFont(Font font);
+
+/*************************************************************************/
+
+/**
+ * Returns the font metrics for the current font.
+ *
+ * @return The font metrics for the current font.
+ */
+public FontMetrics
+getFontMetrics()
+{
+ return(getFontMetrics(getFont()));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the font metrics for the specified font.
+ *
+ * @param font The font to return metrics for.
+ *
+ * @return The requested font metrics.
+ */
+public abstract FontMetrics
+getFontMetrics(Font font);
+
+/*************************************************************************/
+
+/**
+ * Returns the bounding rectangle of the clipping region for this
+ * graphics context.
+ *
+ * @return The bounding rectangle for the clipping region.
+ */
+public abstract Rectangle
+getClipBounds();
+
+/*************************************************************************/
+
+/**
+ * Returns the bounding rectangle of the clipping region for this
+ * graphics context.
+ *
+ * @return The bounding rectangle for the clipping region.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getClipBounds()</code>.
+ */
+public Rectangle
+getClipRect()
+{
+ return(getClipBounds());
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the clipping region to the intersection of the current clipping
+ * region and the rectangle determined by the specified parameters.
+ *
+ * @param x The X coordinate of the upper left corner of the intersect rect.
+ * @param y The Y coordinate of the upper left corner of the intersect rect.
+ * @param width The width of the intersect rect.
+ * @param height The height of the intersect rect.
+ */
+public abstract void
+clipRect(int x, int y, int width, int height);
+
+/*************************************************************************/
+
+/**
+ * Sets the clipping region to the rectangle determined by the specified
+ * parameters.
+ *
+ * @param x The X coordinate of the upper left corner of the rect.
+ * @param y The Y coordinate of the upper left corner of the rect.
+ * @param width The width of the rect.
+ * @param height The height of the rect.
+ */
+public abstract void
+setClip(int x, int y, int width, int height);
+
+/*************************************************************************/
+
+/**
+ * Returns the current clipping region as a <code>Shape</code> object.
+ *
+ * @return The clipping region as a <code>Shape</code>.
+ */
+public abstract Shape
+getClip();
+
+/*************************************************************************/
+
+/**
+ * Sets the clipping region to the specified <code>Shape</code>.
+ *
+ * @param clip The new clipping region.
+ */
+public abstract void
+setClip(Shape clip);
+
+/*************************************************************************/
+
+/**
+ * Copies the specified rectangle to the specified offset location.
+ *
+ * @param x The X coordinate of the upper left corner of the copy rect.
+ * @param y The Y coordinate of the upper left corner of the copy rect.
+ * @param width The width of the copy rect.
+ * @param height The height of the copy rect.
+ * @param dx The offset from the X value to start drawing.
+ * @param dy The offset from the Y value to start drawing.
+ */
+public abstract void
+copyArea(int x, int y, int width, int height, int dx, int dy);
+
+/*************************************************************************/
+
+/**
+ * Draws a line between the two specified points.
+ *
+ * @param x1 The X coordinate of the first point.
+ * @param y1 The Y coordinate of the first point.
+ * @param x2 The X coordinate of the second point.
+ * @param y2 The Y coordinate of the second point.
+ */
+public abstract void
+drawLine(int x1, int y1, int x2, int y2);
+
+/*************************************************************************/
+
+/**
+ * Fills the area bounded by the specified rectangle.
+ *
+ * @param x The X coordinate of the upper left corner of the fill rect.
+ * @param y The Y coordinate of the upper left corner of the fill rect.
+ * @param width The width of the fill rect.
+ * @param height The height of the fill rect.
+ */
+public abstract void
+fillRect(int x, int y, int width, int height);
+
+/*************************************************************************/
+
+/**
+ * Draws the outline of the specified rectangle.
+ *
+ * @param x The X coordinate of the upper left corner of the draw rect.
+ * @param y The Y coordinate of the upper left corner of the draw rect.
+ * @param width The width of the draw rect.
+ * @param height The height of the draw rect.
+ */
+public void
+drawRect(int x, int y, int width, int height)
+{
+ int x1 = x;
+ int y1 = y;
+ int x2 = x + width;
+ int y2 = y + height;
+ drawLine(x1, y1, x2, y1);
+ drawLine(x2, y1, x2, y2);
+ drawLine(x2, y2, x1, y2);
+ drawLine(x1, y2, x1, y1);
+}
+
+/*************************************************************************/
+
+/**
+ * Clears the specified rectangle.
+ *
+ * @param x The X coordinate of the upper left corner of the clear rect.
+ * @param y The Y coordinate of the upper left corner of the clear rect.
+ * @param width The width of the clear rect.
+ * @param height The height of the clear rect.
+ */
+public abstract void
+clearRect(int x, int y, int width, int height);
+
+/*************************************************************************/
+
+/**
+ * Draws the outline of the specified rectangle with rounded cornders.
+ *
+ * @param x The X coordinate of the upper left corner of the draw rect.
+ * @param y The Y coordinate of the upper left corner of the draw rect.
+ * @param width The width of the draw rect.
+ * @param height The height of the draw rect.
+ * @param arcWidth The width of the corner arcs.
+ * @param arcHeight The height of the corner arcs.
+ */
+public abstract void
+drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
+
+/*************************************************************************/
+
+/**
+ * Fills the specified rectangle with rounded cornders.
+ *
+ * @param x The X coordinate of the upper left corner of the fill rect.
+ * @param y The Y coordinate of the upper left corner of the fill rect.
+ * @param width The width of the fill rect.
+ * @param height The height of the fill rect.
+ * @param arcWidth The width of the corner arcs.
+ * @param arcHeight The height of the corner arcs.
+ */
+public abstract void
+fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
+
+/*************************************************************************/
+
+public void
+draw3DRect(int x, int y, int width, int height, boolean raised)
+{
+ Color color = getColor();
+ Color tl = color.brighter();
+ Color br = color.darker();
+
+ if (!raised)
+ {
+ Color tmp = tl;
+ tl = br;
+ br = tmp;
+ }
+
+ int x1 = x;
+ int y1 = y;
+ int x2 = x + width;
+ int y2 = y + height;
+
+ setColor(tl);
+ drawLine(x1, y1, x2, y1);
+ drawLine(x1, y2, x1, y1);
+ setColor(br);
+ drawLine(x2, y1, x2, y2);
+ drawLine(x2, y2, x1, y2);
+ setColor(color);
+}
+
+/**
+ * Fills the specified rectangle with a 3D effect
+ *
+ * @param x The X coordinate of the upper left corner of the fill rect.
+ * @param y The Y coordinate of the upper left corner of the fill rect.
+ * @param width The width of the fill rect.
+ * @param height The height of the fill rect.
+ * @param raised <code>true</code> if the rectangle appears raised,
+ * <code>false</code> if it should appear etched.
+ */
+public void
+fill3DRect(int x, int y, int width, int height, boolean raised)
+{
+ fillRect(x, y, width, height);
+ draw3DRect(x, y, width-1, height-1, raised);
+}
+
+/*************************************************************************/
+
+/**
+ * Draws an oval that just fits within the specified rectangle.
+ *
+ * @param x The X coordinate of the upper left corner of the rect.
+ * @param y The Y coordinate of the upper left corner of the rect.
+ * @param width The width of the rect.
+ * @param height The height of the rect.
+ */
+public abstract void
+drawOval(int x, int y, int width, int height);
+
+/*************************************************************************/
+
+/**
+ * Fills an oval that just fits within the specified rectangle.
+ *
+ * @param x The X coordinate of the upper left corner of the rect.
+ * @param y The Y coordinate of the upper left corner of the rect.
+ * @param width The width of the rect.
+ * @param height The height of the rect.
+ */
+public abstract void
+fillOval(int x, int y, int width, int height);
+
+/*************************************************************************/
+
+/**
+ * Draws an arc using the specified bounding rectangle and the specified
+ * angle parameter. The arc is centered at the center of the rectangle.
+ * The arc starts at the arcAngle position and extend for arcAngle
+ * degrees. The degree origin is at the 3 o'clock position.
+ *
+ * @param x The X coordinate of the upper left corner of the rect.
+ * @param y The Y coordinate of the upper left corner of the rect.
+ * @param width The width of the rect.
+ * @param height The height of the rect.
+ * @param arcStart The beginning angle of the arc.
+ * @param arcAngle The extent of the arc.
+ */
+public abstract void
+drawArc(int x, int y, int width, int height, int arcStart, int arcAngle);
+
+/*************************************************************************/
+
+/**
+ * Fills the arc define by the specified bounding rectangle and the specified
+ * angle parameter. The arc is centered at the center of the rectangle.
+ * The arc starts at the arcAngle position and extend for arcAngle
+ * degrees. The degree origin is at the 3 o'clock position.
+ *
+ * @param x The X coordinate of the upper left corner of the rect.
+ * @param y The Y coordinate of the upper left corner of the rect.
+ * @param width The width of the rect.
+ * @param height The height of the rect.
+ * @param arcStart The beginning angle of the arc.
+ * @param arcAngle The extent of the arc.
+ */
+public abstract void
+fillArc(int x, int y, int width, int height, int arcStart, int arcAngle);
+
+/*************************************************************************/
+
+/**
+ * Draws a series of interconnected lines determined by the arrays
+ * of corresponding x and y coordinates.
+ *
+ * @param xPoints The X coordinate array.
+ * @param yPoints The Y coordinate array.
+ * @param npoints The number of points to draw.
+ */
+public abstract void
+drawPolyline(int xPoints[], int yPoints[], int npoints);
+
+/*************************************************************************/
+
+/**
+ * Draws a series of interconnected lines determined by the arrays
+ * of corresponding x and y coordinates. The figure is closed if necessary
+ * by connecting the first and last points.
+ *
+ * @param xPoints The X coordinate array.
+ * @param yPoints The Y coordinate array.
+ * @param npoints The number of points to draw.
+ */
+public abstract void
+drawPolygon(int xPoints[], int yPoints[], int npoints);
+
+/*************************************************************************/
+
+/**
+ * Draws the specified polygon.
+ *
+ * @param polygon The polygon to draw.
+ */
+public void
+drawPolygon(Polygon polygon)
+{
+ drawPolygon(polygon.xpoints, polygon.ypoints, polygon.npoints);
+}
+
+/*************************************************************************/
+
+/**
+ * Fills the polygon determined by the arrays
+ * of corresponding x and y coordinates.
+ *
+ * @param xPoints The X coordinate array.
+ * @param yPoints The Y coordinate array.
+ * @param npoints The number of points to draw.
+ */
+public abstract void
+fillPolygon(int xPoints[], int yPoints[], int npoints);
+
+/*************************************************************************/
+
+/**
+ * Fills the specified polygon
+ *
+ * @param polygon The polygon to fill.
+ */
+public void
+fillPolygon(Polygon polygon)
+{
+ fillPolygon(polygon.xpoints, polygon.ypoints, polygon.npoints);
+}
+
+/*************************************************************************/
+
+/**
+ * Draws the specified string starting at the specified point.
+ *
+ * @param string The string to draw.
+ * @param x The X coordinate of the point to draw at.
+ * @param y The Y coordinate of the point to draw at.
+ */
+public abstract void
+drawString(String string, int x, int y);
+
+public abstract void drawString (AttributedCharacterIterator ci, int x, int y);
+
+/*************************************************************************/
+
+/**
+ * Draws the specified characters starting at the specified point.
+ *
+ * @param data The array of characters to draw.
+ * @param offset The offset into the array to start drawing characters from.
+ * @param length The number of characters to draw.
+ * @param x The X coordinate of the point to draw at.
+ * @param y The Y coordinate of the point to draw at.
+ */
+public void
+drawChars(char data[], int offset, int length, int x, int y)
+{
+ drawString(new String(data, offset, length), x, y);
+}
+
+public void
+drawBytes(byte[] data, int offset, int length, int x, int y)
+{
+ String str = new String(data, offset, length);
+ drawString(str, x, y);
+}
+
+/*************************************************************************/
+
+/**
+ * Draws all of the image that is available and returns. If the image
+ * is not completely loaded, <code>false</code> is returned and
+ * the specified iamge observer is notified as more data becomes
+ * available.
+ *
+ * @param image The image to draw.
+ * @param x The X coordinate of the point to draw at.
+ * @param y The Y coordinate of the point to draw at.
+ * @param observer The image observer to notify as data becomes available.
+ *
+ * @return <code>true</code> if all the image data is available,
+ * <code>false</code> otherwise.
+ */
+public abstract boolean
+drawImage(Image image, int x, int y, ImageObserver observer);
+
+/*************************************************************************/
+
+/**
+ * Draws all of the image that is available and returns. The image
+ * is scaled to fit in the specified rectangle. If the image
+ * is not completely loaded, <code>false</code> is returned and
+ * the specified iamge observer is notified as more data becomes
+ * available.
+ *
+ * @param image The image to draw.
+ * @param x The X coordinate of the point to draw at.
+ * @param y The Y coordinate of the point to draw at.
+ * @param width The width of the rectangle to draw in.
+ * @param height The height of the rectangle to draw in.
+ * @param observer The image observer to notify as data becomes available.
+ *
+ * @return <code>true</code> if all the image data is available,
+ * <code>false</code> otherwise.
+ */
+public abstract boolean
+drawImage(Image image, int x, int y, int width, int height,
+ ImageObserver observer);
+
+/*************************************************************************/
+
+/**
+ * Draws all of the image that is available and returns. If the image
+ * is not completely loaded, <code>false</code> is returned and
+ * the specified iamge observer is notified as more data becomes
+ * available.
+ *
+ * @param image The image to draw.
+ * @param x The X coordinate of the point to draw at.
+ * @param y The Y coordinate of the point to draw at.
+ * @param bgcolor The background color to use for the image.
+ * @param observer The image observer to notify as data becomes available.
+ *
+ * @return <code>true</code> if all the image data is available,
+ * <code>false</code> otherwise.
+ */
+public abstract boolean
+drawImage(Image image, int x, int y, Color bgcolor, ImageObserver observer);
+
+/*************************************************************************/
+
+/**
+ * Draws all of the image that is available and returns. The image
+ * is scaled to fit in the specified rectangle. If the image
+ * is not completely loaded, <code>false</code> is returned and
+ * the specified iamge observer is notified as more data becomes
+ * available.
+ *
+ * @param image The image to draw.
+ * @param x The X coordinate of the point to draw at.
+ * @param y The Y coordinate of the point to draw at.
+ * @param width The width of the rectangle to draw in.
+ * @param height The height of the rectangle to draw in.
+ * @param bgcolor The background color to use for the image.
+ * @param observer The image observer to notify as data becomes available.
+ *
+ * @return <code>true</code> if all the image data is available,
+ * <code>false</code> otherwise.
+ */
+public abstract boolean
+drawImage(Image image, int x, int y, int width, int height, Color bgcolor,
+ ImageObserver observer);
+
+/*************************************************************************/
+
+/**
+ * FIXME: Write Javadocs for this when you understand it.
+ */
+public abstract boolean
+drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
+ int sx2, int sy2, ImageObserver observer);
+
+/*************************************************************************/
+
+/**
+ * FIXME: Write Javadocs for this when you understand it.
+ */
+public abstract boolean
+drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
+ int sx2, int sy2, Color bgcolor, ImageObserver observer);
+
+/*************************************************************************/
+
+/**
+ * Free any resources held by this graphics context immediately instead
+ * of waiting for the object to be garbage collected and finalized.
+ */
+public abstract void
+dispose();
+
+/*************************************************************************/
+
+/**
+ * Frees the resources held by this graphics context when it is
+ * garbage collected.
+ */
+public void
+finalize()
+{
+ dispose();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a string representation of this object.
+ *
+ * @return A string representation of this object.
+ */
+public String
+toString()
+{
+ return getClass ().getName () + "[font=" + getFont () + ",color=" + getColor () + "]";
+}
+
+public boolean
+hitClip(int x, int y, int width, int height)
+{
+ throw new UnsupportedOperationException("not implemented yet");
+}
+
+public Rectangle
+getClipBounds(Rectangle r)
+{
+ Rectangle clipBounds = getClipBounds();
+
+ if (r == null)
+ return clipBounds;
+
+ r.x = clipBounds.x;
+ r.y = clipBounds.y;
+ r.width = clipBounds.width;
+ r.height = clipBounds.height;
+ return r;
+}
+
+} // class Graphics
+
diff --git a/libjava/classpath/java/awt/Graphics2D.java b/libjava/classpath/java/awt/Graphics2D.java
new file mode 100644
index 0000000..3faa9dc
--- /dev/null
+++ b/libjava/classpath/java/awt/Graphics2D.java
@@ -0,0 +1,158 @@
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+/**
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public abstract class Graphics2D extends Graphics
+{
+
+ protected Graphics2D()
+ {
+ }
+
+ public void draw3DRect(int x, int y, int width, int height,
+ boolean raised)
+ {
+ super.draw3DRect(x, y, width, height, raised);
+ }
+
+ public void fill3DRect(int x, int y, int width, int height,
+ boolean raised)
+ {
+ super.fill3DRect(x, y, width, height, raised);
+ }
+
+ public abstract void draw(Shape shape);
+
+ public abstract boolean drawImage(Image image, AffineTransform xform,
+ ImageObserver obs);
+
+ public abstract void drawImage(BufferedImage image,
+ BufferedImageOp op,
+ int x,
+ int y);
+
+ public abstract void drawRenderedImage(RenderedImage image,
+ AffineTransform xform);
+
+ public abstract void drawRenderableImage(RenderableImage image,
+ AffineTransform xform);
+
+ public abstract void drawString(String text, int x, int y);
+
+ public abstract void drawString(String text, float x, float y);
+
+ public abstract void drawString(AttributedCharacterIterator iterator,
+ int x, int y);
+
+ public abstract void drawString(AttributedCharacterIterator iterator,
+ float x, float y);
+
+ // public abstract void drawGlyphVector(GlyphVector g, float x, float y);
+
+ public abstract void fill(Shape shape);
+
+ public abstract boolean hit(Rectangle rect, Shape text,
+ boolean onStroke);
+
+ public abstract GraphicsConfiguration getDeviceConfiguration();
+
+ public abstract void setComposite(Composite comp);
+
+ public abstract void setPaint(Paint paint);
+
+ public abstract void setStroke(Stroke stroke);
+
+ public abstract void setRenderingHint(RenderingHints.Key hintKey,
+ Object hintValue);
+
+ public abstract Object getRenderingHint(RenderingHints.Key hintKey);
+
+ public abstract void setRenderingHints(Map hints);
+
+ public abstract void addRenderingHints(Map hints);
+
+ public abstract RenderingHints getRenderingHints();
+
+ public abstract void translate(int x, int y);
+
+ public abstract void translate(double tx, double ty);
+
+ public abstract void rotate(double theta);
+
+ public abstract void rotate(double theta, double x, double y);
+
+ public abstract void scale(double scaleX, double scaleY);
+
+ public abstract void shear(double shearX, double shearY);
+
+ public abstract void transform(AffineTransform Tx);
+
+ public abstract void setTransform(AffineTransform Tx);
+
+ public abstract AffineTransform getTransform();
+
+ public abstract Paint getPaint();
+
+ public abstract Composite getComposite();
+
+ public abstract void setBackground(Color color);
+
+ public abstract Color getBackground();
+
+ public abstract Stroke getStroke();
+
+ public abstract void clip(Shape s);
+
+ public abstract FontRenderContext getFontRenderContext ();
+
+ public abstract void drawGlyphVector (GlyphVector g, float x, float y);
+}
diff --git a/libjava/classpath/java/awt/GraphicsConfigTemplate.java b/libjava/classpath/java/awt/GraphicsConfigTemplate.java
new file mode 100644
index 0000000..e468883
--- /dev/null
+++ b/libjava/classpath/java/awt/GraphicsConfigTemplate.java
@@ -0,0 +1,106 @@
+/* GraphicsConfigTemplate.java -- a template for selecting configurations
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * This allows filtering an array of GraphicsConfigurations for the best
+ * one based on various requirements. The resulting configuration has had
+ * all non-default attributes set as required to meet or exceed the request.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see GraphicsConfiguration
+ * @see GraphicsDevice
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public abstract class GraphicsConfigTemplate implements Serializable
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = -8061369279557787079L;
+
+ /** States that a feature is required to select a configuration. */
+ public static final int REQUIRED = 1;
+
+ /**
+ * States that a feature is preferred, but not required, to select a
+ * configuration. In the case of multiple valid configurations, the tie
+ * breaks in favor of the one with the feature.
+ */
+ public static final int PREFERRED = 2;
+
+ /**
+ * States that a feature is not necessary in the configuration. In the case
+ * of multiple valid configurations, the tie breaks in favor of the one
+ * without the feature, to reduce overhead.
+ */
+ public static final int UNNECESSARY = 3;
+
+ /**
+ * The default constructor.
+ */
+ public GraphicsConfigTemplate()
+ {
+ }
+
+ /**
+ * Returns the "best" match among the array of possible configurations, given
+ * the criteria of this template.
+ *
+ * @param array the array to choose from
+ * @return the best match
+ * @throws NullPointerException if array is null
+ */
+ public abstract GraphicsConfiguration getBestConfiguration
+ (GraphicsConfiguration[] array);
+
+ /**
+ * Returns true if the given configuration supports all the features required
+ * by this template.
+ *
+ * @param config the configuration to test
+ * @return true if it is a match
+ * @throws NullPointerException if config is null
+ */
+ public abstract boolean isGraphicsConfigSupported
+ (GraphicsConfiguration config);
+} // class GraphicsConfigTemplate
diff --git a/libjava/classpath/java/awt/GraphicsConfiguration.java b/libjava/classpath/java/awt/GraphicsConfiguration.java
new file mode 100644
index 0000000..6dc27793
--- /dev/null
+++ b/libjava/classpath/java/awt/GraphicsConfiguration.java
@@ -0,0 +1,218 @@
+/* GraphicsConfiguration.java -- describes characteristics of graphics
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.VolatileImage;
+
+/**
+ * This class describes the configuration of various graphics devices, such
+ * as a monitor or printer. Different configurations may exist for the same
+ * device, according to the different native modes supported.
+ *
+ * <p>Virtual devices are supported (for example, in a multiple screen
+ * environment, a virtual device covers all screens simultaneously); the
+ * configuration will have a non-zero relative coordinate system in such
+ * a case.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Window
+ * @see Frame
+ * @see GraphicsEnvironment
+ * @see GraphicsDevice
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public abstract class GraphicsConfiguration
+{
+ /**
+ * The default constructor.
+ *
+ * @see GraphicsDevice#getConfigurations()
+ * @see GraphicsDevice#getDefaultConfiguration()
+ * @see GraphicsDevice#getBestConfiguration(GraphicsConfigTemplate)
+ * @see Graphics2D#getDeviceConfiguration()
+ */
+ protected GraphicsConfiguration ()
+ {
+ }
+
+ /**
+ * Gets the associated device that this configuration describes.
+ *
+ * @return the device
+ */
+ public abstract GraphicsDevice getDevice();
+
+ /**
+ * Returns a buffered image optimized to this device, so that blitting can
+ * be supported in the buffered image.
+ *
+ * @param w the width of the buffer
+ * @param h the height of the buffer
+ * @return the buffered image, or null if none is supported
+ */
+ public abstract BufferedImage createCompatibleImage(int w, int h);
+
+ /**
+ * Returns a buffered volatile image optimized to this device, so that
+ * blitting can be supported in the buffered image. Because the buffer is
+ * volatile, it can be optimized by native graphics accelerators.
+ *
+ * @param w the width of the buffer
+ * @param h the height of the buffer
+ * @return the buffered image, or null if none is supported
+ * @see Component#createVolatileImage(int, int)
+ * @since 1.4
+ */
+ public abstract VolatileImage createCompatibleVolatileImage(int w, int h);
+
+ /**
+ * Returns a buffered volatile image optimized to this device, and with the
+ * given capabilities, so that blitting can be supported in the buffered
+ * image. Because the buffer is volatile, it can be optimized by native
+ * graphics accelerators.
+ *
+ * @param w the width of the buffer
+ * @param h the height of the buffer
+ * @param caps the desired capabilities of the image buffer
+ * @return the buffered image, or null if none is supported
+ * @throws AWTException if the capabilities cannot be met
+ * @since 1.4
+ */
+ public VolatileImage createCompatibleVolatileImage(int w, int h,
+ ImageCapabilities caps)
+ throws AWTException
+ {
+ throw new AWTException("not implemented");
+ }
+
+ /**
+ * Returns a buffered image optimized to this device, and with the specified
+ * transparency, so that blitting can be supported in the buffered image.
+ *
+ * @param w the width of the buffer
+ * @param h the height of the buffer
+ * @param transparency the transparency of the buffer
+ * @return the buffered image, or null if none is supported
+ * @see Transparency#OPAQUE
+ * @see Transparency#BITMASK
+ * @see Transparency#TRANSLUCENT
+ */
+ public abstract BufferedImage createCompatibleImage(int w, int h,
+ int transparency);
+
+ /**
+ * Gets the color model of the corresponding device.
+ *
+ * @return the color model
+ */
+ public abstract ColorModel getColorModel();
+
+ /**
+ * Gets a color model for the corresponding device which supports the desired
+ * transparency level.
+ *
+ * @param transparency the transparency of the model
+ * @return the color model, with transparency
+ * @see Transparency#OPAQUE
+ * @see Transparency#BITMASK
+ * @see Transparency#TRANSLUCENT
+ */
+ public abstract ColorModel getColorModel(int transparency);
+
+ /**
+ * Returns a transform that maps user coordinates to device coordinates. The
+ * preferred mapping is about 72 user units to 1 inch (2.54 cm) of physical
+ * space. This is often the identity transform. The device coordinates have
+ * the origin at the upper left, with increasing x to the right, and
+ * increasing y to the bottom.
+ *
+ * @return the transformation from user space to device space
+ * @see #getNormalizingTransform()
+ */
+ public abstract AffineTransform getDefaultTransform();
+
+ /**
+ * Returns a transform that maps user coordinates to device coordinates. The
+ * exact mapping is 72 user units to 1 inch (2.54 cm) of physical space.
+ * This is often the identity transform. The device coordinates have the
+ * origin at the upper left, with increasing x to the right, and increasing
+ * y to the bottom. Note that this is more accurate (and thus, sometimes more
+ * costly) than the default transform.
+ *
+ * @return the normalized transformation from user space to device space
+ * @see #getDefaultTransform()
+ */
+ public abstract AffineTransform getNormalizingTransform();
+
+ /**
+ * Returns the bounds of the configuration, in device coordinates. If this
+ * is a virtual device (for example, encompassing several screens), the
+ * bounds may have a non-zero origin.
+ *
+ * @return the device bounds
+ * @since 1.3
+ */
+ public abstract Rectangle getBounds();
+
+ /**
+ * Returns the buffering capabilities of this configuration.
+ *
+ * @return the buffer capabilities
+ * @since 1.4
+ */
+ public BufferCapabilities getBufferCapabilities()
+ {
+ throw new Error("not implemented");
+ }
+
+ /**
+ * Returns the imaging capabilities of this configuration.
+ *
+ * @return the image capabilities
+ * @since 1.4
+ */
+ public ImageCapabilities getImageCapabilities()
+ {
+ throw new Error("not implemented");
+ }
+} // class GraphicsConfiguration
diff --git a/libjava/classpath/java/awt/GraphicsDevice.java b/libjava/classpath/java/awt/GraphicsDevice.java
new file mode 100644
index 0000000..95487a2
--- /dev/null
+++ b/libjava/classpath/java/awt/GraphicsDevice.java
@@ -0,0 +1,292 @@
+/* GraphicsDevice.java -- information about a graphics device
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.VolatileImage;
+
+/**
+ * This describes a graphics device available to the given environment. This
+ * includes screen and printer devices, and the different configurations for
+ * each device. Also, this allows you to create virtual devices which operate
+ * over a multi-screen environment.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see GraphicsEnvironment
+ * @see GraphicsConfiguration
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public abstract class GraphicsDevice
+{
+ /** Device is a raster screen. */
+ public static final int TYPE_RASTER_SCREEN = 0;
+
+ /** Device is a printer. */
+ public static final int TYPE_PRINTER = 1;
+
+ /** Device is an image buffer not visible to the user. */
+ public static final int TYPE_IMAGE_BUFFER = 2;
+
+ /** The current full-screen window, or null if there is none. */
+ private Window full_screen;
+
+ /**
+ * The bounds of the fullscreen window before it has been switched to full
+ * screen.
+ */
+ private Rectangle fullScreenOldBounds;
+
+ /** The current display mode, or null if unknown. */
+ private DisplayMode mode;
+
+ /**
+ * The default constructor.
+ *
+ * @see GraphicsEnvironment#getScreenDevices()
+ * @see GraphicsEnvironment#getDefaultScreenDevice()
+ * @see GraphicsConfiguration#getDevice()
+ */
+ protected GraphicsDevice()
+ {
+ }
+
+ /**
+ * Returns the type of the device.
+ *
+ * @return the device type
+ * @see #TYPE_RASTER_SCREEN
+ * @see #TYPE_PRINTER
+ * @see #TYPE_IMAGE_BUFFER
+ */
+ public abstract int getType();
+
+ /**
+ * Returns an identification string for the device. This can be
+ * vendor-specific, and may be useful for debugging.
+ *
+ * @return the identification
+ */
+ public abstract String getIDstring();
+
+ /**
+ * Return all configurations valid for this device.
+ *
+ * @return an array of configurations
+ */
+ public abstract GraphicsConfiguration[] getConfigurations();
+
+ /**
+ * Return the default configuration for this device.
+ *
+ * @return the default configuration
+ */
+ public abstract GraphicsConfiguration getDefaultConfiguration();
+
+ /**
+ * Return the best configuration, according to the criteria in the given
+ * template.
+ *
+ * @param template the template to adjust by
+ * @return the best configuration
+ * @throws NullPointerException if template is null
+ */
+ public GraphicsConfiguration getBestConfiguration
+ (GraphicsConfigTemplate template)
+ {
+ return template.getBestConfiguration(getConfigurations());
+ }
+
+ /**
+ * Returns true if the device supports full-screen exclusive mode. The
+ * default implementation returns true; subclass it if this is not the case.
+ *
+ * @return true if full screen support is available
+ * @since 1.4
+ */
+ public boolean isFullScreenSupported()
+ {
+ return true;
+ }
+
+ /**
+ * Toggle the given window between full screen and normal mode. The previous
+ * full-screen window, if different, is restored; if the given window is
+ * null, no window will be full screen. If
+ * <code>isFullScreenSupported()</code> returns true, full screen mode is
+ * considered to be exclusive, which implies:<ul>
+ * <li>Windows cannot overlap the full-screen window. All other application
+ * windows will always appear beneath the full-screen window in the
+ * Z-order.</li>
+ * <li>Input method windows are disabled. It is advisable to call
+ * <code>Component.enableInputMethods(false)</code> to make a component
+ * a non-client of the input method framework.</li>
+ * </ul><br>
+ * If <code>isFullScreenSupported()</code> returns false, full-screen
+ * exclusive mode is simulated by resizing the window to the size of the
+ * screen and positioning it at (0,0). This is also what this method does.
+ * If a device supports real fullscreen mode then it should override this
+ * method as well as #isFullScreenSupported and #getFullScreenWindow.
+ *
+ * @param w the window to toggle
+ * @see #isFullScreenSupported()
+ * @see #getFullScreenWindow()
+ * @see #setDisplayMode(DisplayMode)
+ * @see Component#enableInputMethods(boolean)
+ * @since 1.4
+ */
+ public synchronized void setFullScreenWindow(Window w)
+ {
+ // Restore the previous window to normal mode and release the reference.
+ if (full_screen != null)
+ {
+ full_screen.setBounds(fullScreenOldBounds);
+ }
+
+ full_screen = null;
+
+ // If w != null, make it full-screen.
+ if (w != null)
+ {
+ fullScreenOldBounds = w.getBounds();
+ full_screen = w;
+ DisplayMode dMode = getDisplayMode();
+ full_screen.setBounds(0, 0, dMode.getWidth(), dMode.getHeight());
+ full_screen.requestFocus();
+ full_screen.setLocationRelativeTo(null);
+ }
+ }
+
+ /**
+ * Returns the current full-screen window of the device, or null if no
+ * window is full-screen.
+ *
+ * @return the full-screen window
+ * @see #setFullScreenWindow(Window)
+ * @since 1.4
+ */
+ public Window getFullScreenWindow()
+ {
+ return full_screen;
+ }
+
+ /**
+ * Returns whether this device supports low-level display changes. This may
+ * depend on whether full-screen exclusive mode is available.
+ *
+ * XXX The default implementation returns false for now.
+ *
+ * @return true if display changes are supported
+ * @see #setDisplayMode(DisplayMode)
+ * @since 1.4
+ */
+ public boolean isDisplayChangeSupported()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the display mode. This may be dependent on the availability of
+ * full-screen exclusive mode.
+ *
+ * @param mode the new mode
+ * @throws IllegalArgumentException if the new mode is not in getDisplayModes
+ * @throws UnsupportedOperationException if ! isDisplayChangeSupported()
+ * @see #getDisplayMode()
+ * @see #getDisplayModes()
+ * @see #isDisplayChangeSupported()
+ * @since 1.4
+ */
+ public void setDisplayMode(DisplayMode mode)
+ {
+ DisplayMode[] array = getDisplayModes();
+ if (! isDisplayChangeSupported())
+ throw new UnsupportedOperationException();
+ int i = array == null ? 0 : array.length;
+ while (--i >= 0)
+ if (array[i].equals(mode))
+ break;
+ if (i < 0)
+ throw new IllegalArgumentException();
+ this.mode = mode;
+ }
+
+ /**
+ * Returns the current display mode of this device, or null if unknown.
+ *
+ * @return the current display mode
+ * @see #setDisplayMode(DisplayMode)
+ * @see #getDisplayModes()
+ * @since 1.4
+ */
+ public DisplayMode getDisplayMode()
+ {
+ return mode;
+ }
+
+ /**
+ * Return an array of all available display modes. This implementation
+ * returns a 0-length array, so subclasses must override this.
+ *
+ * @return the array of available modes
+ * @since 1.4
+ */
+ public DisplayMode[] getDisplayModes()
+ {
+ return new DisplayMode[0];
+ }
+
+ /**
+ * Return the number of bytes available in accelerated memory on this
+ * device. The device may support creation or caching on a first-come,
+ * first-served basis, depending on the operating system and driver.
+ * Memory may be a finite resource, and because of multi-threading, you
+ * are not guaranteed that the result of this method ensures your image
+ * will successfully be put in accelerated memory. A negative result means
+ * the memory is unlimited. The default implementation assumes no special
+ * memory is available, and returns 0.
+ *
+ * @return the size of accelerated memory available
+ * @see VolatileImage#flush()
+ * @see ImageCapabilities#isAccelerated()
+ */
+ public int getAvailableAcceleratedMemory()
+ {
+ return 0;
+ }
+} // class GraphicsDevice
diff --git a/libjava/classpath/java/awt/GraphicsEnvironment.java b/libjava/classpath/java/awt/GraphicsEnvironment.java
new file mode 100644
index 0000000..a82e7a3
--- /dev/null
+++ b/libjava/classpath/java/awt/GraphicsEnvironment.java
@@ -0,0 +1,244 @@
+/* GraphicsEnvironment.java -- information about the graphics environment
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import gnu.java.awt.ClasspathToolkit;
+import gnu.classpath.SystemProperties;
+import java.awt.image.BufferedImage;
+import java.util.Locale;
+
+/**
+ * This descibes the collection of GraphicsDevice and Font objects available
+ * on a given platform. The resources might be local or remote, and specify
+ * the valid configurations for displaying graphics.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see GraphicsDevice
+ * @see GraphicsConfiguration
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public abstract class GraphicsEnvironment
+{
+ private static GraphicsEnvironment localGraphicsEnvironment;
+
+ /**
+ * The environment must be obtained from a factory or query method, hence
+ * this constructor is protected.
+ */
+ protected GraphicsEnvironment()
+ {
+ }
+
+ /**
+ * Returns the local graphics environment. If the java.awt.graphicsenv
+ * system property is set, it instantiates the specified class,
+ * otherwise it assume that the awt toolkit is a ClasspathToolkit
+ * and delegates to it to create the instance.
+ *
+ * @return the local environment
+ */
+ public static GraphicsEnvironment getLocalGraphicsEnvironment()
+ {
+ if (localGraphicsEnvironment != null)
+ return localGraphicsEnvironment;
+
+ String graphicsenv = SystemProperties.getProperty("java.awt.graphicsenv",
+ null);
+ if (graphicsenv != null)
+ {
+ try
+ {
+ // We intentionally use the bootstrap class loader.
+ localGraphicsEnvironment = (GraphicsEnvironment)
+ Class.forName(graphicsenv).newInstance();
+ return localGraphicsEnvironment;
+ }
+ catch (Exception x)
+ {
+ throw (InternalError)
+ new InternalError("Unable to instantiate java.awt.graphicsenv")
+ .initCause(x);
+ }
+ }
+ else
+ {
+ ClasspathToolkit tk;
+ tk = ((ClasspathToolkit) Toolkit.getDefaultToolkit());
+ localGraphicsEnvironment = tk.getLocalGraphicsEnvironment();
+ return localGraphicsEnvironment;
+ }
+ }
+
+ /**
+ * Check if the local environment is headless, meaning that it does not
+ * support a display, keyboard, or mouse. Many methods in the Abstract
+ * Windows Toolkit (java.awt) throw a {@link HeadlessException} if this
+ * returns true.
+ *
+ * This method returns true if the java.awt.headless property is set
+ * to "true".
+ *
+ * @return true if the environment is headless, meaning that graphics are
+ * unsupported
+ * @since 1.4
+ */
+ public static boolean isHeadless()
+ {
+ String headless = SystemProperties.getProperty("java.awt.headless", null);
+ return "true".equalsIgnoreCase(headless);
+ }
+
+ /**
+ * Check if the given environment is headless, meaning that it does not
+ * support a display, keyboard, or mouse. Many methods in the Abstract
+ * Windows Toolkit (java.awt) throw a {@link HeadlessException} if this
+ * returns true. This default implementation returns isHeadless(), so
+ * subclasses need only override it if they differ.
+ *
+ * @return true if the environment is headless, meaning that graphics are
+ * unsupported
+ * @since 1.4
+ */
+ public boolean isHeadlessInstance()
+ {
+ return isHeadless();
+ }
+
+ /**
+ * Get an array of all the GraphicsDevice objects.
+ *
+ * @return the available graphics devices, may be 0 length
+ * @throws HeadlessException if the environment is headless
+ */
+ public abstract GraphicsDevice[] getScreenDevices();
+
+ /**
+ * Get the default screen GraphicsDevice object.
+ *
+ * @return the default screen device
+ * @throws HeadlessException if the environment is headless
+ */
+ public abstract GraphicsDevice getDefaultScreenDevice();
+
+ /**
+ * Return a Graphics2D object which will render into the specified image.
+ *
+ * @param image the image to render into
+ * @return the object that renders into the image
+ */
+ public abstract Graphics2D createGraphics(BufferedImage image);
+
+ /**
+ * Returns an array of the one-point size fonts available in this
+ * environment. From there, the user can select the font and derive the
+ * correct one of proper size and attributes, using <code>deriveFont</code>.
+ * Only one master version of each font appears in this array; if a font
+ * can be derived from another, it must be created in that way.
+ *
+ * @return the array of available fonts
+ * @see #getAvailableFontFamilyNames()
+ * @see Font#deriveFont(int, float)
+ * @since 1.2
+ */
+ public abstract Font[] getAllFonts();
+
+ /**
+ * Returns an array of the font family names available in this environment.
+ * This allows flexibility in choosing the style of font, while still letting
+ * the Font class decide its best match.
+ *
+ * @return the array of available font families
+ * @see #getAllFonts()
+ * @see Font#getFamily()
+ * @since 1.2
+ */
+ public abstract String[] getAvailableFontFamilyNames();
+
+ /**
+ * Returns an array of the font family names available in this environment,
+ * localized to the current Locale if l is non-null. This allows
+ * flexibility in choosing the style of font, while still letting the Font
+ * class decide its best match.
+ *
+ * @param l the locale to use
+ * @return the array of available font families, localized
+ * @see #getAllFonts()
+ * @see Font#getFamily()
+ * @since 1.2
+ */
+ public abstract String[] getAvailableFontFamilyNames(Locale l);
+
+ /**
+ * Returns the point where a window should be centered. You should probably
+ * also check that the window fits within the screen bounds. The default
+ * simply returns the center of the maximum window bounds; subclasses should
+ * override this if native objects (like scrollbars) make that off-centered.
+ *
+ * @return the centering point
+ * @throws HeadlessException if the environment is headless
+ * @see #getMaximumWindowBounds()
+ * @since 1.4
+ */
+ public Point getCenterPoint()
+ {
+ Rectangle r = getMaximumWindowBounds();
+ return new Point(r.x + r.width / 2, r.y + r.height / 2);
+ }
+
+ /**
+ * Returns the maximum bounds for a centered window object. The default
+ * implementation simply returns the bounds of the default configuration
+ * of the default screen; subclasses should override this to if native
+ * objects (like scrollbars) reduce what is truly available. Also,
+ * subclasses should override this if the window should be centered across
+ * a multi-screen display.
+ *
+ * @return the maximum window bounds
+ * @throws HeadlessException if the environment is headless
+ * @see #getCenterPoint()
+ * @see GraphicsConfiguration#getBounds()
+ * @see Toolkit#getScreenInsets(GraphicsConfiguration)
+ * @since 1.4
+ */
+ public Rectangle getMaximumWindowBounds()
+ {
+ return getDefaultScreenDevice().getDefaultConfiguration().getBounds();
+ }
+} // class GraphicsEnvironment
diff --git a/libjava/classpath/java/awt/GridBagConstraints.java b/libjava/classpath/java/awt/GridBagConstraints.java
new file mode 100644
index 0000000..8d8b4fa
--- /dev/null
+++ b/libjava/classpath/java/awt/GridBagConstraints.java
@@ -0,0 +1,195 @@
+/* GridBagConstraints.java -- Constraints for GridBag layout manager
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * This specifies the constraints for a component managed by the
+ * GridBagLayout layout manager.
+ */
+public class GridBagConstraints implements Cloneable, Serializable
+{
+ static final long serialVersionUID = -1000070633030801713L;
+
+ /** Fill in both directions. */
+ public static final int BOTH = 1;
+ /** Don't fill. */
+ public static final int NONE = 0;
+ /** Fill horizontally. */
+ public static final int HORIZONTAL = 2;
+ /** Fill vertically. */
+ public static final int VERTICAL = 3;
+
+ /** Position in the center. */
+ public static final int CENTER = 10;
+ /** Position to the east. */
+ public static final int EAST = 13;
+ /** Position to the north. */
+ public static final int NORTH = 11;
+ /** Position to the northeast. */
+ public static final int NORTHEAST = 12;
+ /** Position to the northwest. */
+ public static final int NORTHWEST = 18;
+ /** Position to the south. */
+ public static final int SOUTH = 15;
+ /** Position to the southeast. */
+ public static final int SOUTHEAST = 14;
+ /** Position to the southwest. */
+ public static final int SOUTHWEST = 16;
+ /** Position to the west. */
+ public static final int WEST = 17;
+
+ /** Occupy all remaining cells except last cell. */
+ public static final int RELATIVE = -1;
+ /** Occupy all remaining cells. */
+ public static final int REMAINDER = 0;
+
+ /**
+ * Position to where the first text line would end. Equals to NORTHEAST for
+ * horizontal left-to-right orientations.
+ */
+ public static final int FIRST_LINE_END = 24;
+
+ /**
+ * Position to where the first text line would start. Equals to NORTHWEST for
+ * horizontal left-to-right orientations.
+ */
+ public static final int FIRST_LINE_START = 23;
+
+ /**
+ * Position to where the last text line would end. Equals to SOUTHEAST for
+ * horizontal left-to-right orientations.
+ */
+ public static final int LAST_LINE_END = 26;
+
+ /**
+ * Position to where the last text line would start. Equals to SOUTHWEST for
+ * horizontal left-to-right orientations.
+ */
+ public static final int LAST_LINE_START = 25;
+
+ /**
+ * Position to where a text line would end. Equals to EAST for
+ * left-to-right orientations.
+ */
+ public static final int LINE_END = 22;
+
+ /**
+ * Position to where a text line would start. Equals to WEST for
+ * left-to-right orientations.
+ */
+ public static final int LINE_START = 21;
+
+ /**
+ * Position to where a page ends. Equals SOUTH for horizontal orientations.
+ */
+ public static final int PAGE_END = 20;
+
+ /**
+ * Position to where a page starts. Equals NORTH for horizontal orientations.
+ */
+ public static final int PAGE_START = 19;
+
+ public int anchor;
+ public int fill;
+ public int gridheight;
+ public int gridwidth;
+ public int gridx;
+ public int gridy;
+ public Insets insets;
+ public int ipadx;
+ public int ipady;
+ public double weightx;
+ public double weighty;
+
+ /** Create a copy of this object. */
+ public Object clone ()
+ {
+ try
+ {
+ GridBagConstraints g = (GridBagConstraints) super.clone ();
+ g.insets = (Insets) insets.clone ();
+ return g;
+ }
+ catch (CloneNotSupportedException _)
+ {
+ // Can't happen.
+ return null;
+ }
+ }
+
+ /** Create a new GridBagConstraints object with the default
+ * parameters. */
+ public GridBagConstraints ()
+ {
+ this.anchor = CENTER;
+ this.fill = NONE;
+ this.gridx = RELATIVE;
+ this.gridy = RELATIVE;
+ this.gridwidth = 1;
+ this.gridheight = 1;
+ this.ipadx = 0;
+ this.ipady = 0;
+ this.insets = new Insets (0, 0, 0, 0);
+ this.weightx = 0;
+ this.weighty = 0;
+ }
+
+ /** Create a new GridBagConstraints object with the indicated
+ * parameters. */
+ public GridBagConstraints (int gridx, int gridy,
+ int gridwidth, int gridheight,
+ double weightx, double weighty,
+ int anchor, int fill,
+ Insets insets, int ipadx, int ipady)
+ {
+ this.anchor = anchor;
+ this.fill = fill;
+ this.gridx = gridx;
+ this.gridy = gridy;
+ this.gridwidth = gridwidth;
+ this.gridheight = gridheight;
+ this.ipadx = ipadx;
+ this.ipady = ipady;
+ this.insets = insets;
+ this.weightx = weightx;
+ this.weighty = weighty;
+ }
+}
diff --git a/libjava/classpath/java/awt/GridBagLayout.java b/libjava/classpath/java/awt/GridBagLayout.java
new file mode 100644
index 0000000..767610c
--- /dev/null
+++ b/libjava/classpath/java/awt/GridBagLayout.java
@@ -0,0 +1,1069 @@
+/* GridBagLayout - Layout manager for components according to GridBagConstraints
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ * @author Jeroen Frijters (jeroen@frijters.net)
+ */
+public class GridBagLayout
+ implements Serializable, LayoutManager2
+{
+ private static final long serialVersionUID = 8838754796412211005L;
+
+ protected static final int MINSIZE = 1;
+ protected static final int PREFERREDSIZE = 2;
+ protected static final int MAXGRIDSIZE = 512;
+
+ // comptable remembers the original contraints given to us.
+ // internalcomptable is used to keep track of modified constraint values
+ // that we calculate, particularly when we are given RELATIVE and
+ // REMAINDER constraints.
+ // Constraints kept in comptable are never modified, and constraints
+ // kept in internalcomptable can be modified internally only.
+ protected Hashtable comptable;
+ private Hashtable internalcomptable;
+ protected GridBagLayoutInfo layoutInfo;
+ protected GridBagConstraints defaultConstraints;
+
+ public double[] columnWeights;
+ public int[] columnWidths;
+ public double[] rowWeights;
+ public int[] rowHeights;
+
+ public GridBagLayout ()
+ {
+ this.comptable = new Hashtable();
+ this.internalcomptable = new Hashtable();
+ this.defaultConstraints= new GridBagConstraints();
+ }
+
+ /**
+ * Helper method to calc the sum of a range of elements in an int array.
+ */
+ private int sumIntArray (int[] array, int upto)
+ {
+ int result = 0;
+
+ for (int i = 0; i < upto; i++)
+ result += array [i];
+
+ return result;
+ }
+
+ /**
+ * Helper method to calc the sum of all elements in an int array.
+ */
+ private int sumIntArray (int[] array)
+ {
+ return sumIntArray(array, array.length);
+ }
+
+ /**
+ * Helper method to calc the sum of all elements in an double array.
+ */
+ private double sumDoubleArray (double[] array)
+ {
+ double result = 0;
+
+ for (int i = 0; i < array.length; i++)
+ result += array [i];
+
+ return result;
+ }
+
+ public void addLayoutComponent (String name, Component component)
+ {
+ // do nothing here.
+ }
+
+ public void removeLayoutComponent (Component component)
+ {
+ // do nothing here
+ }
+
+ public void addLayoutComponent (Component component, Object constraints)
+ {
+ if (constraints == null)
+ return;
+
+ if (!(constraints instanceof GridBagConstraints))
+ throw new IllegalArgumentException("constraints "
+ + constraints
+ + " are not an instance of GridBagConstraints");
+
+ setConstraints (component, (GridBagConstraints) constraints);
+ }
+
+ public Dimension preferredLayoutSize (Container parent)
+ {
+ if (parent == null)
+ return new Dimension (0, 0);
+
+ GridBagLayoutInfo li = getLayoutInfo (parent, PREFERREDSIZE);
+ return getMinSize (parent, li);
+ }
+
+ public Dimension minimumLayoutSize (Container parent)
+ {
+ if (parent == null)
+ return new Dimension (0, 0);
+
+ GridBagLayoutInfo li = getLayoutInfo (parent, MINSIZE);
+ return getMinSize (parent, li);
+ }
+
+ public Dimension maximumLayoutSize (Container target)
+ {
+ return new Dimension (Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+
+ public void layoutContainer (Container parent)
+ {
+ arrangeGrid (parent);
+ }
+
+ public float getLayoutAlignmentX (Container target)
+ {
+ return Component.CENTER_ALIGNMENT;
+ }
+
+ public float getLayoutAlignmentY (Container target)
+ {
+ return Component.CENTER_ALIGNMENT;
+ }
+
+ public void invalidateLayout (Container target)
+ {
+ this.layoutInfo = null;
+ }
+
+ public void setConstraints (Component component,
+ GridBagConstraints constraints)
+ {
+ GridBagConstraints clone = (GridBagConstraints) constraints.clone();
+
+ if (clone.gridx < 0)
+ clone.gridx = GridBagConstraints.RELATIVE;
+
+ if (clone.gridy < 0)
+ clone.gridy = GridBagConstraints.RELATIVE;
+
+ if (clone.gridwidth == 0)
+ clone.gridwidth = GridBagConstraints.REMAINDER;
+ else if (clone.gridwidth < 0
+ && clone.gridwidth != GridBagConstraints.REMAINDER
+ && clone.gridwidth != GridBagConstraints.RELATIVE)
+ clone.gridwidth = 1;
+
+ if (clone.gridheight == 0)
+ clone.gridheight = GridBagConstraints.REMAINDER;
+ else if (clone.gridheight < 0
+ && clone.gridheight != GridBagConstraints.REMAINDER
+ && clone.gridheight != GridBagConstraints.RELATIVE)
+ clone.gridheight = 1;
+
+ comptable.put (component, clone);
+ }
+
+ public GridBagConstraints getConstraints (Component component)
+ {
+ return (GridBagConstraints) (lookupConstraints (component).clone());
+ }
+
+ protected GridBagConstraints lookupConstraints (Component component)
+ {
+ GridBagConstraints result = (GridBagConstraints) comptable.get (component);
+
+ if (result == null)
+ {
+ setConstraints (component, defaultConstraints);
+ result = (GridBagConstraints) comptable.get (component);
+ }
+
+ return result;
+ }
+
+ private GridBagConstraints lookupInternalConstraints (Component component)
+ {
+ GridBagConstraints result =
+ (GridBagConstraints) internalcomptable.get (component);
+
+ if (result == null)
+ {
+ result = (GridBagConstraints) lookupConstraints(component).clone();
+ internalcomptable.put (component, result);
+ }
+
+ return result;
+ }
+
+ /**
+ * @since 1.1
+ */
+ public Point getLayoutOrigin ()
+ {
+ if (layoutInfo == null)
+ return new Point (0, 0);
+
+ return new Point (layoutInfo.pos_x, layoutInfo.pos_y);
+ }
+
+ /**
+ * @since 1.1
+ */
+ public int[][] getLayoutDimensions ()
+ {
+ int[][] result = new int [2][];
+ if (layoutInfo == null)
+ {
+ result[0] = new int[0];
+ result[1] = new int[0];
+
+ return result;
+ }
+
+ result [0] = new int [layoutInfo.cols];
+ System.arraycopy (layoutInfo.colWidths, 0, result [0], 0, layoutInfo.cols);
+ result [1] = new int [layoutInfo.rows];
+ System.arraycopy (layoutInfo.rowHeights, 0, result [1], 0, layoutInfo.rows);
+ return result;
+ }
+
+ public double[][] getLayoutWeights ()
+ {
+ double[][] result = new double [2][];
+ if (layoutInfo == null)
+ {
+ result[0] = new double[0];
+ result[1] = new double[0];
+
+ return result;
+ }
+
+ result [0] = new double [layoutInfo.cols];
+ System.arraycopy (layoutInfo.colWeights, 0, result [0], 0, layoutInfo.cols);
+ result [1] = new double [layoutInfo.rows];
+ System.arraycopy (layoutInfo.rowWeights, 0, result [1], 0, layoutInfo.rows);
+ return result;
+ }
+
+ /**
+ * @since 1.1
+ */
+ public Point location (int x, int y)
+ {
+ if (layoutInfo == null)
+ return new Point (0, 0);
+
+ int col;
+ int row;
+ int pixel_x = layoutInfo.pos_x;
+ int pixel_y = layoutInfo.pos_y;
+
+ for (col = 0; col < layoutInfo.cols; col++)
+ {
+ int w = layoutInfo.colWidths [col];
+ if (x < pixel_x + w)
+ break;
+
+ pixel_x += w;
+ }
+
+ for (row = 0; row < layoutInfo.rows; row++)
+ {
+ int h = layoutInfo.rowHeights [row];
+ if (y < pixel_y + h)
+ break;
+
+ pixel_y += h;
+ }
+
+ return new Point (col, row);
+ }
+
+ /**
+ * Obsolete.
+ */
+ protected void AdjustForGravity (GridBagConstraints gbc, Rectangle rect)
+ {
+ // FIXME
+ throw new Error ("Not implemented");
+ }
+
+ /**
+ * Obsolete.
+ */
+ protected void ArrangeGrid (Container parent)
+ {
+ Component[] components = parent.getComponents();
+
+ if (components.length == 0)
+ return;
+
+ GridBagLayoutInfo info = getLayoutInfo (parent, PREFERREDSIZE);
+ if (info.cols == 0 && info.rows == 0)
+ return;
+ layoutInfo = info;
+
+ // DEBUG
+ //dumpLayoutInfo (layoutInfo);
+
+ for(int i = 0; i < components.length; i++)
+ {
+ Component component = components [i];
+
+ // If component is not visible we dont have to care about it.
+ if (!component.isVisible())
+ continue;
+
+ GridBagConstraints constraints =
+ lookupInternalConstraints(component);
+
+ int cellx = sumIntArray(layoutInfo.colWidths, constraints.gridx);
+ int celly = sumIntArray(layoutInfo.rowHeights, constraints.gridy);
+ int cellw = sumIntArray(layoutInfo.colWidths,
+ constraints.gridx + constraints.gridwidth) - cellx;
+ int cellh = sumIntArray(layoutInfo.rowHeights,
+ constraints.gridy + constraints.gridheight) - celly;
+
+ Insets insets = constraints.insets;
+ if (insets != null)
+ {
+ cellx += insets.left;
+ celly += insets.top;
+ cellw -= insets.left + insets.right;
+ cellh -= insets.top + insets.bottom;
+ }
+
+ Dimension dim = component.getPreferredSize();
+
+ // Note: Documentation says that padding is added on both sides, but
+ // visual inspection shows that the Sun implementation only adds it
+ // once, so we do the same.
+ dim.width += constraints.ipadx;
+ dim.height += constraints.ipady;
+
+ switch(constraints.fill)
+ {
+ case GridBagConstraints.HORIZONTAL:
+ dim.width = cellw;
+ break;
+ case GridBagConstraints.VERTICAL:
+ dim.height = cellh;
+ break;
+ case GridBagConstraints.BOTH:
+ dim.width = cellw;
+ dim.height = cellh;
+ break;
+ }
+
+ int x;
+ int y;
+
+ switch(constraints.anchor)
+ {
+ case GridBagConstraints.NORTH:
+ x = cellx + (cellw - dim.width) / 2;
+ y = celly;
+ break;
+ case GridBagConstraints.SOUTH:
+ x = cellx + (cellw - dim.width) / 2;
+ y = celly + cellh - dim.height;
+ break;
+ case GridBagConstraints.WEST:
+ x = cellx;
+ y = celly + (cellh - dim.height) / 2;
+ break;
+ case GridBagConstraints.EAST:
+ x = cellx + cellw - dim.width;
+ y = celly + (cellh - dim.height) / 2;
+ break;
+ case GridBagConstraints.NORTHEAST:
+ x = cellx + cellw - dim.width;
+ y = celly;
+ break;
+ case GridBagConstraints.NORTHWEST:
+ x = cellx;
+ y = celly;
+ break;
+ case GridBagConstraints.SOUTHEAST:
+ x = cellx + cellw - dim.width;
+ y = celly + cellh - dim.height;
+ break;
+ case GridBagConstraints.SOUTHWEST:
+ x = cellx;
+ y = celly + cellh - dim.height;
+ break;
+ default:
+ x = cellx + (cellw - dim.width) / 2;
+ y = celly + (cellh - dim.height) / 2;
+ break;
+ }
+
+ component.setBounds(layoutInfo.pos_x + x, layoutInfo.pos_y + y, dim.width, dim.height);
+ }
+
+ // DEBUG
+ //dumpLayoutInfo (layoutInfo);
+ }
+
+ /**
+ * Obsolete.
+ */
+ protected GridBagLayoutInfo GetLayoutInfo (Container parent, int sizeflag)
+ {
+ if (sizeflag != MINSIZE && sizeflag != PREFERREDSIZE)
+ throw new IllegalArgumentException();
+
+ Dimension parentDim = parent.getSize ();
+ Insets parentInsets = parent.getInsets ();
+ parentDim.width -= parentInsets.left + parentInsets.right;
+ parentDim.height -= parentInsets.top + parentInsets.bottom;
+
+ int current_y = 0;
+ int max_x = 0;
+ int max_y = 0;
+
+ // Guaranteed to contain the last component added to the given row
+ // or column, whose gridwidth/height is not REMAINDER.
+ HashMap lastInRow = new HashMap();
+ HashMap lastInCol = new HashMap();
+
+ Component[] components = parent.getComponents();
+
+ // Components sorted by gridwidths/heights,
+ // smallest to largest, with REMAINDER and RELATIVE at the end.
+ // These are useful when determining sizes and weights.
+ ArrayList sortedByWidth = new ArrayList(components.length);
+ ArrayList sortedByHeight = new ArrayList(components.length);
+
+ // STEP 1: first we figure out how many rows/columns
+ for (int i = 0; i < components.length; i++)
+ {
+ Component component = components [i];
+
+ // If component is not visible we dont have to care about it.
+ if (!component.isVisible())
+ continue;
+
+ // When looking up the constraint for the first time, check the
+ // original unmodified constraint. After the first time, always
+ // refer to the internal modified constraint.
+ GridBagConstraints originalConstraints = lookupConstraints (component);
+ GridBagConstraints constraints = (GridBagConstraints) originalConstraints.clone();
+ internalcomptable.put(component, constraints);
+
+ // Cases:
+ //
+ // 1. gridy == RELATIVE, gridx == RELATIVE
+ //
+ // use y as the row number; check for the next
+ // available slot at row y
+ //
+ // 2. only gridx == RELATIVE
+ //
+ // check for the next available slot at row gridy
+ //
+ // 3. only gridy == RELATIVE
+ //
+ // check for the next available slot at column gridx
+ //
+ // 4. neither gridx or gridy == RELATIVE
+ //
+ // nothing to check; just add it
+
+
+ // cases 1 and 2
+ if(constraints.gridx == GridBagConstraints.RELATIVE)
+ {
+ if (constraints.gridy == GridBagConstraints.RELATIVE)
+ constraints.gridy = current_y;
+
+ int x;
+
+ // Check the component that occupies the right-most spot in this
+ // row. We want to add this component after it.
+ // If this row is empty, add to the 0 position.
+ if (!lastInRow.containsKey(new Integer(constraints.gridy)))
+ x = 0;
+ else
+ {
+ Component lastComponent = (Component) lastInRow.get(new Integer(constraints.gridy));
+ GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+ x = lastConstraints.gridx + Math.max(1, lastConstraints.gridwidth);
+ }
+
+ // Determine if this component will fit in the slot vertically.
+ // If not, bump it over to where it does fit.
+ for (int y = constraints.gridy + 1; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
+ {
+ if (lastInRow.containsKey(new Integer(y)))
+ {
+ Component lastComponent = (Component) lastInRow.get(new Integer(y));
+ GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+ x = Math.max (x,
+ lastConstraints.gridx + Math.max(1, lastConstraints.gridwidth));
+ }
+ }
+
+ constraints.gridx = x;
+ }
+ // case 3
+ else if(constraints.gridy == GridBagConstraints.RELATIVE)
+ {
+ int y;
+ // Check the component that occupies the bottom-most spot in
+ // this column. We want to add this component below it.
+ // If this column is empty, add to the 0 position.
+ if (!lastInCol.containsKey(new Integer(constraints.gridx)))
+ y = 0;
+ else
+ {
+ Component lastComponent = (Component)lastInCol.get(new Integer(constraints.gridx));
+ GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+ y = lastConstraints.gridy + Math.max(1, lastConstraints.gridheight);
+ }
+
+ // Determine if this component will fit in the slot horizontally.
+ // If not, bump it down to where it does fit.
+ for (int x = constraints.gridx + 1; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
+ {
+ if (lastInCol.containsKey(new Integer(x)))
+ {
+ Component lastComponent = (Component) lastInCol.get(new Integer(x));
+ GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+ y = Math.max (y,
+ lastConstraints.gridy + Math.max(1, lastConstraints.gridheight));
+ }
+ }
+
+ constraints.gridy = y;
+ }
+ // case 4: do nothing
+
+ max_x = Math.max(max_x,
+ constraints.gridx + Math.max(1, constraints.gridwidth));
+ max_y = Math.max(max_y,
+ constraints.gridy + Math.max(1, constraints.gridheight));
+
+ sortBySpan(component, constraints.gridwidth, sortedByWidth, true);
+ sortBySpan(component, constraints.gridheight, sortedByHeight, false);
+
+ // Update our reference points for RELATIVE gridx and gridy.
+ if(constraints.gridwidth == GridBagConstraints.REMAINDER)
+ {
+ current_y = constraints.gridy + Math.max(1, constraints.gridheight);
+ }
+ else if (constraints.gridwidth != GridBagConstraints.REMAINDER)
+ {
+ for (int y = constraints.gridy; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
+ {
+ if(lastInRow.containsKey(new Integer(y)))
+ {
+ Component lastComponent = (Component) lastInRow.get(new Integer(y));
+ GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+ if (constraints.gridx > lastConstraints.gridx)
+ {
+ lastInRow.put(new Integer(y), component);
+ }
+ }
+ else
+ {
+ lastInRow.put(new Integer(y), component);
+ }
+ }
+
+ for (int x = constraints.gridx; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
+ {
+ if(lastInCol.containsKey(new Integer(x)))
+ {
+ Component lastComponent = (Component) lastInCol.get(new Integer(x));
+ GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+ if (constraints.gridy > lastConstraints.gridy)
+ {
+ lastInCol.put(new Integer(x), component);
+ }
+ }
+ else
+ {
+ lastInCol.put(new Integer(x), component);
+ }
+ }
+ }
+ } // end of STEP 1
+
+ GridBagLayoutInfo info = new GridBagLayoutInfo(max_x, max_y);
+
+ // Check if column widths and row heights are overridden.
+
+ for (int x = 0; x < max_x; x++)
+ {
+ if(columnWidths != null && columnWidths.length > x)
+ info.colWidths[x] = columnWidths[x];
+ if(columnWeights != null && columnWeights.length > x)
+ info.colWeights[x] = columnWeights[x];
+ }
+
+ for (int y = 0; y < max_y; y++)
+ {
+ if(rowHeights != null && rowHeights.length > y)
+ info.rowHeights[y] = rowHeights[y];
+ if(rowWeights != null && rowWeights.length > y)
+ info.rowWeights[y] = rowWeights[y];
+ }
+
+ // STEP 2: Fix up any cells with width/height as REMAINDER/RELATIVE.
+ for (int i = 0; i < components.length; i++)
+ {
+ Component component = components [i];
+
+ // If component is not visible we dont have to care about it.
+ if (!component.isVisible())
+ continue;
+
+ GridBagConstraints constraints = lookupInternalConstraints (component);
+
+ if(constraints.gridwidth == GridBagConstraints.REMAINDER || constraints.gridwidth == GridBagConstraints.RELATIVE)
+ {
+ if(constraints.gridwidth == GridBagConstraints.REMAINDER)
+ {
+ for (int y = constraints.gridy; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
+ {
+ if (lastInRow.containsKey(new Integer(y)))
+ {
+ Component lastComponent = (Component) lastInRow.get(new Integer(y));
+ GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+
+ if (lastConstraints.gridwidth == GridBagConstraints.RELATIVE)
+ {
+ constraints.gridx = max_x - 1;
+ break;
+ }
+ else
+ {
+ constraints.gridx = Math.max (constraints.gridx,
+ lastConstraints.gridx + Math.max (1, lastConstraints.gridwidth));
+ }
+ }
+ }
+ constraints.gridwidth = max_x - constraints.gridx;
+ }
+ else if (constraints.gridwidth == GridBagConstraints.RELATIVE)
+ {
+ constraints.gridwidth = max_x - constraints.gridx - 1;
+ }
+
+ // Re-sort
+ sortedByWidth.remove(sortedByWidth.indexOf(component));
+ sortBySpan(component, constraints.gridwidth, sortedByWidth, true);
+ }
+
+ if(constraints.gridheight == GridBagConstraints.REMAINDER || constraints.gridheight == GridBagConstraints.RELATIVE)
+ {
+ if(constraints.gridheight == GridBagConstraints.REMAINDER)
+ {
+ for (int x = constraints.gridx; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
+ {
+ if (lastInCol.containsKey(new Integer(x)))
+ {
+ Component lastComponent = (Component) lastInRow.get(new Integer(x));
+ GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+
+ if (lastConstraints.gridheight == GridBagConstraints.RELATIVE)
+ {
+ constraints.gridy = max_y - 1;
+ break;
+ }
+ else
+ {
+ constraints.gridy = Math.max (constraints.gridy,
+ lastConstraints.gridy + Math.max (1, lastConstraints.gridheight));
+ }
+ }
+ }
+ constraints.gridheight = max_y - constraints.gridy;
+ }
+ else if (constraints.gridheight == GridBagConstraints.RELATIVE)
+ {
+ constraints.gridheight = max_y - constraints.gridy - 1;
+ }
+
+ // Re-sort
+ sortedByHeight.remove(sortedByHeight.indexOf(component));
+ sortBySpan(component, constraints.gridheight, sortedByHeight, false);
+ }
+ } // end of STEP 2
+
+ // STEP 3: Determine sizes and weights for columns.
+ for (int i = 0; i < sortedByWidth.size(); i++)
+ {
+ Component component = (Component) sortedByWidth.get(i);
+
+ // If component is not visible we dont have to care about it.
+ if (!component.isVisible())
+ continue;
+
+ GridBagConstraints constraints = lookupInternalConstraints (component);
+
+ int width = (sizeflag == PREFERREDSIZE) ?
+ component.getPreferredSize().width :
+ component.getMinimumSize().width;
+
+ if(constraints.insets != null)
+ width += constraints.insets.left + constraints.insets.right;
+
+ width += constraints.ipadx;
+
+ distributeSizeAndWeight(width,
+ constraints.weightx,
+ constraints.gridx,
+ constraints.gridwidth,
+ info.colWidths,
+ info.colWeights);
+ } // end of STEP 3
+
+ // STEP 4: Determine sizes and weights for rows.
+ for (int i = 0; i < sortedByHeight.size(); i++)
+ {
+ Component component = (Component) sortedByHeight.get(i);
+
+ // If component is not visible we dont have to care about it.
+ if (!component.isVisible())
+ continue;
+
+ GridBagConstraints constraints = lookupInternalConstraints (component);
+
+ int height = (sizeflag == PREFERREDSIZE) ?
+ component.getPreferredSize().height :
+ component.getMinimumSize().height;
+
+ if(constraints.insets != null)
+ height += constraints.insets.top + constraints.insets.bottom;
+
+ height += constraints.ipady;
+
+ distributeSizeAndWeight(height,
+ constraints.weighty,
+ constraints.gridy,
+ constraints.gridheight,
+ info.rowHeights,
+ info.rowWeights);
+ } // end of STEP 4
+
+ // Adjust cell sizes iff parent size not zero.
+ if (parentDim.width > 0 && parentDim.height > 0)
+ {
+ calcCellSizes (info.colWidths, info.colWeights, parentDim.width);
+ calcCellSizes (info.rowHeights, info.rowWeights, parentDim.height);
+ }
+
+ int totalWidth = sumIntArray(info.colWidths);
+ int totalHeight = sumIntArray(info.rowHeights);
+
+ // Make sure pos_x and pos_y are never negative.
+ if (totalWidth >= parentDim.width)
+ info.pos_x = parentInsets.left;
+ else
+ info.pos_x = parentInsets.left + (parentDim.width - totalWidth) / 2;
+
+ if (totalHeight >= parentDim.height)
+ info.pos_y = parentInsets.top;
+ else
+ info.pos_y = parentInsets.top + (parentDim.height - totalHeight) / 2;
+
+ // DEBUG
+ //dumpLayoutInfo (info);
+
+ return info;
+ }
+
+ /**
+ * Obsolete.
+ */
+ protected Dimension GetMinSize (Container parent, GridBagLayoutInfo info)
+ {
+ if (parent == null || info == null)
+ return new Dimension (0, 0);
+
+ Insets insets = parent.getInsets();
+ int width = sumIntArray (info.colWidths) + insets.left + insets.right;
+ int height = sumIntArray (info.rowHeights) + insets.top + insets.bottom;
+ return new Dimension (width, height);
+ }
+
+ /**
+ * @since 1.4
+ */
+ protected Dimension getMinSize (Container parent, GridBagLayoutInfo info)
+ {
+ return GetMinSize (parent, info);
+ }
+
+ /**
+ * Helper method used by GetLayoutInfo to keep components sorted, either
+ * by gridwidth or gridheight.
+ *
+ * @param component Component to add to the sorted list.
+ * @param span Either the component's gridwidth or gridheight.
+ * @param list <code>ArrayList</code> of components, sorted by
+ * their span.
+ * @param sortByWidth Flag indicating sorting index. If true, sort by
+ * width. Otherwise, sort by height.
+ * FIXME: Use a better sorting algorithm.
+ */
+ private void sortBySpan (Component component, int span, ArrayList list, boolean sortByWidth)
+ {
+ if (span == GridBagConstraints.REMAINDER
+ || span == GridBagConstraints.RELATIVE)
+ {
+ // Put all RELATIVE and REMAINDER components at the end.
+ list.add(component);
+ }
+ else
+ {
+ int i = 0;
+ if (list.size() > 0)
+ {
+ GridBagConstraints gbc = lookupInternalConstraints((Component) list.get(i));
+ int otherspan = sortByWidth ?
+ gbc.gridwidth :
+ gbc.gridheight;
+ while (otherspan != GridBagConstraints.REMAINDER
+ && otherspan != GridBagConstraints.RELATIVE
+ && span >= otherspan)
+ {
+ i++;
+ if (i < list.size())
+ {
+ gbc = lookupInternalConstraints((Component) list.get(i));
+ otherspan = sortByWidth ?
+ gbc.gridwidth :
+ gbc.gridheight;
+ }
+ else
+ break;
+ }
+ }
+ list.add(i, component);
+ }
+ }
+
+ /**
+ * Helper method used by GetLayoutInfo to distribute a component's size
+ * and weight.
+ *
+ * @param size Preferred size of component, with inset and padding
+ * already added.
+ * @param weight Weight of component.
+ * @param start Starting position of component. Either
+ * constraints.gridx or gridy.
+ * @param span Span of component. either contraints.gridwidth or
+ * gridheight.
+ * @param sizes Sizes of rows or columns.
+ * @param weights Weights of rows or columns.
+ */
+ private void distributeSizeAndWeight (int size, double weight,
+ int start, int span,
+ int[] sizes, double[] weights)
+ {
+ if (span == 1)
+ {
+ sizes[start] = Math.max(sizes[start], size);
+ weights[start] = Math.max(weights[start], weight);
+ }
+ else
+ {
+ int numOccupied = span;
+ int lastOccupied = -1;
+
+ for(int i = start; i < start + span; i++)
+ {
+ if (sizes[i] == 0.0)
+ numOccupied--;
+ else
+ {
+ size -= sizes[i];
+ lastOccupied = i;
+ }
+ }
+
+ // A component needs to occupy at least one row.
+ if(numOccupied == 0)
+ sizes[start + span - 1] = size;
+ else if (size > 0)
+ sizes[lastOccupied] += size;
+
+ calcCellWeights(weight, weights, start, span);
+ }
+ }
+
+ /**
+ * Helper method used by GetLayoutInfo to calculate weight distribution.
+ * @param weight Weight of component.
+ * @param weights Weights of rows/columns.
+ * @param start Starting position of component in grid (gridx/gridy).
+ * @param span Span of component (gridwidth/gridheight).
+ */
+ private void calcCellWeights (double weight, double[] weights, int start, int span)
+ {
+ double totalWeight = 0.0;
+ for(int k = start; k < start + span; k++)
+ totalWeight += weights[k];
+
+ if(weight > totalWeight)
+ {
+ if (totalWeight == 0.0)
+ {
+ weights[start + span - 1] += weight;
+ }
+ else
+ {
+ double diff = weight - totalWeight ;
+ double remaining = diff;
+
+ for(int k = start; k < start + span; k++)
+ {
+ double extraWeight = diff * weights[k] / totalWeight;
+ weights[k] += extraWeight;
+ remaining -= extraWeight;
+ }
+
+ if (remaining > 0.0 && weights[start + span - 1] != 0.0)
+ {
+ weights[start + span - 1] += remaining;
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper method used by GetLayoutInfo to distribute extra space
+ * based on weight distribution.
+ *
+ * @param sizes Sizes of rows/columns.
+ * @param weights Weights of rows/columns.
+ * @param range Dimension of container.
+ */
+ private void calcCellSizes (int[] sizes, double[] weights, int range)
+ {
+ int totalSize = sumIntArray (sizes);
+ double totalWeight = sumDoubleArray (weights);
+
+ int diff = range - totalSize;
+
+ if (diff == 0)
+ return;
+
+ for (int i = 0; i < sizes.length; i++)
+ {
+ int newsize = (int) (sizes[i] + (((double) diff) * weights [i] / totalWeight ));
+
+ if (newsize > 0)
+ sizes[i] = newsize;
+ }
+ }
+
+ private void dumpLayoutInfo (GridBagLayoutInfo info)
+ {
+ System.out.println ("GridBagLayoutInfo:");
+ System.out.println ("cols: " + info.cols + ", rows: " + info.rows);
+ System.out.print ("colWidths: ");
+ dumpArray(info.colWidths);
+ System.out.print ("rowHeights: ");
+ dumpArray(info.rowHeights);
+ System.out.print ("colWeights: ");
+ dumpArray(info.colWeights);
+ System.out.print ("rowWeights: ");
+ dumpArray(info.rowWeights);
+ }
+
+ private void dumpArray(int[] array)
+ {
+ String sep = "";
+ for(int i = 0; i < array.length; i++)
+ {
+ System.out.print(sep);
+ System.out.print(array[i]);
+ sep = ", ";
+ }
+ System.out.println();
+ }
+
+ private void dumpArray(double[] array)
+ {
+ String sep = "";
+ for(int i = 0; i < array.length; i++)
+ {
+ System.out.print(sep);
+ System.out.print(array[i]);
+ sep = ", ";
+ }
+ System.out.println();
+ }
+
+ /**
+ * @since 1.4
+ */
+ protected void arrangeGrid (Container parent)
+ {
+ ArrangeGrid (parent);
+ }
+
+ /**
+ * @since 1.4
+ */
+ protected GridBagLayoutInfo getLayoutInfo (Container parent, int sizeflag)
+ {
+ return GetLayoutInfo (parent, sizeflag);
+ }
+
+ /**
+ * @since 1.4
+ */
+ protected void adjustForGravity (GridBagConstraints gbc, Rectangle rect)
+ {
+ AdjustForGravity (gbc, rect);
+ }
+}
diff --git a/libjava/classpath/java/awt/GridBagLayoutInfo.java b/libjava/classpath/java/awt/GridBagLayoutInfo.java
new file mode 100644
index 0000000..43ba09d
--- /dev/null
+++ b/libjava/classpath/java/awt/GridBagLayoutInfo.java
@@ -0,0 +1,70 @@
+/* GridBagLayoutInfo -
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ */
+class GridBagLayoutInfo implements Serializable
+{
+ private static final long serialVersionUID = -4899416460737170217L;
+
+ int pos_x;
+ int pos_y;
+ int cols;
+ int rows;
+ int colWidths[];
+ int rowHeights[];
+ double colWeights[];
+ double rowWeights[];
+
+ GridBagLayoutInfo (int cols, int rows)
+ {
+ this.pos_x = 0;
+ this.pos_y = 0;
+ this.cols = cols;
+ this.rows = rows;
+ this.colWidths = new int [cols];
+ this.rowHeights = new int [rows];
+ this.colWeights = new double [cols];
+ this.rowWeights = new double [rows];
+ }
+}
diff --git a/libjava/classpath/java/awt/GridLayout.java b/libjava/classpath/java/awt/GridLayout.java
new file mode 100644
index 0000000..80d9641
--- /dev/null
+++ b/libjava/classpath/java/awt/GridLayout.java
@@ -0,0 +1,360 @@
+/* GridLayout.java -- Grid-based layout engine
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+
+/** This class implements a grid-based layout scheme. Components are
+ * all given the same size and are laid out from left to right and top
+ * to bottom. A GridLayout is configured with a number of rows and a
+ * number of columns. If both are specified, then the number of
+ * columns is ignored and is derived from the number of rows and the
+ * total number of components. If either is zero then that dimension
+ * is computed based on the actual size of the container. An
+ * exception is thrown if an attempt is made to set both the number of
+ * rows and the number of columns to 0. This class also supports
+ * horizontal and vertical gaps; these are used as spacing between
+ * cells.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class GridLayout implements LayoutManager, Serializable
+{
+ static final long serialVersionUID = -7411804673224730901L;
+
+ /** Add a new component to the layout. This particular implementation
+ * does nothing.
+ * @param name The name of the component to add.
+ * @param comp The component to add.
+ */
+ public void addLayoutComponent (String name, Component comp)
+ {
+ // Nothing.
+ }
+
+ /** Return the number of columns in this layout. */
+ public int getColumns ()
+ {
+ return cols;
+ }
+
+ /** Return the horizontal gap. */
+ public int getHgap ()
+ {
+ return hgap;
+ }
+
+ /** Return the number of rows in this layout. */
+ public int getRows ()
+ {
+ return rows;
+ }
+
+ /** Return the vertical gap. */
+ public int getVgap ()
+ {
+ return vgap;
+ }
+
+ /** Create a new <code>GridLayout</code> with one row and any number
+ * of columns. Both gaps are set to 0.
+ */
+ public GridLayout ()
+ {
+ this (1, 0, 0, 0);
+ }
+
+ /** Create a new <code>GridLayout</code> with the specified number
+ * of rows and columns. Both gaps are set to 0. Note that the row
+ * and column settings cannot both be zero. If both the row and
+ * column values are non-zero, the rows value takes precedence.
+ * @param rows Number of rows
+ * @param cols Number of columns
+ * @exception IllegalArgumentException If rows and columns are both
+ * 0, or if either are negative
+ */
+ public GridLayout (int rows, int cols)
+ {
+ this (rows, cols, 0, 0);
+ }
+
+ /** Create a new GridLayout with the specified number of rows and
+ * columns and the specified gaps.
+ * Note that the row and column settings cannot both be
+ * zero. If both the row and column values are non-zero, the rows value
+ * takes precedence.
+ * @param rows Number of rows
+ * @param cols Number of columns
+ * @param hgap The horizontal gap
+ * @param vgap The vertical gap
+ * @exception IllegalArgumentException If rows and columns are both
+ * 0, if either are negative, or if either gap is negative
+ */
+ public GridLayout (int rows, int cols, int hgap, int vgap)
+ {
+ if (rows < 0)
+ throw new IllegalArgumentException ("number of rows cannot be negative");
+ if (cols < 0)
+ throw new IllegalArgumentException ("number of columns cannot be negative");
+ if (rows == 0 && cols == 0)
+ throw new IllegalArgumentException ("both rows and columns cannot be 0");
+ if (hgap < 0)
+ throw new IllegalArgumentException ("horizontal gap must be nonnegative");
+ if (vgap < 0)
+ throw new IllegalArgumentException ("vertical gap must be nonnegative");
+ this.rows = rows;
+ this.cols = cols;
+ this.hgap = hgap;
+ this.vgap = vgap;
+ }
+
+ /** Lay out the container's components based on current settings.
+ * The free space in the container is divided evenly into the specified
+ * number of rows and columns in this object.
+ * @param parent The container to lay out
+ */
+ public void layoutContainer (Container parent)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int num = parent.ncomponents;
+
+ // There's no point, and handling this would mean adding special
+ // cases.
+ if (num == 0)
+ return;
+
+ // This is more efficient than calling getComponents().
+ Component[] comps = parent.component;
+
+ int real_rows = rows;
+ int real_cols = cols;
+ if (real_rows == 0)
+ real_rows = (num + real_cols - 1) / real_cols;
+ else
+ real_cols = (num + real_rows - 1) / real_rows;
+
+ // We might have less than a single row. In this case we expand
+ // to fill.
+ if (num < real_cols)
+ real_cols = num;
+
+ Dimension d = parent.getSize ();
+ Insets ins = parent.getInsets ();
+
+ // Compute width and height of each cell in the grid.
+ int tw = d.width - ins.left - ins.right;
+ tw = (tw - (real_cols - 1) * hgap) / real_cols;
+ int th = d.height - ins.top - ins.bottom;
+ th = (th - (real_rows - 1) * vgap) / real_rows;
+
+ // If the cells are too small, still try to do something.
+ if (tw < 0)
+ tw = 1;
+ if (th < 0)
+ th = 1;
+
+ int x = ins.left;
+ int y = ins.top;
+ int i = 0;
+ int recount = 0;
+
+ while (i < num)
+ {
+ comps[i].setBounds (x, y, tw, th);
+
+ ++i;
+ ++recount;
+ if (recount == real_cols)
+ {
+ recount = 0;
+ y += vgap + th;
+ x = ins.left;
+ }
+ else
+ x += hgap + tw;
+ }
+ }
+ }
+
+ /** Get the minimum layout size of the container.
+ * @param cont The parent container
+ */
+ public Dimension minimumLayoutSize (Container cont)
+ {
+ return getSize (cont, true);
+ }
+
+ /** Get the preferred layout size of the container.
+ * @param cont The parent container
+ */
+ public Dimension preferredLayoutSize (Container cont)
+ {
+ return getSize (cont, false);
+ }
+
+ /** Remove the indicated component from this layout manager.
+ * This particular implementation does nothing.
+ * @param comp The component to remove
+ */
+ public void removeLayoutComponent (Component comp)
+ {
+ // Nothing.
+ }
+
+ /** Set the number of columns.
+ * @param newCols
+ * @exception IllegalArgumentException If the number of columns is
+ * negative, or if the number of columns is zero and the number
+ * of rows is already 0.
+ */
+ public void setColumns (int newCols)
+ {
+ if (newCols < 0)
+ throw new IllegalArgumentException ("number of columns cannot be negative");
+ if (newCols == 0 && rows == 0)
+ throw new IllegalArgumentException ("number of rows is already 0");
+ this.cols = newCols;
+ }
+
+ /** Set the horizontal gap
+ * @param hgap The horizontal gap
+ * @exception IllegalArgumentException If the hgap value is less than zero.
+ */
+ public void setHgap (int hgap)
+ {
+ if (hgap < 0)
+ throw new IllegalArgumentException ("horizontal gap must be nonnegative");
+ this.hgap = hgap;
+ }
+
+ /** Set the number of rows
+ * @param newRows
+ * @exception IllegalArgumentException If the number of rows is
+ * negative, or if the number of rows is zero and the number
+ * of columns is already 0.
+ */
+ public void setRows (int newRows)
+ {
+ if (newRows < 0)
+ throw new IllegalArgumentException ("number of rows cannot be negative");
+ if (newRows == 0 && cols == 0)
+ throw new IllegalArgumentException ("number of columns is already 0");
+ this.rows = newRows;
+ }
+
+ /** Set the vertical gap.
+ * @param vgap The vertical gap
+ * @exception IllegalArgumentException If the vgap value is less than zero.
+ */
+ public void setVgap (int vgap)
+ {
+ if (vgap < 0)
+ throw new IllegalArgumentException ("vertical gap must be nonnegative");
+ this.vgap = vgap;
+ }
+
+ /** Return String description of this object. */
+ public String toString ()
+ {
+ return ("[" + getClass ().getName ()
+ + ",hgap=" + hgap + ",vgap=" + vgap
+ + ",rows=" + rows + ",cols=" + cols
+ + "]");
+ }
+
+ // This method is used to compute the various sizes.
+ private Dimension getSize (Container parent, boolean is_min)
+ {
+ synchronized (parent.getTreeLock ())
+ {
+ int w = 0, h = 0, num = parent.ncomponents;
+ // This is more efficient than calling getComponents().
+ Component[] comps = parent.component;
+
+ for (int i = 0; i < num; ++i)
+ {
+ Dimension d;
+
+ if (is_min)
+ d = comps[i].getMinimumSize ();
+ else
+ d = comps[i].getPreferredSize ();
+
+ w = Math.max (d.width, w);
+ h = Math.max (d.height, h);
+ }
+
+ int real_rows = rows;
+ int real_cols = cols;
+ if (real_rows == 0)
+ real_rows = (num + real_cols - 1) / real_cols;
+ else
+ real_cols = (num + real_rows - 1) / real_rows;
+
+ Insets ins = parent.getInsets ();
+ // We subtract out an extra gap here because the gaps are only
+ // between cells.
+ w = ins.left + ins.right + real_cols * (w + hgap) - hgap;
+ h = ins.top + ins.bottom + real_rows * (h + vgap) - vgap;
+ return new Dimension (w, h);
+ }
+ }
+
+ /**
+ * @serial The number of columns in the grid.
+ */
+ private int cols;
+
+ /**
+ * @serial The number of rows in the grid.
+ */
+ private int rows;
+
+ /**
+ * @serial The horizontal gap between columns
+ */
+ private int hgap;
+
+ /**
+ * @serial The vertical gap between rows
+ */
+ private int vgap;
+}
diff --git a/libjava/classpath/java/awt/HeadlessException.java b/libjava/classpath/java/awt/HeadlessException.java
new file mode 100644
index 0000000..b180b1d
--- /dev/null
+++ b/libjava/classpath/java/awt/HeadlessException.java
@@ -0,0 +1,72 @@
+/* HeadlessException.java -- operation not possible in headless environment
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This exception is thrown when code dependent on a keyboard, mouse, or
+ * display is executed in a headless environment.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public class HeadlessException extends UnsupportedOperationException
+{
+ /**
+ * Compatible with JDK 1.4+.
+ */
+ private static final long serialVersionUID = 167183644944358563L;
+
+ /**
+ * Create a new instance with no detailed error message.
+ */
+ public HeadlessException()
+ {
+ }
+
+ /**
+ * Create a new instance with the specified detailed error message.
+ *
+ * @param message the detailed error message
+ */
+ public HeadlessException(String message)
+ {
+ super(message);
+ }
+} // class HeadlessException
diff --git a/libjava/classpath/java/awt/IllegalComponentStateException.java b/libjava/classpath/java/awt/IllegalComponentStateException.java
new file mode 100644
index 0000000..4a47f1d
--- /dev/null
+++ b/libjava/classpath/java/awt/IllegalComponentStateException.java
@@ -0,0 +1,71 @@
+/* IllegalComponentStateException.java -- bad component state
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This exception is thrown when the requested operation failed because
+ * a component was not in the proper state.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @status updated to 1.4
+ */
+public class IllegalComponentStateException extends IllegalStateException
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -1889339587208144238L;
+
+ /**
+ * Create a new instance with no detailed error message.
+ */
+ public IllegalComponentStateException()
+ {
+ }
+
+ /**
+ * Create a new instance with the specified detailed error message.
+ *
+ * @param message the detailed error message
+ */
+ public IllegalComponentStateException(String message)
+ {
+ super(message);
+ }
+} // class IllegalComponentStateException
diff --git a/libjava/classpath/java/awt/Image.java b/libjava/classpath/java/awt/Image.java
new file mode 100644
index 0000000..b657ad0
--- /dev/null
+++ b/libjava/classpath/java/awt/Image.java
@@ -0,0 +1,203 @@
+/* Image.java -- superclass for images
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.FilteredImageSource;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.ReplicateScaleFilter;
+
+/**
+ * This is the abstract superclass of all image objects in Java.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public abstract class Image
+{
+ /**
+ * This variable is returned whenever a property that is not defined
+ * is requested.
+ */
+ // For debug purposes, this might as well be a unique string.
+ public static final Object UndefinedProperty
+ = new String("undefined property");
+
+ /**
+ * Constant indicating that the default scaling algorithm should be used.
+ *
+ * @since 1.1
+ */
+ public static final int SCALE_DEFAULT = 1;
+
+ /**
+ * Constant indicating that a fast scaling algorithm should be used.
+ *
+ * @since 1.1
+ */
+ public static final int SCALE_FAST = 2;
+
+ /**
+ * Constant indicating that a smooth scaling algorithm should be used.
+ *
+ * @since 1.1
+ */
+ public static final int SCALE_SMOOTH = 4;
+
+ /**
+ * Constant indicating that the <code>ReplicateScaleFilter</code> class
+ * algorithm should be used for scaling.
+ *
+ * @see ReplicateScaleFilter
+ * @since 1.1
+ */
+ public static final int SCALE_REPLICATE = 8;
+
+ /**
+ * Constant indicating that the area averaging scaling algorithm should be
+ * used.
+ *
+ * @see java.awt.image.AreaAveragingScaleFilter
+ * @since 1.1
+ */
+ public static final int SCALE_AREA_AVERAGING = 16;
+
+ /**
+ * A default constructor for subclasses.
+ */
+ public Image()
+ {
+ }
+
+ /**
+ * Returns the width of the image, or -1 if it is unknown. If the
+ * image width is unknown, the observer object will be notified when
+ * the value is known.
+ *
+ * @param observer the image observer for this object
+ * @return the width in pixels
+ * @see #getHeight(ImageObserver)
+ */
+ public abstract int getWidth(ImageObserver observer);
+
+ /**
+ * Returns the height of the image, or -1 if it is unknown. If the
+ * image height is unknown, the observer object will be notified when
+ * the value is known.
+ *
+ * @param observer the image observer for this object
+ * @return the height in pixels
+ * @see #getWidth(ImageObserver)
+ */
+ public abstract int getHeight(ImageObserver observer);
+
+ /**
+ * Returns the image producer object for this object. The producer is the
+ * object which generates pixels for this image.
+ *
+ * @return the image producer for this object
+ */
+ public abstract ImageProducer getSource();
+
+ /**
+ * Returns a graphics context object for drawing an off-screen object.
+ * This method is only valid for off-screen objects.
+ *
+ * @return a graphics context object for an off-screen object
+ * @see Graphics#getcreateImage(int, int)
+ */
+ public abstract Graphics getGraphics();
+
+ /**
+ * This method requests a named property for an object. The value of the
+ * property is returned. The value <code>UndefinedProperty</code> is
+ * returned if there is no property with the specified name. The value
+ * <code>null</code> is returned if the properties for the object are
+ * not yet known. In this case, the specified image observer is notified
+ * when the properties are known.
+ *
+ * @param name the requested property name
+ * @param observer the image observer for this object
+ * @return the named property, if available
+ * @see #UndefinedProperty
+ */
+ public abstract Object getProperty(String name, ImageObserver observer);
+
+ /**
+ * Scales the image to the requested dimension. A new Image with asynchronous
+ * loading will be produced according to the hints of the algorithm
+ * requested. If either the width or height is non-positive, it is adjusted
+ * to preserve the original aspect ratio.
+ *
+ * @param width the width of the scaled image
+ * @param height the height of the scaled image
+ * @param flags a value indicating the algorithm to use
+ * @return the scaled <code>Image</code> object
+ * @see #SCALE_DEFAULT
+ * @see #SCALE_FAST
+ * @see #SCALE_SMOOTH
+ * @see #SCALE_REPLICATE
+ * @see #SCALE_AREA_AVERAGING
+ * @since 1.1
+ */
+ public Image getScaledInstance(int width, int height, int flags)
+ {
+ switch (flags)
+ {
+ case SCALE_DEFAULT:
+ case SCALE_FAST:
+ case SCALE_REPLICATE:
+ ImageProducer producer =
+ new FilteredImageSource(this.getSource(),
+ new ReplicateScaleFilter(width, height));
+ return Toolkit.getDefaultToolkit().createImage(producer);
+ case SCALE_SMOOTH:
+ case SCALE_AREA_AVERAGING:
+ default:
+ throw new Error("not implemented");
+ }
+ }
+
+ /**
+ * Flushes (that is, destroys) any resources used for this image. This
+ * includes the actual image data.
+ */
+ public abstract void flush();
+} // class Image
diff --git a/libjava/classpath/java/awt/ImageCapabilities.java b/libjava/classpath/java/awt/ImageCapabilities.java
new file mode 100644
index 0000000..2fe71d1
--- /dev/null
+++ b/libjava/classpath/java/awt/ImageCapabilities.java
@@ -0,0 +1,107 @@
+/* ImageCapabilities.java -- the capabilities of an image buffer
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This class represents the capabilities of an image buffer. An
+ * image buffer may be backed by accelerated graphics resources.
+ * Those resources may or may not be volatile. This class is used to
+ * describe these image buffer characteristics.
+ */
+public class ImageCapabilities implements Cloneable
+{
+ /**
+ * Whether or not this the image buffer uses accelerated graphics
+ * resources.
+ */
+ private final boolean accelerated;
+
+ /**
+ * Create a new image capability descriptor.
+ *
+ * @param accelerated true if the image buffer uses accelerated
+ * graphics resources
+ */
+ public ImageCapabilities(boolean accelerated)
+ {
+ this.accelerated = accelerated;
+ }
+
+ /**
+ * Returns whether or not the image buffer uses accelerated graphics
+ * resources.
+ *
+ * @return true if the image buffer uses accelerated graphics
+ * resources; false otherwise
+ */
+ public boolean isAccelerated()
+ {
+ return accelerated;
+ }
+
+ /**
+ * Returns whether or not the image buffer's resources are volatile,
+ * meaning that they can be reclaimed by the graphics system at any
+ * time.
+ *
+ * @return true if the image buffer's resources are volatile; false
+ * otherwise
+ */
+ public boolean isTrueVolatile()
+ {
+ return true;
+ }
+
+ /**
+ * Clone this image capability descriptor.
+ *
+ * @return a clone of this image capability descriptor
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e);
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/Insets.java b/libjava/classpath/java/awt/Insets.java
new file mode 100644
index 0000000..7238a34
--- /dev/null
+++ b/libjava/classpath/java/awt/Insets.java
@@ -0,0 +1,158 @@
+/* Insets.java -- information about a container border
+ Copyright (C) 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * This class represents the "margin" or space around a container.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @status
+ */
+public class Insets implements Cloneable, Serializable
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -2272572637695466749L;
+
+ /**
+ * The gap from the top.
+ *
+ * @serial the top inset
+ */
+ public int top;
+
+ /**
+ * The gap from the left.
+ *
+ * @serial the left inset
+ */
+ public int left;
+
+ /**
+ * The gap from the bottom.
+ *
+ * @serial the bottom inset
+ */
+ public int bottom;
+
+ /**
+ * The gap from the right.
+ *
+ * @serial the right inset
+ */
+ public int right;
+
+ /**
+ * Initializes a new instance of <code>Inset</code> with the specified
+ * inset values.
+ *
+ * @param top the top inset
+ * @param left the left inset
+ * @param bottom the bottom inset
+ * @param right the right inset
+ */
+ public Insets(int top, int left, int bottom, int right)
+ {
+ this.top = top;
+ this.left = left;
+ this.bottom = bottom;
+ this.right = right;
+ }
+
+ /**
+ * Tests whether this object is equal to the specified object. The other
+ * object must be an instance of Insets with identical field values.
+ *
+ * @param obj the object to test against
+ * @return true if the specified object is equal to this one
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof Insets))
+ return false;
+ Insets i = (Insets) obj;
+ return top == i.top && bottom == i.bottom
+ && left == i.left && right == i.right;
+ }
+
+ /**
+ * Returns a hashcode for this instance. The formula is unspecified, but
+ * appears to be <code>XXX what is it? </code>.
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ // This can't be right...
+ return top + bottom + left + right;
+ }
+
+ /**
+ * Returns a string representation of this object, which will be non-null.
+ * The format is unspecified, but appears to be <code>XXX what is it?</code>.
+ *
+ * @return a string representation of this object
+ */
+ public String toString()
+ {
+ return getClass().getName() + "(top=" + top + ",bottom=" + bottom +
+ ",left=" + left + ",right=" + right + ')';
+ }
+
+ /**
+ * Returns a copy of this object.
+ *
+ * @return a copy of this object
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+} // class Insets
diff --git a/libjava/classpath/java/awt/ItemSelectable.java b/libjava/classpath/java/awt/ItemSelectable.java
new file mode 100644
index 0000000..f155f72
--- /dev/null
+++ b/libjava/classpath/java/awt/ItemSelectable.java
@@ -0,0 +1,75 @@
+/* ItemSelectable.java -- items that can be selected
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ItemListener;
+
+/**
+ * This interface is for objects that can have one or more items selected.
+ * For example, radio buttons.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public interface ItemSelectable
+{
+ /**
+ * Returns the list of objects that are selected in this component.
+ *
+ * @return the list of selected objects, or null
+ */
+ Object[] getSelectedObjects();
+
+ /**
+ * Adds an item listener to this object. It will receive selection events
+ * for this object by the user (but not programatically). If listener is
+ * null, it is ignored.
+ *
+ * @param listener the item listener to add
+ */
+ void addItemListener(ItemListener listener);
+
+ /**
+ * Removes an item listener from this object.
+ *
+ * @param listener the item listener to remove
+ */
+ void removeItemListener(ItemListener listener);
+} // interface ItemSelectable
diff --git a/libjava/classpath/java/awt/JobAttributes.java b/libjava/classpath/java/awt/JobAttributes.java
new file mode 100644
index 0000000..2acb3a0
--- /dev/null
+++ b/libjava/classpath/java/awt/JobAttributes.java
@@ -0,0 +1,500 @@
+/* JobAttributes.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * Needs documentation...
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ * @status updated to 1.4, lacks documentation
+ */
+public final class JobAttributes implements Cloneable
+{
+ public static final class DefaultSelectionType extends AttributeValue
+ {
+ private static final String[] NAMES = { "all", "range", "selection" };
+ public static final DefaultSelectionType ALL
+ = new DefaultSelectionType(0);
+ public static final DefaultSelectionType RANGE
+ = new DefaultSelectionType(1);
+ public static final DefaultSelectionType SELECTION
+ = new DefaultSelectionType(2);
+ private DefaultSelectionType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class DefaultSelectionType
+
+ public static final class DestinationType extends AttributeValue
+ {
+ private static final String[] NAMES = { "file", "printer" };
+ public static final DestinationType FILE = new DestinationType(0);
+ public static final DestinationType PRINTER = new DestinationType(1);
+ private DestinationType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class DestinationType
+
+ public static final class DialogType extends AttributeValue
+ {
+ private static final String[] NAMES = { "common", "native", "none" };
+ public static final DialogType COMMON = new DialogType(0);
+ public static final DialogType NATIVE = new DialogType(1);
+ public static final DialogType NONE = new DialogType(2);
+ private DialogType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class DialogType
+
+ public static final class MultipleDocumentHandlingType
+ extends AttributeValue
+ {
+ private static final String[] NAMES = {
+ "separate-documents-collated-copies",
+ "separate-documents-uncollated-copies"
+ };
+ public static final MultipleDocumentHandlingType
+ SEPARATE_DOCUMENTS_COLLATED_COPIES
+ = new MultipleDocumentHandlingType(0);
+ public static final MultipleDocumentHandlingType
+ SEPARATE_DOCUMENTS_UNCOLLATED_COPIES
+ = new MultipleDocumentHandlingType(1);
+ private MultipleDocumentHandlingType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class MultipleDocumentHandlingType
+
+ public static final class SidesType extends AttributeValue
+ {
+ private static final String[] NAMES
+ = { "one-sided", "two-sided-long-edge", "two-sided-short-edge" };
+ public static final SidesType ONE_SIDED = new SidesType(0);
+ public static final SidesType TWO_SIDED_LONG_EDGE = new SidesType(1);
+ public static final SidesType TWO_SIDED_SHORT_EDGE = new SidesType(2);
+ private SidesType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class SidesType
+
+ private int copies;
+ private DefaultSelectionType selection;
+ private DestinationType destination;
+ private DialogType dialog;
+ private String filename;
+ private int maxPage;
+ private int minPage;
+ private MultipleDocumentHandlingType multiple;
+ private int[][] pageRanges; // null for default value
+ private int fromPage; // 0 for default value
+ private int toPage; // 0 for default value
+ private String printer;
+ private SidesType sides;
+
+ public JobAttributes()
+ {
+ copies = 1;
+ selection = DefaultSelectionType.ALL;
+ destination = DestinationType.PRINTER;
+ dialog = DialogType.NATIVE;
+ maxPage = Integer.MAX_VALUE;
+ minPage = 1;
+ multiple
+ = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES;
+ sides = SidesType.ONE_SIDED;
+ }
+
+ public JobAttributes(JobAttributes attr)
+ {
+ set(attr);
+ }
+
+ public JobAttributes(int copies, DefaultSelectionType selection,
+ DestinationType destination, DialogType dialog,
+ String filename, int max, int min,
+ MultipleDocumentHandlingType multiple,
+ int[][] pageRanges, String printer, SidesType sides)
+ {
+ if (copies <= 0 || selection == null || destination == null
+ || dialog == null || max < min || min <= 0 || multiple == null
+ || sides == null)
+ throw new IllegalArgumentException();
+ this.copies = copies;
+ this.selection = selection;
+ this.destination = destination;
+ this.dialog = dialog;
+ this.filename = filename;
+ maxPage = max;
+ minPage = min;
+ this.multiple = multiple;
+ setPageRanges(pageRanges);
+ this.printer = printer;
+ this.sides = sides;
+ }
+
+ public Object clone()
+ {
+ return new JobAttributes(this);
+ }
+
+ public void set(JobAttributes attr)
+ {
+ copies = attr.copies;
+ selection = attr.selection;
+ destination = attr.destination;
+ dialog = attr.dialog;
+ filename = attr.filename;
+ maxPage = attr.maxPage;
+ minPage = attr.minPage;
+ multiple = attr.multiple;
+ pageRanges = (int[][]) attr.pageRanges.clone();
+ printer = attr.printer;
+ sides = attr.sides;
+ fromPage = attr.fromPage;
+ toPage = attr.toPage;
+ }
+
+ public int getCopies()
+ {
+ return copies;
+ }
+
+ public void setCopies(int copies)
+ {
+ if (copies <= 0)
+ throw new IllegalArgumentException();
+ this.copies = copies;
+ }
+
+ public void setCopiesToDefault()
+ {
+ copies = 1;
+ }
+
+ public DefaultSelectionType getDefaultSelection()
+ {
+ return selection;
+ }
+
+ public void setDefaultSelection(DefaultSelectionType selection)
+ {
+ if (selection == null)
+ throw new IllegalArgumentException();
+ this.selection = selection;
+ }
+
+ public DestinationType getDestination()
+ {
+ return destination;
+ }
+
+ public void setDestination(DestinationType destination)
+ {
+ if (destination == null)
+ throw new IllegalArgumentException();
+ this.destination = destination;
+ }
+
+ public DialogType getDialog()
+ {
+ return dialog;
+ }
+
+ public void setDialog(DialogType dialog)
+ {
+ if (dialog == null)
+ throw new IllegalArgumentException();
+ this.dialog = dialog;
+ }
+
+ public String getFileName()
+ {
+ return filename;
+ }
+
+ public void setFileName(String filename)
+ {
+ this.filename = filename;
+ }
+
+ public int getFromPage()
+ {
+ return fromPage != 0 ? fromPage
+ : pageRanges != null ? pageRanges[0][0]
+ : toPage != 0 ? toPage : minPage;
+ }
+
+ public void setFromPage(int fromPage)
+ {
+ if (fromPage < minPage || (fromPage > toPage && toPage != 0)
+ || fromPage > maxPage)
+ throw new IllegalArgumentException();
+ if (pageRanges == null)
+ this.fromPage = fromPage;
+ }
+
+ public int getMaxPage()
+ {
+ return maxPage;
+ }
+
+ public void setMaxPage(int maxPage)
+ {
+ if (maxPage < minPage)
+ throw new IllegalArgumentException();
+ this.maxPage = maxPage;
+ if (maxPage < fromPage)
+ fromPage = maxPage;
+ if (maxPage < toPage)
+ toPage = maxPage;
+ if (pageRanges != null)
+ {
+ int i = pageRanges.length - 1;
+ while (i >= 0 && maxPage < pageRanges[i][1])
+ i--;
+ if (maxPage >= pageRanges[++i][0])
+ pageRanges[i++][1] = maxPage;
+ if (i == 0)
+ pageRanges = null;
+ else if (i < pageRanges.length)
+ {
+ int[][] tmp = new int[i][];
+ System.arraycopy(pageRanges, 0, tmp, 0, i);
+ pageRanges = tmp;
+ }
+ }
+ }
+
+ public int getMinPage()
+ {
+ return minPage;
+ }
+
+ public void setMinPage(int minPage)
+ {
+ if (minPage <= 0 || minPage > maxPage)
+ throw new IllegalArgumentException();
+ this.minPage = minPage;
+ if (minPage > toPage)
+ toPage = minPage;
+ if (minPage > fromPage)
+ fromPage = minPage;
+ if (pageRanges != null)
+ {
+ int size = pageRanges.length;
+ int i = 0;
+ while (i < size && minPage > pageRanges[i][0])
+ i++;
+ if (minPage <= pageRanges[i - 1][1])
+ pageRanges[--i][0] = minPage;
+ if (i == size)
+ pageRanges = null;
+ else if (i > 0)
+ {
+ int[][] tmp = new int[size - i][];
+ System.arraycopy(pageRanges, i, tmp, 0, size - i);
+ pageRanges = tmp;
+ }
+ }
+ }
+
+ public MultipleDocumentHandlingType getMultipleDocumentHandling()
+ {
+ return multiple;
+ }
+
+ public void setMultipleDocumentHandling
+ (MultipleDocumentHandlingType multiple)
+ {
+ if (multiple == null)
+ throw new IllegalArgumentException();
+ this.multiple = multiple;
+ }
+
+ public void setMultipleDocumentHandlingToDefault()
+ {
+ multiple
+ = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES;
+ }
+
+ public int[][] getPageRanges()
+ {
+ if (pageRanges == null)
+ return new int[][] { { getFromPage(), getToPage() } };
+ // Perform a deep clone, so user code cannot affect original arrays.
+ int i = pageRanges.length;
+ int[][] result = new int[i][];
+ while (--i >= 0)
+ result[i] = (int[]) pageRanges[i].clone();
+ return result;
+ }
+
+ public void setPageRanges(int[][] pageRanges)
+ {
+ int size = pageRanges == null ? 0 : pageRanges.length;
+ if (size == 0)
+ throw new IllegalArgumentException();
+ while (--size >= 0)
+ {
+ int[] range = pageRanges[size];
+ if (range == null || range.length != 2
+ || range[0] < minPage || range[1] < range[0] || range[1] > maxPage
+ || (size != 0 && range[0] <= pageRanges[size - 1][1]))
+ throw new IllegalArgumentException();
+ }
+ size = pageRanges.length;
+ if (fromPage > 0 && pageRanges[0][0] > fromPage)
+ fromPage = pageRanges[0][0];
+ if (toPage > 0 && pageRanges[size - 1][1] < toPage)
+ toPage = pageRanges[size - 1][1];
+ this.pageRanges = new int[size][];
+ while (--size >= 0)
+ this.pageRanges[size] = (int[]) pageRanges[size].clone();
+ }
+
+ public String getPrinter()
+ {
+ return printer;
+ }
+
+ public void setPrinter(String printer)
+ {
+ this.printer = printer;
+ }
+
+ public SidesType getSides()
+ {
+ return sides;
+ }
+
+ public void setSides(SidesType sides)
+ {
+ if (sides == null)
+ throw new IllegalArgumentException();
+ this.sides = sides;
+ }
+
+ public void setSidesToDefault()
+ {
+ sides = SidesType.ONE_SIDED;
+ }
+
+ public int getToPage()
+ {
+ return toPage != 0 ? toPage
+ : pageRanges != null ? pageRanges[pageRanges.length - 1][1]
+ : fromPage != 0 ? fromPage : maxPage;
+ }
+
+ public void setToPage(int toPage)
+ {
+ if (toPage < minPage || (fromPage > toPage && fromPage != 0)
+ || toPage > maxPage)
+ throw new IllegalArgumentException();
+ if (pageRanges == null)
+ this.toPage = toPage;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ return true;
+ if (! (o instanceof JobAttributes))
+ return false;
+ JobAttributes ja = (JobAttributes) o;
+ if (copies != ja.copies || selection != ja.selection
+ || destination != ja.destination || dialog != ja.dialog
+ || ! filename.equals(ja.filename) || maxPage != ja.maxPage
+ || minPage != ja.minPage || multiple != ja.multiple
+ || fromPage != ja.fromPage || toPage != ja.toPage
+ || ! printer.equals(ja.printer) || sides != ja.sides
+ || (pageRanges == null) != (ja.pageRanges == null))
+ return false;
+ if (pageRanges != ja.pageRanges)
+ for (int i = pageRanges.length; --i >= 0; )
+ if (pageRanges[i][0] != ja.pageRanges[i][0]
+ || pageRanges[i][1] != ja.pageRanges[i][1])
+ return false;
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hash = (selection.value << 6) ^ (destination.value << 5)
+ ^ (dialog.value << 3) ^ (multiple.value << 2) ^ sides.value
+ ^ (filename == null ? 0 : filename.hashCode())
+ ^ (printer == null ? 0 : printer.hashCode());
+ // The effect of the above fields on the hashcode match the JDK. However,
+ // I am unable to reverse engineer the effect of the fields listed below,
+ // so I am using my own implementation. Note that this still satisfies
+ // the general contract of hashcode, it just doesn't match the JDK.
+ hash ^= (copies << 27) ^ (maxPage << 22) ^ (minPage << 17);
+ if (pageRanges == null)
+ hash ^= (getFromPage() << 13) ^ (getToPage() << 8);
+ else
+ for (int i = pageRanges.length; --i >= 0; )
+ hash ^= (pageRanges[i][0] << 13) ^ (pageRanges[i][1] << 8);
+ return hash;
+ }
+
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer("copies=").append(copies)
+ .append(",defaultSelection=").append(selection).append(",destination=")
+ .append(destination).append(",dialog=").append(dialog)
+ .append(",fileName=").append(filename).append(",fromPage=")
+ .append(getFromPage()).append(",maxPage=").append(maxPage)
+ .append(",minPage=").append(minPage)
+ .append(",multiple-document-handling=").append(multiple)
+ .append(",page-ranges=[");
+ if (pageRanges == null)
+ s.append(minPage).append(':').append(minPage).append(']');
+ else
+ for (int i = 0; i < pageRanges.length; i++)
+ s.append(pageRanges[i][0]).append(':').append(pageRanges[i][1])
+ .append(',');
+ s.setLength(s.length() - 1);
+ return s.append("],printer=").append(printer).append(",sides=")
+ .append(sides).append(",toPage=").append(getToPage()).toString();
+ }
+} // class JobAttributes
diff --git a/libjava/classpath/java/awt/KeyEventDispatcher.java b/libjava/classpath/java/awt/KeyEventDispatcher.java
new file mode 100644
index 0000000..3099727
--- /dev/null
+++ b/libjava/classpath/java/awt/KeyEventDispatcher.java
@@ -0,0 +1,82 @@
+/* KeyEventDispatcher.java -- dispatches key events
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.KeyEvent;
+
+/**
+ * An instance of this interface coordinates with a KeyboardFocusManager to
+ * target and dispatch all key events. This allows retargeting, consuming,
+ * changing, or otherwise manipulating the key event before sending it on to
+ * a target.
+ *
+ * <p>By default, the KeyboardFocusManager is the sink for all key events not
+ * dispatched by other dispatchers. Therefore, it is unnecessary for the user
+ * to register the focus manager as a dispatcher.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see KeyboardFocusManager#addKeyEventDispatcher(KeyEventDispatcher)
+ * @see KeyboardFocusManager#removeKeyEventDispatcher(KeyEventDispatcher)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public interface KeyEventDispatcher
+{
+ /**
+ * Called by the KeyboardFocusManager to request that a key event be
+ * dispatched. The dispatcher is free to retarget the event, consume it,
+ * dispatch it, or make other changes. This is usually done to allow
+ * delivery of key events to objects other than the window in focus, such
+ * as for navigating non-focusable components. If this dispatcher chooses
+ * to dispatch the event itself, it should call <code>redispatchEvent</code>
+ * to avoid infinite recursion.
+ *
+ * <p>If the return value is false, the KeyEvent is passed to the next
+ * dispatcher in the chain, ending with the KeyboardFocusManager. If the
+ * return value is true, the event has been consumed (although it might
+ * have been ignored), and no further action will be taken on the event. Be
+ * sure to check whether the event was consumed before dispatching it
+ * further.
+ *
+ * @param e the key event
+ * @return true if the event has been consumed
+ * @see KeyboardFocusManager#redispatchEvent(Component, AWTEvent)
+ */
+ boolean dispatchKeyEvent(KeyEvent e);
+} // interface KeyEventDispatcher
diff --git a/libjava/classpath/java/awt/KeyEventPostProcessor.java b/libjava/classpath/java/awt/KeyEventPostProcessor.java
new file mode 100644
index 0000000..0b39dc2
--- /dev/null
+++ b/libjava/classpath/java/awt/KeyEventPostProcessor.java
@@ -0,0 +1,81 @@
+/* KeyEventPostProcessor.java -- performs actions after a key event dispatch
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.KeyEvent;
+
+/**
+ * An instance of this interface coordinates with a KeyboardFocusManager to
+ * target and dispatch all key events that are otherwise unconsumed. This
+ * allows events which take place when nothing has focus to still operate,
+ * such as menu keyboard shortcuts.
+ *
+ * <p>By default, the KeyboardFocusManager is the sink for all key events not
+ * post-processed elsewhere. Therefore, it is unnecessary for the user
+ * to register the focus manager as a dispatcher.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see KeyboardFocusManager#addKeyEventPostProcessor(KeyEventPostProcessor)
+ * @see KeyboardFocusManager#removeKeyEventPostProcessor(KeyEventPostProcessor)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public interface KeyEventPostProcessor
+{
+ /**
+ * Called by the KeyboardFocusManager to request that a key event be
+ * post-processed. Typically, the event has already been dispatched and
+ * handled, unless no object has focus. Thus, this allows global event
+ * handling for things like menu shortcuts. If this post-processor chooses
+ * to dispatch the event, it should call <code>redispatchEvent</code>
+ * to avoid infinite recursion.
+ *
+ * <p>If the return value is false, the KeyEvent is passed to the next
+ * dispatcher in the chain, ending with the KeyboardFocusManager. If the
+ * return value is true, the event has been consumed (although it might
+ * have been ignored), and no further action will be taken on the event. Be
+ * sure to check whether the event was consumed before dispatching it
+ * further.
+ *
+ * @param e the key event
+ * @return true if the event has been consumed
+ * @see KeyboardFocusManager#redispatchEvent(Component, AWTEvent)
+ */
+ boolean postProcessKeyEvent(KeyEvent e);
+} // interface KeyEventPostProcessor
diff --git a/libjava/classpath/java/awt/KeyboardFocusManager.java b/libjava/classpath/java/awt/KeyboardFocusManager.java
new file mode 100644
index 0000000..f646184
--- /dev/null
+++ b/libjava/classpath/java/awt/KeyboardFocusManager.java
@@ -0,0 +1,1478 @@
+/* KeyboardFocusManager.java -- manage component focusing via the keyboard
+ Copyright (C) 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.applet.Applet;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.beans.PropertyVetoException;
+import java.beans.VetoableChangeListener;
+import java.beans.VetoableChangeSupport;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The <code>KeyboardFocusManager</code> handles the focusing of
+ * windows for receiving keyboard events. The manager handles
+ * the dispatch of all <code>FocusEvent</code>s and
+ * <code>KeyEvent</code>s, along with <code>WindowEvent</code>s
+ * relating to the focused window. Users can use the manager
+ * to ascertain the current focus owner and fire events.
+ * <br />
+ * <br />
+ * The focus owner is the <code>Component</code> that receives
+ * key events. The focus owner is either the currently focused
+ * window or a component within this window.
+ * <br />
+ * <br />
+ * The underlying native windowing system may denote the active
+ * window or its children with special decorations (e.g. a highlighted
+ * title bar). The active window is always either a <code>Frame</code>
+ * or <code>Dialog</code>, and is either the currently focused
+ * window or its owner.
+ * <br />
+ * <br />
+ * Applets may be partitioned into different applet contexts, according
+ * to their code base. In this case, each context has its own
+ * <code>KeyboardFocusManager</code>, as opposed to the global
+ * manager maintained by applets which share the same context.
+ * Each context is insulated from the others, and they don't interact.
+ * The resulting behaviour, as with context division, depends on the browser
+ * supporting the applets. Regardless, there can only ever be
+ * one focused window, one active window and one focus owner
+ * per <code>ClassLoader</code>.
+ * <br />
+ * <br />
+ * To support this separation of focus managers, the manager instances
+ * and the internal state information is grouped by the
+ * <code>ThreadGroup</code> to which it pertains. With respect to
+ * applets, each code base has its own <code>ThreadGroup</code>, so the
+ * isolation of each context is enforced within the manager.
+ * <br />
+ * <br />
+ * By default, the manager defines TAB and Ctrl+TAB as the
+ * forward focus traversal keys and Shift+TAB and Ctrl+Shift+TAB
+ * as the backward focus traversal keys. No up or down cycle
+ * traversal keys are defined by default. Traversal takes effect
+ * on the firing of a relevant <code>KEY_PRESSED</code> event.
+ * However, all other key events related to the use of the
+ * defined focus traversal key sequence are consumed and not
+ * dispatched.
+ * <br />
+ * <br />
+ * These default traversal keys come into effect on all windows
+ * for which no alternative set of keys is defined. This also
+ * applies recursively to any child components of such a window,
+ * which define no traversal keys of their own.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Thomas Fitzsimmons (fitzsim@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.4
+ */
+public abstract class KeyboardFocusManager
+ implements KeyEventDispatcher, KeyEventPostProcessor
+{
+ /** Identifies {@link AWTKeyStroke}s that move the focus forward in
+ the focus cycle. */
+ public static final int FORWARD_TRAVERSAL_KEYS = 0;
+
+ /** Identifies {@link AWTKeyStroke}s that move the focus backward in
+ the focus cycle. */
+ public static final int BACKWARD_TRAVERSAL_KEYS = 1;
+
+ /** Identifies {@link AWTKeyStroke}s that move the focus up to the
+ parent focus cycle root. */
+ public static final int UP_CYCLE_TRAVERSAL_KEYS = 2;
+
+ /** Identifies {@link AWTKeyStroke}s that move the focus down to the
+ child focus cycle root. */
+ public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3;
+
+ /** The set of {@link AWTKeyStroke}s that cause focus to be moved to
+ the next focusable Component in the focus cycle. */
+ private static final Set DEFAULT_FORWARD_KEYS;
+
+ /** The set of {@link AWTKeyStroke}s that cause focus to be moved to
+ the previous focusable Component in the focus cycle. */
+ private static final Set DEFAULT_BACKWARD_KEYS;
+
+ /** Populate the DEFAULT_FORWARD_KEYS and DEFAULT_BACKWARD_KEYS
+ {@link java.util.Set}s. */
+ static
+ {
+ Set s = new HashSet();
+ s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0));
+ s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
+ KeyEvent.CTRL_DOWN_MASK));
+ DEFAULT_FORWARD_KEYS = Collections.unmodifiableSet(s);
+ s = new HashSet();
+ s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
+ KeyEvent.SHIFT_DOWN_MASK));
+ s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
+ KeyEvent.SHIFT_DOWN_MASK
+ | KeyEvent.CTRL_DOWN_MASK));
+ DEFAULT_BACKWARD_KEYS = Collections.unmodifiableSet(s);
+ }
+
+ /** The global object {@link java.util.Map}s. */
+
+ /** For security reasons, {@link java.applet.Applet}s in different
+ codebases must be insulated from one another. Since {@link
+ KeyboardFocusManager}s have the ability to return {@link
+ Component}s from a given {@link java.applet.Applet}, each
+ codebase must have an independent {@link KeyboardFocusManager}.
+ Since each codebase has its own {@link ThreadGroup} in which its
+ {@link Applet}s run, it makes sense to partition {@link
+ KeyboardFocusManager}s according to {@link
+ java.lang.ThreadGroup}. Thus, currentKeyboardFocusManagers is a
+ {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}. */
+ private static Map currentKeyboardFocusManagers = new HashMap ();
+
+ /** {@link java.applet.Applet}s in one codebase must not be allowed
+ to access {@link Component}s in {@link java.applet.Applet}s in
+ other codebases. To enforce this restriction, we key the
+ following {@link java.util.Map}s on {@link java.lang.ThreadGroup}s (which
+ are per-codebase). For example, if {@link
+ java.lang.ThreadGroup} A calls {@link #setGlobalFocusOwner},
+ passing {@link Component} C, currentFocusOwners[A] is assigned
+ C, and all other currentFocusOwners values are nullified. Then
+ if {@link java.lang.ThreadGroup} A subsequently calls {@link
+ #getGlobalFocusOwner}, it will return currentFocusOwners[A],
+ that is, {@link Component} C. If another {@link
+ java.lang.ThreadGroup} K calls {@link #getGlobalFocusOwner}, it
+ will return currentFocusOwners[K], that is, null.
+
+ Since this is a static field, we ensure that there is only one
+ focused {@link Component} per class loader. */
+ private static Map currentFocusOwners = new HashMap ();
+
+ /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
+ that stores the {@link Component} that owns the permanent
+ keyboard focus. @see currentFocusOwners */
+ private static Map currentPermanentFocusOwners = new HashMap ();
+
+ /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
+ that stores the focused {@link Window}. @see
+ currentFocusOwners */
+ private static Map currentFocusedWindows = new HashMap ();
+
+ /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
+ that stores the active {@link Window}. @see
+ currentFocusOwners */
+ private static Map currentActiveWindows = new HashMap ();
+
+ /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
+ that stores the focus cycle root {@link Container}. @see
+ currentFocusOwners */
+ private static Map currentFocusCycleRoots = new HashMap ();
+
+ /** The default {@link FocusTraveralPolicy} that focus-managing
+ {@link Container}s will use to define their initial focus
+ traversal policy. */
+ private FocusTraversalPolicy defaultPolicy;
+
+ /** An array that stores the {@link #FORWARD_TRAVERSAL_KEYS}, {@link
+ #BACKWARD_TRAVERSAL_KEYS}, {@link #UP_CYCLE_TRAVERSAL_KEYS} and
+ {@link #DOWN_CYCLE_TRAVERSAL_KEYS} {@link AWTKeyStroke}s {@link
+ java.util.Set}s. */
+ private Set[] defaultFocusKeys = new Set[]
+ {
+ DEFAULT_FORWARD_KEYS, DEFAULT_BACKWARD_KEYS,
+ Collections.EMPTY_SET, Collections.EMPTY_SET
+ };
+
+ /**
+ * A utility class to support the handling of events relating to property changes.
+ */
+ private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport (this);
+
+ /**
+ * A utility class to support the handling of events relating to vetoable changes.
+ */
+ private final VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport (this);
+
+ /** A list of {@link KeyEventDispatcher}s that process {@link
+ KeyEvent}s before they are processed the default keyboard focus
+ manager. */
+ private final ArrayList keyEventDispatchers = new ArrayList();
+
+ /** A list of {@link KeyEventPostProcessor}s that process unconsumed
+ {@link KeyEvent}s. */
+ private final ArrayList keyEventPostProcessors = new ArrayList();
+
+ /**
+ * Construct a KeyboardFocusManager.
+ */
+ public KeyboardFocusManager ()
+ {
+ }
+
+ /**
+ * Retrieve the keyboard focus manager associated with the {@link
+ * java.lang.ThreadGroup} to which the calling thread belongs.
+ *
+ * @return the keyboard focus manager associated with the current
+ * thread group
+ */
+ public static KeyboardFocusManager getCurrentKeyboardFocusManager ()
+ {
+ ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+
+ if (currentKeyboardFocusManagers.get (currentGroup) == null)
+ setCurrentKeyboardFocusManager (null);
+
+ return (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
+ }
+
+ /**
+ * Set the keyboard focus manager associated with the {@link
+ * java.lang.ThreadGroup} to which the calling thread belongs.
+ *
+ * @param m the keyboard focus manager for the current thread group
+ */
+ public static void setCurrentKeyboardFocusManager (KeyboardFocusManager m)
+ {
+ SecurityManager sm = System.getSecurityManager ();
+ if (sm != null)
+ sm.checkPermission (new AWTPermission ("replaceKeyboardFocusManager"));
+
+ ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+ KeyboardFocusManager manager;
+
+ if (m == null)
+ manager = createFocusManager();
+ else
+ manager = m;
+
+ currentKeyboardFocusManagers.put (currentGroup, manager);
+ }
+
+ /**
+ * Creates a KeyboardFocusManager. The exact class is determined by the
+ * system property 'gnu.java.awt.FocusManager'. If this is not set,
+ * we default to DefaultKeyboardFocusManager.
+ */
+ private static KeyboardFocusManager createFocusManager()
+ {
+ String fmClassName = System.getProperty("gnu.java.awt.FocusManager",
+ "java.awt.DefaultKeyboardFocusManager");
+ try
+ {
+ Class fmClass = Class.forName(fmClassName);
+ KeyboardFocusManager fm = (KeyboardFocusManager) fmClass.newInstance();
+ return fm;
+ }
+ catch (ClassNotFoundException ex)
+ {
+ System.err.println("The class " + fmClassName + " cannot be found.");
+ System.err.println("Check the setting of the system property");
+ System.err.println("gnu.java.awt.FocusManager");
+ return null;
+ }
+ catch (InstantiationException ex)
+ {
+ System.err.println("The class " + fmClassName + " cannot be");
+ System.err.println("instantiated.");
+ System.err.println("Check the setting of the system property");
+ System.err.println("gnu.java.awt.FocusManager");
+ return null;
+ }
+ catch (IllegalAccessException ex)
+ {
+ System.err.println("The class " + fmClassName + " cannot be");
+ System.err.println("accessed.");
+ System.err.println("Check the setting of the system property");
+ System.err.println("gnu.java.awt.FocusManager");
+ return null;
+ }
+ }
+
+ /**
+ * Retrieve the {@link Component} that has the keyboard focus, or
+ * null if the focus owner was not set by a thread in the current
+ * {@link java.lang.ThreadGroup}.
+ *
+ * @return the keyboard focus owner or null
+ */
+ public Component getFocusOwner ()
+ {
+ Component owner = (Component) getObject (currentFocusOwners);
+ if (owner == null)
+ owner = (Component) getObject (currentPermanentFocusOwners);
+ return owner;
+ }
+
+ /**
+ * Retrieve the {@link Component} that has the keyboard focus,
+ * regardless of whether or not it was set by a thread in the
+ * current {@link java.lang.ThreadGroup}. If there is no temporary
+ * focus owner in effect then this method will return the same value
+ * as {@link #getGlobalPermanentFocusOwner}.
+ *
+ * @return the keyboard focus owner
+ * @throws SecurityException if this is not the keyboard focus
+ * manager associated with the current {@link java.lang.ThreadGroup}
+ */
+ protected Component getGlobalFocusOwner ()
+ {
+ // Check if there is a temporary focus owner.
+ Component focusOwner = (Component) getGlobalObject (currentFocusOwners);
+
+ return (focusOwner == null) ? getGlobalPermanentFocusOwner () : focusOwner;
+ }
+
+ /**
+ * Set the {@link Component} that will be returned by {@link
+ * #getFocusOwner} (when it is called from the current {@link
+ * java.lang.ThreadGroup}) and {@link #getGlobalFocusOwner}. This
+ * method does not actually transfer the keyboard focus.
+ *
+ * @param owner the Component to return from getFocusOwner and
+ * getGlobalFocusOwner
+ *
+ * @see Component#requestFocus()
+ * @see Component#requestFocusInWindow()
+ */
+ protected void setGlobalFocusOwner (Component owner)
+ {
+ if (owner == null || owner.focusable)
+ setGlobalObject (currentFocusOwners, owner, "focusOwner");
+ }
+
+ /**
+ * Clear the global focus owner and deliver a FOCUS_LOST event to
+ * the previously-focused {@link Component}. Until another {@link
+ * Component} becomes the keyboard focus owner, key events will be
+ * discarded by top-level windows.
+ */
+ public void clearGlobalFocusOwner ()
+ {
+ synchronized (currentFocusOwners)
+ {
+ Component focusOwner = getGlobalFocusOwner ();
+ Component permanentFocusOwner = getGlobalPermanentFocusOwner ();
+
+ setGlobalFocusOwner (null);
+ setGlobalPermanentFocusOwner (null);
+
+ // Inform the old focus owner that it has lost permanent
+ // focus.
+ if (focusOwner != null)
+ {
+ // We can't cache the event queue, because of
+ // bootstrapping issues. We need to set the default
+ // KeyboardFocusManager in EventQueue before the event
+ // queue is started.
+ EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+ if (focusOwner != permanentFocusOwner)
+ q.postEvent (new FocusEvent (focusOwner, FocusEvent.FOCUS_LOST, true));
+ else
+ q.postEvent (new FocusEvent (focusOwner, FocusEvent.FOCUS_LOST, false));
+ }
+
+ if (focusOwner != permanentFocusOwner)
+ {
+ EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+ q.postEvent (new FocusEvent (permanentFocusOwner, FocusEvent.FOCUS_LOST, false));
+ }
+ }
+ }
+
+ /**
+ * Retrieve the {@link Component} that has the permanent keyboard
+ * focus, or null if the focus owner was not set by a thread in the
+ * current {@link java.lang.ThreadGroup}.
+ *
+ * @return the keyboard focus owner or null
+ */
+ public Component getPermanentFocusOwner ()
+ {
+ return (Component) getObject (currentPermanentFocusOwners);
+ }
+
+ /**
+ * Retrieve the {@link Component} that has the permanent keyboard
+ * focus, regardless of whether or not it was set by a thread in the
+ * current {@link java.lang.ThreadGroup}.
+ *
+ * @return the keyboard focus owner
+ * @throws SecurityException if this is not the keyboard focus
+ * manager associated with the current {@link java.lang.ThreadGroup}
+ */
+ protected Component getGlobalPermanentFocusOwner ()
+ {
+ return (Component) getGlobalObject (currentPermanentFocusOwners);
+ }
+
+ /**
+ * Set the {@link Component} that will be returned by {@link
+ * #getPermanentFocusOwner} (when it is called from the current
+ * {@link java.lang.ThreadGroup}) and {@link
+ * #getGlobalPermanentFocusOwner}. This method does not actually
+ * transfer the keyboard focus.
+ *
+ * @param focusOwner the Component to return from
+ * getPermanentFocusOwner and getGlobalPermanentFocusOwner
+ *
+ * @see Component#requestFocus()
+ * @see Component#requestFocusInWindow()
+ */
+ protected void setGlobalPermanentFocusOwner (Component focusOwner)
+ {
+ if (focusOwner == null || focusOwner.focusable)
+ setGlobalObject (currentPermanentFocusOwners, focusOwner,
+ "permanentFocusOwner");
+ }
+
+ /**
+ * Retrieve the {@link Window} that is or contains the keyboard
+ * focus owner, or null if the focused window was not set by a
+ * thread in the current {@link java.lang.ThreadGroup}.
+ *
+ * @return the focused window or null
+ */
+ public Window getFocusedWindow ()
+ {
+ return (Window) getObject (currentFocusedWindows);
+ }
+
+ /**
+ * Retrieve the {@link Window} that is or contains the focus owner,
+ * regardless of whether or not the {@link Window} was set focused
+ * by a thread in the current {@link java.lang.ThreadGroup}.
+ *
+ * @return the focused window
+ * @throws SecurityException if this is not the keyboard focus
+ * manager associated with the current {@link java.lang.ThreadGroup}
+ */
+ protected Window getGlobalFocusedWindow ()
+ {
+ return (Window) getGlobalObject (currentFocusedWindows);
+ }
+
+ /**
+ * Set the {@link Window} that will be returned by {@link
+ * #getFocusedWindow} (when it is called from the current {@link
+ * java.lang.ThreadGroup}) and {@link #getGlobalFocusedWindow}.
+ * This method does not actually cause <code>window</code> to become
+ * the focused {@link Window}.
+ *
+ * @param window the Window to return from getFocusedWindow and
+ * getGlobalFocusedWindow
+ */
+ protected void setGlobalFocusedWindow (Window window)
+ {
+ if (window == null || window.focusable)
+ setGlobalObject (currentFocusedWindows, window, "focusedWindow");
+ }
+
+ /**
+ * Retrieve the active {@link Window}, or null if the active window
+ * was not set by a thread in the current {@link
+ * java.lang.ThreadGroup}.
+ *
+ * @return the active window or null
+ */
+ public Window getActiveWindow()
+ {
+ return (Window) getObject (currentActiveWindows);
+ }
+
+ /**
+ * Retrieve the active {@link Window}, regardless of whether or not
+ * the {@link Window} was made active by a thread in the current
+ * {@link java.lang.ThreadGroup}.
+ *
+ * @return the active window
+ * @throws SecurityException if this is not the keyboard focus
+ * manager associated with the current {@link java.lang.ThreadGroup}
+ */
+ protected Window getGlobalActiveWindow()
+ {
+ return (Window) getGlobalObject (currentActiveWindows);
+ }
+
+ /**
+ * Set the {@link Window} that will be returned by {@link
+ * #getActiveWindow} (when it is called from the current {@link
+ * java.lang.ThreadGroup}) and {@link #getGlobalActiveWindow}. This
+ * method does not actually cause <code>window</code> to be made
+ * active.
+ *
+ * @param window the Window to return from getActiveWindow and
+ * getGlobalActiveWindow
+ */
+ protected void setGlobalActiveWindow(Window window)
+ {
+ setGlobalObject (currentActiveWindows, window, "activeWindow");
+ }
+
+ /**
+ * Retrieve the default {@link FocusTraversalPolicy}.
+ * Focus-managing {@link Container}s use the returned object to
+ * define their initial focus traversal policy.
+ *
+ * @return a non-null default FocusTraversalPolicy object
+ */
+ public FocusTraversalPolicy getDefaultFocusTraversalPolicy ()
+ {
+ if (defaultPolicy == null)
+ defaultPolicy = new DefaultFocusTraversalPolicy ();
+ return defaultPolicy;
+ }
+
+ /**
+ * Set the {@link FocusTraversalPolicy} returned by {@link
+ * #getDefaultFocusTraversalPolicy}. Focus-managing {@link
+ * Container}s created after this call will use policy as their
+ * initial focus traversal policy. Existing {@link Container}s'
+ * focus traversal policies will not be affected by calls to this
+ * method.
+ *
+ * @param policy the FocusTraversalPolicy that will be returned by
+ * subsequent calls to getDefaultFocusTraversalPolicy
+ * @throws IllegalArgumentException if policy is null
+ */
+ public void setDefaultFocusTraversalPolicy (FocusTraversalPolicy policy)
+ {
+ if (policy == null)
+ throw new IllegalArgumentException ();
+ firePropertyChange ("defaultFocusTraversalPolicy", defaultPolicy, policy);
+ defaultPolicy = policy;
+ }
+
+ /**
+ * Set the default {@link java.util.Set} of focus traversal keys for
+ * one of the focus traversal directions.
+ *
+ * @param id focus traversal direction identifier
+ * @param keystrokes set of AWTKeyStrokes
+ *
+ * @see #FORWARD_TRAVERSAL_KEYS
+ * @see #BACKWARD_TRAVERSAL_KEYS
+ * @see #UP_CYCLE_TRAVERSAL_KEYS
+ * @see #DOWN_CYCLE_TRAVERSAL_KEYS
+ */
+ public void setDefaultFocusTraversalKeys (int id, Set keystrokes)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+
+ if (keystrokes == null)
+ throw new IllegalArgumentException ();
+
+ Set sa;
+ Set sb;
+ Set sc;
+ String type;
+ switch (id)
+ {
+ case FORWARD_TRAVERSAL_KEYS:
+ sa = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
+ sb = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
+ sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
+ type = "forwardDefaultFocusTraversalKeys";
+ break;
+ case BACKWARD_TRAVERSAL_KEYS:
+ sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
+ sb = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
+ sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
+ type = "backwardDefaultFocusTraversalKeys";
+ break;
+ case UP_CYCLE_TRAVERSAL_KEYS:
+ sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
+ sb = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
+ sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
+ type = "upCycleDefaultFocusTraversalKeys";
+ break;
+ case DOWN_CYCLE_TRAVERSAL_KEYS:
+ sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
+ sb = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
+ sc = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
+ type = "downCycleDefaultFocusTraversalKeys";
+ break;
+ default:
+ throw new IllegalArgumentException ();
+ }
+ int i = keystrokes.size ();
+ Iterator iter = keystrokes.iterator ();
+ while (--i >= 0)
+ {
+ Object o = iter.next ();
+ if (!(o instanceof AWTKeyStroke)
+ || sa.contains (o) || sb.contains (o) || sc.contains (o)
+ || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
+ throw new IllegalArgumentException ();
+ }
+ keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
+ firePropertyChange (type, defaultFocusKeys[id], keystrokes);
+ defaultFocusKeys[id] = keystrokes;
+ }
+
+ /**
+ * Retrieve the default {@link java.util.Set} of focus traversal
+ * keys for one of the focus traversal directions.
+ *
+ * @param id focus traversal direction identifier
+ *
+ * @return the default set of AWTKeyStrokes
+ *
+ * @see #FORWARD_TRAVERSAL_KEYS
+ * @see #BACKWARD_TRAVERSAL_KEYS
+ * @see #UP_CYCLE_TRAVERSAL_KEYS
+ * @see #DOWN_CYCLE_TRAVERSAL_KEYS
+ */
+ public Set getDefaultFocusTraversalKeys (int id)
+ {
+ if (id < FORWARD_TRAVERSAL_KEYS || id > DOWN_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+ return defaultFocusKeys[id];
+ }
+
+ /**
+ * Retrieve the current focus cycle root, or null if the focus owner
+ * was not set by a thread in the current {@link
+ * java.lang.ThreadGroup}.
+ *
+ * @return the current focus cycle root or null
+ */
+ public Container getCurrentFocusCycleRoot ()
+ {
+ return (Container) getObject (currentFocusCycleRoots);
+ }
+
+ /**
+ * Retrieve the current focus cycle root, regardless of whether or
+ * not it was made set by a thread in the current {@link
+ * java.lang.ThreadGroup}.
+ *
+ * @return the current focus cycle root
+ * @throws SecurityException if this is not the keyboard focus
+ * manager associated with the current {@link java.lang.ThreadGroup}
+ */
+ protected Container getGlobalCurrentFocusCycleRoot ()
+ {
+ return (Container) getGlobalObject (currentFocusCycleRoots);
+ }
+
+ /**
+ * Set the {@link Container} that will be returned by {@link
+ * #getCurrentFocusCycleRoot} (when it is called from the current
+ * {@link java.lang.ThreadGroup}) and {@link
+ * #getGlobalCurrentFocusCycleRoot}. This method does not actually
+ * make <code>cycleRoot</code> the current focus cycle root.
+ *
+ * @param cycleRoot the focus cycle root to return from
+ * getCurrentFocusCycleRoot and getGlobalCurrentFocusCycleRoot
+ */
+ public void setGlobalCurrentFocusCycleRoot (Container cycleRoot)
+ {
+ setGlobalObject (currentFocusCycleRoots, cycleRoot, "currentFocusCycleRoot");
+ }
+
+ /**
+ * Registers the supplied property change listener for receiving
+ * events caused by the following property changes:
+ *
+ * <ul>
+ * <li>the current focus owner ("focusOwner")</li>
+ * <li>the permanent focus owner ("permanentFocusOwner")</li>
+ * <li>the focused window ("focusedWindow")</li>
+ * <li>the active window ("activeWindow")</li>
+ * <li>the default focus traversal policy ("defaultFocusTraversalPolicy")</li>
+ * <li>the default set of forward traversal keys ("forwardDefaultFocusTraversalKeys")</li>
+ * <li>the default set of backward traversal keys ("backwardDefaultFocusTraversalKeys")</li>
+ * <li>the default set of up cycle traversal keys ("upCycleDefaultFocusTraversalKeys")</li>
+ * <li>the default set of down cycle traversal keys ("downCycleDefaultFocusTraversalKeys")</li>
+ * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
+ * </ul>
+ *
+ * If the supplied listener is null, nothing occurs.
+ *
+ * @param l the new listener to register.
+ * @see KeyboardFocusManager#addPropertyChangeListener(String, java.beans.PropertyChangeListener)
+ */
+ public void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ if (l != null)
+ propertyChangeSupport.addPropertyChangeListener(l);
+ }
+
+ /**
+ * Removes the supplied property change listener from the list
+ * of registered listeners. If the supplied listener is null,
+ * nothing occurs.
+ *
+ * @param l the listener to remove.
+ */
+ public void removePropertyChangeListener(PropertyChangeListener l)
+ {
+ if (l != null)
+ propertyChangeSupport.removePropertyChangeListener(l);
+ }
+
+ /**
+ * Returns the currently registered property change listeners
+ * in array form. The returned array is empty if no listeners are
+ * currently registered.
+ *
+ * @return an array of registered property change listeners.
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners()
+ {
+ return propertyChangeSupport.getPropertyChangeListeners();
+ }
+
+ /**
+ * Registers a property change listener for receiving events relating
+ * to a change to a specified property. The supplied property name can be
+ * either user-defined or one from the following list of properties
+ * relevant to this class:
+ *
+ * <ul>
+ * <li>the current focus owner ("focusOwner")</li>
+ * <li>the permanent focus owner ("permanentFocusOwner")</li>
+ * <li>the focused window ("focusedWindow")</li>
+ * <li>the active window ("activeWindow")</li>
+ * <li>the default focus traversal policy ("defaultFocusTraversalPolicy")</li>
+ * <li>the default set of forward traversal keys ("forwardDefaultFocusTraversalKeys")</li>
+ * <li>the default set of backward traversal keys ("backwardDefaultFocusTraversalKeys")</li>
+ * <li>the default set of up cycle traversal keys ("upCycleDefaultFocusTraversalKeys")</li>
+ * <li>the default set of down cycle traversal keys ("downCycleDefaultFocusTraversalKeys")</li>
+ * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
+ * </ul>
+ *
+ * Nothing occurs if a null listener is supplied. null is regarded as a valid property name.
+ *
+ * @param name the name of the property to handle change events for.
+ * @param l the listener to register for changes to the specified property.
+ * @see KeyboardFocusManager#addPropertyChangeListener(java.beans.PropertyChangeListener)
+ */
+ public void addPropertyChangeListener(String name, PropertyChangeListener l)
+ {
+ if (l != null)
+ propertyChangeSupport.addPropertyChangeListener(name, l);
+ }
+
+ /**
+ * Removes the supplied property change listener registered for the
+ * specified property from the list of registered listeners. If the
+ * supplied listener is null, nothing occurs.
+ *
+ * @param name the name of the property the listener is
+ * monitoring changes to.
+ * @param l the listener to remove.
+ */
+ public void removePropertyChangeListener(String name,
+ PropertyChangeListener l)
+ {
+ if (l != null)
+ propertyChangeSupport.removePropertyChangeListener(name, l);
+ }
+
+ /**
+ * Returns the currently registered property change listeners
+ * in array form, which listen for changes to the supplied property.
+ * The returned array is empty, if no listeners are currently registered
+ * for events pertaining to the supplied property.
+ *
+ * @param name The property the returned listeners monitor for changes.
+ * @return an array of registered property change listeners which
+ * listen for changes to the supplied property.
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners(String name)
+ {
+ return propertyChangeSupport.getPropertyChangeListeners(name);
+ }
+
+ /**
+ * Fires a property change event as a response to a change to
+ * to the specified property. The event is only fired if a
+ * change has actually occurred (i.e. o and n are different).
+ *
+ * @param name The name of the property to which a change occurred.
+ * @param o The old value of the property.
+ * @param n The new value of the property.
+ */
+ protected void firePropertyChange(String name, Object o, Object n)
+ {
+ propertyChangeSupport.firePropertyChange(name, o, n);
+ }
+
+ /**
+ * Registers a vetoable property change listener for receiving events
+ * relating to the following properties:
+ *
+ * <ul>
+ * <li>the current focus owner ("focusOwner")</li>
+ * <li>the permanent focus owner ("permanentFocusOwner")</li>
+ * <li>the focused window ("focusedWindow")</li>
+ * <li>the active window ("activeWindow")</li>
+ * </ul>
+ *
+ * Nothing occurs if a null listener is supplied.
+ *
+ * @param l the listener to register.
+ * @see KeyboardFocusManager#addVetoableChangeListener(String, java.beans.VetoableChangeListener)
+ */
+ public void addVetoableChangeListener(VetoableChangeListener l)
+ {
+ if (l != null)
+ vetoableChangeSupport.addVetoableChangeListener(l);
+ }
+
+ /**
+ * Removes the supplied vetoable property change listener from
+ * the list of registered listeners. If the supplied listener
+ * is null, nothing occurs.
+ *
+ * @param l the listener to remove.
+ */
+ public void removeVetoableChangeListener(VetoableChangeListener l)
+ {
+ if (l != null)
+ vetoableChangeSupport.removeVetoableChangeListener(l);
+ }
+
+ /**
+ * Returns the currently registered vetoable property change listeners
+ * in array form. The returned array is empty if no listeners are
+ * currently registered.
+ *
+ * @return an array of registered vetoable property change listeners.
+ * @since 1.4
+ */
+ public VetoableChangeListener[] getVetoableChangeListeners()
+ {
+ return vetoableChangeSupport.getVetoableChangeListeners();
+ }
+
+ /**
+ * Registers a vetoable property change listener for receiving events relating
+ * to a vetoable change to a specified property. The supplied property name can be
+ * either user-defined or one from the following list of properties
+ * relevant to this class:
+ *
+ * <ul>
+ * <li>the current focus owner ("focusOwner")</li>
+ * <li>the permanent focus owner ("permanentFocusOwner")</li>
+ * <li>the focused window ("focusedWindow")</li>
+ * <li>the active window ("activeWindow")</li>
+ * </ul>
+ *
+ * Nothing occurs if a null listener is supplied. null is regarded as a valid property name.
+ *
+ * @param name the name of the property to handle change events for.
+ * @param l the listener to register for changes to the specified property.
+ * @see KeyboardFocusManager#addVetoableChangeListener(java.beans.VetoableChangeListener)
+ */
+ public void addVetoableChangeListener(String name, VetoableChangeListener l)
+ {
+ if (l != null)
+ vetoableChangeSupport.addVetoableChangeListener(name, l);
+ }
+
+ /**
+ * Removes the supplied vetoable property change listener registered
+ * for the specified property from the list of registered listeners.
+ * If the supplied listener is null, nothing occurs.
+ *
+ * @param name the name of the vetoable property the listener is
+ * monitoring changes to.
+ * @param l the listener to remove.
+ */
+ public void removeVetoableChangeListener(String name,
+ VetoableChangeListener l)
+ {
+ if (l != null)
+ vetoableChangeSupport.removeVetoableChangeListener(name, l);
+ }
+
+ /**
+ * Returns the currently registered vetoable property change listeners
+ * in array form, which listen for changes to the supplied property.
+ * The returned array is empty, if no listeners are currently registered
+ * for events pertaining to the supplied property.
+ *
+ * @param name The property the returned listeners monitor for changes.
+ * @return an array of registered property change listeners which
+ * listen for changes to the supplied property.
+ * @since 1.4
+ */
+ public VetoableChangeListener[] getVetoableChangeListeners(String name)
+ {
+ return vetoableChangeSupport.getVetoableChangeListeners(name);
+ }
+
+ /**
+ * Fires a property change event as a response to a vetoable change to
+ * to the specified property. The event is only fired if a
+ * change has actually occurred (i.e. o and n are different).
+ * In the event that the property change is vetoed, the following
+ * occurs:
+ *
+ * <ol>
+ * <li>
+ * This method throws a <code>PropertyVetoException</code> to
+ * the proposed change.
+ * </li>
+ * <li>
+ * A new event is fired to reverse the previous change.
+ * </li>
+ * <li>
+ * This method again throws a <code>PropertyVetoException</code>
+ * in response to the reversion.
+ * </li>
+ * </ol>
+ *
+ * @param name The name of the property to which a change occurred.
+ * @param o The old value of the property.
+ * @param n The new value of the property.
+ * @throws PropertyVetoException if one of the listeners vetos
+ * the change by throwing this exception.
+ */
+ protected void fireVetoableChange(String name, Object o, Object n)
+ throws PropertyVetoException
+ {
+ vetoableChangeSupport.fireVetoableChange(name, o, n);
+ }
+
+ /**
+ * Adds a key event dispatcher to the list of registered dispatchers.
+ * When a key event is fired, each dispatcher's <code>dispatchKeyEvent</code>
+ * method is called in the order that they were added, prior to the manager
+ * dispatching the event itself. Notifications halt when one of the
+ * dispatchers returns true.
+ * <br />
+ * <br />
+ * The same dispatcher can exist multiple times within the list
+ * of registered dispatchers, and there is no limit on the length
+ * of this list. A null dispatcher is simply ignored.
+ *
+ * @param dispatcher The dispatcher to register.
+ */
+ public void addKeyEventDispatcher(KeyEventDispatcher dispatcher)
+ {
+ if (dispatcher != null)
+ keyEventDispatchers.add(dispatcher);
+ }
+
+ /**
+ * Removes the specified key event dispatcher from the list of
+ * registered dispatchers. The manager always dispatches events,
+ * regardless of its existence within the list. The manager
+ * can be added and removed from the list, as with any other
+ * dispatcher, but this does not affect its ability to dispatch
+ * key events. Non-existent and null dispatchers are simply ignored
+ * by this method.
+ *
+ * @param dispatcher The dispatcher to remove.
+ */
+ public void removeKeyEventDispatcher(KeyEventDispatcher dispatcher)
+ {
+ keyEventDispatchers.remove(dispatcher);
+ }
+
+ /**
+ * Returns the currently registered key event dispatchers in <code>List</code>
+ * form. At present, this only includes dispatchers explicitly registered
+ * via the <code>addKeyEventDispatcher()</code> method, but this behaviour
+ * is subject to change and should not be depended on. The manager itself
+ * may be a member of the list, but only if explicitly registered. If no
+ * dispatchers have been registered, the list will be empty.
+ *
+ * @return A list of explicitly registered key event dispatchers.
+ * @see KeyboardFocusManager#addKeyEventDispatcher(java.awt.KeyEventDispatcher)
+ */
+ protected List getKeyEventDispatchers ()
+ {
+ return (List) keyEventDispatchers.clone ();
+ }
+
+ /**
+ * Adds a key event post processor to the list of registered post processors.
+ * Post processors work in the same way as key event dispatchers, except
+ * that they are invoked after the manager has dispatched the key event,
+ * and not prior to this. Each post processor's <code>postProcessKeyEvent</code>
+ * method is called to see if any post processing needs to be performed. THe
+ * processors are called in the order in which they were added to the list,
+ * and notifications continue until one returns true. As with key event
+ * dispatchers, the manager is implicitly called following this process,
+ * regardless of whether or not it is present within the list.
+ * <br />
+ * <br />
+ * The same post processor can exist multiple times within the list
+ * of registered post processors, and there is no limit on the length
+ * of this list. A null post processor is simply ignored.
+ *
+ * @param postProcessor the post processor to register.
+ * @see KeyboardFocusManager#addKeyEventDispatcher(java.awt.KeyEventDispatcher)
+ */
+ public void addKeyEventPostProcessor (KeyEventPostProcessor postProcessor)
+ {
+ if (postProcessor != null)
+ keyEventPostProcessors.add (postProcessor);
+ }
+
+ /**
+ * Removes the specified key event post processor from the list of
+ * registered post processors. The manager always post processes events,
+ * regardless of its existence within the list. The manager
+ * can be added and removed from the list, as with any other
+ * post processor, but this does not affect its ability to post process
+ * key events. Non-existent and null post processors are simply ignored
+ * by this method.
+ *
+ * @param postProcessor the post processor to remove.
+ */
+ public void removeKeyEventPostProcessor (KeyEventPostProcessor postProcessor)
+ {
+ keyEventPostProcessors.remove (postProcessor);
+ }
+
+ /**
+ * Returns the currently registered key event post processors in <code>List</code>
+ * form. At present, this only includes post processors explicitly registered
+ * via the <code>addKeyEventPostProcessor()</code> method, but this behaviour
+ * is subject to change and should not be depended on. The manager itself
+ * may be a member of the list, but only if explicitly registered. If no
+ * post processors have been registered, the list will be empty.
+ *
+ * @return A list of explicitly registered key event post processors.
+ * @see KeyboardFocusManager#addKeyEventPostProcessor(java.awt.KeyEventPostProcessor)
+ */
+ protected List getKeyEventPostProcessors ()
+ {
+ return (List) keyEventPostProcessors.clone ();
+ }
+
+ /**
+ * The AWT event dispatcher uses this method to request that the manager
+ * handle a particular event. If the manager fails or refuses to
+ * dispatch the supplied event (this method returns false), the
+ * AWT event dispatcher will try to dispatch the event itself.
+ * <br />
+ * <br />
+ * The manager is expected to handle all <code>FocusEvent</code>s
+ * and <code>KeyEvent</code>s, and <code>WindowEvent</code>s
+ * relating to the focus. Dispatch is done with regard to the
+ * the focus owner and the currently focused and active windows.
+ * In handling the event, the source of the event may be overridden.
+ * <br />
+ * <br />
+ * The actual dispatching is performed by calling
+ * <code>redispatchEvent()</code>. This avoids the infinite recursion
+ * of dispatch requests which may occur if this method is called on
+ * the target component.
+ *
+ * @param e the event to dispatch.
+ * @return true if the event was dispatched.
+ * @see KeyboardFocusManager#redispatchEvent(java.awt.Component, java.awt.AWTEvent)
+ * @see KeyEvent
+ * @see FocusEvent
+ * @see WindowEvent
+ */
+ public abstract boolean dispatchEvent (AWTEvent e);
+
+ /**
+ * Handles redispatching of an event so that recursion of
+ * dispatch requests does not occur. Event dispatch methods
+ * within this manager (<code>dispatchEvent()</code>) and
+ * the key event dispatchers should use this method to handle
+ * dispatching rather than the dispatch method of the target
+ * component.
+ * <br />
+ * <br />
+ * <strong>
+ * This method is not intended for general consumption, and is
+ * only for the use of the aforementioned classes.
+ * </strong>
+ *
+ * @param target the target component to which the event is
+ * dispatched.
+ * @param e the event to dispatch.
+ */
+ public final void redispatchEvent (Component target, AWTEvent e)
+ {
+ synchronized (e)
+ {
+ e.setSource (target);
+ target.dispatchEvent (e);
+ }
+ }
+
+ /**
+ * Attempts to dispatch key events for which no key event dispatcher
+ * has so far succeeded. This method is usually called by
+ * <code>dispatchEvent()</code> following the sending of the key
+ * event to any registered key event dispatchers. If the key
+ * event reaches this stage, none of the dispatchers returned
+ * true. This is, of course, always the case if there are no
+ * registered dispatchers.
+ * <br />
+ * <br />
+ * If this method also fails to handle the key event, then
+ * false is returned to the caller. In the case of
+ * <code>dispatchEvent()</code>, the calling method may try
+ * to handle the event itself or simply forward on the
+ * false result to its caller. When the event is dispatched
+ * by this method, a true result is propogated through the
+ * calling methods.
+ *
+ * @param e the key event to dispatch.
+ * @return true if the event was dispatched successfully.
+ */
+ public abstract boolean dispatchKeyEvent (KeyEvent e);
+
+ /**
+ * Handles the post processing of key events. By default,
+ * this method will map unhandled key events to appropriate
+ * <code>MenuShortcut</code>s. The event is consumed
+ * in the process and the shortcut is activated. This
+ * method is usually called by <code>dispatchKeyEvent</code>.
+ *
+ * @param e the key event to post process.
+ * @return true by default, as the event was handled.
+ */
+ public abstract boolean postProcessKeyEvent (KeyEvent e);
+
+ /**
+ * Handles focus traversal operations for key events which
+ * represent focus traversal keys in relation to the supplied
+ * component. The supplied component is assumed to have the
+ * focus, whether it does so or not, and the operation is
+ * carried out as appropriate, with this in mind.
+ *
+ * @param focused the component on which to perform focus traversal,
+ * on the assumption that this component has the focus.
+ * @param e the possible focus traversal key event.
+ */
+ public abstract void processKeyEvent (Component focused, KeyEvent e);
+
+ /**
+ * Delays all key events following the specified timestamp until the
+ * supplied component has focus. The AWT calls this method when it is
+ * determined that a focus change may occur within the native windowing
+ * system. Any key events which occur following the time specified by
+ * after are delayed until a <code>FOCUS_GAINED</code> event is received
+ * for the untilFocused component. The manager is responsible for ensuring
+ * this takes place.
+ *
+ * @param after the timestamp beyond which all key events are delayed until
+ * the supplied component gains focus.
+ * @param untilFocused the component to wait on gaining focus.
+ */
+ protected abstract void enqueueKeyEvents (long after, Component untilFocused);
+
+ /**
+ * Removes the key event block specified by the supplied timestamp and component.
+ * All delayed key events are released for normal dispatching following its
+ * removal and subsequent key events that would have been blocked are now
+ * immediately dispatched. If the specified timestamp is below 0, then
+ * the request with the oldest timestamp is removed.
+ *
+ * @param after the timestamp of the key event block to be removed, or a
+ * value smaller than 0 if the oldest is to be removed.
+ * @param untilFocused the component of the key event block to be removed.
+ */
+ protected abstract void dequeueKeyEvents (long after, Component untilFocused);
+
+ /**
+ * Discards all key event blocks relating to focus requirements for
+ * the supplied component, regardless of timestamp.
+ *
+ * @param comp the component of the key event block(s) to be removed.
+ */
+ protected abstract void discardKeyEvents (Component comp);
+
+ /**
+ * Moves the current focus to the next component following
+ * comp, based on the current focus traversal policy. By
+ * default, only visible, displayable, accepted components
+ * can receive focus. <code>Canvas</code>es, <code>Panel</code>s,
+ * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
+ * <code>Window</code>s and lightweight components are judged
+ * to be unacceptable by default. See the
+ * <code>DefaultFocusTraversalPolicy</code> for more details.
+ *
+ * @param comp the component prior to the one which will
+ * become the focus, following execution of this method.
+ * @see DefaultFocusTraversalPolicy
+ */
+ public abstract void focusNextComponent(Component comp);
+
+ /**
+ * Moves the current focus to the previous component, prior to
+ * comp, based on the current focus traversal policy. By
+ * default, only visible, displayable, accepted components
+ * can receive focus. <code>Canvas</code>es, <code>Panel</code>s,
+ * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
+ * <code>Window</code>s and lightweight components are judged
+ * to be unacceptable by default. See the
+ * <code>DefaultFocusTraversalPolicy</code> for more details.
+ *
+ * @param comp the component following the one which will
+ * become the focus, following execution of this method.
+ * @see DefaultFocusTraversalPolicy
+ */
+ public abstract void focusPreviousComponent(Component comp);
+
+ /**
+ * Moves the current focus upwards by one focus cycle.
+ * Both the current focus owner and current focus cycle root
+ * become the focus cycle root of the supplied component.
+ * However, in the case of a <code>Window</code>, the default
+ * focus component becomes the focus owner and the focus cycle
+ * root is not changed.
+ *
+ * @param comp the component used as part of the focus traversal.
+ */
+ public abstract void upFocusCycle(Component comp);
+
+ /**
+ * Moves the current focus downwards by one focus cycle.
+ * If the supplied container is a focus cycle root, then this
+ * becomes the current focus cycle root and the focus goes
+ * to the default component of the specified container.
+ * Nothing happens for non-focus cycle root containers.
+ *
+ * @param cont the container used as part of the focus traversal.
+ */
+ public abstract void downFocusCycle(Container cont);
+
+ /**
+ * Moves the current focus to the next component, based on the
+ * current focus traversal policy. By default, only visible,
+ * displayable, accepted component can receive focus.
+ * <code>Canvas</code>es, <code>Panel</code>s,
+ * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
+ * <code>Window</code>s and lightweight components are judged
+ * to be unacceptable by default. See the
+ * <code>DefaultFocusTraversalPolicy</code> for more details.
+ *
+ * @see DefaultFocusTraversalPolicy
+ */
+ public final void focusNextComponent()
+ {
+ focusNextComponent (null);
+ }
+
+ /**
+ * Moves the current focus to the previous component, based on the
+ * current focus traversal policy. By default, only visible,
+ * displayable, accepted component can receive focus.
+ * <code>Canvas</code>es, <code>Panel</code>s,
+ * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
+ * <code>Window</code>s and lightweight components are judged
+ * to be unacceptable by default. See the
+ * <code>DefaultFocusTraversalPolicy</code> for more details.
+ *
+ * @see DefaultFocusTraversalPolicy
+ */
+ public final void focusPreviousComponent()
+ {
+ focusPreviousComponent (null);
+ }
+
+ /**
+ * Moves the current focus upwards by one focus cycle,
+ * so that the new focus owner is the focus cycle root
+ * of the current owner. The current focus cycle root then
+ * becomes the focus cycle root of the new focus owner.
+ * However, in the case of the focus cycle root of the
+ * current focus owner being a <code>Window</code>, the default
+ * component of this window becomes the focus owner and the
+ * focus cycle root is not changed.
+ */
+ public final void upFocusCycle()
+ {
+ upFocusCycle (null);
+ }
+
+ /**
+ * Moves the current focus downwards by one focus cycle,
+ * iff the current focus cycle root is a <code>Container</code>.
+ * Usually, the new focus owner is set to the default component
+ * of the container and the current focus cycle root is set
+ * to the current focus owner. Nothing occurs if the current
+ * focus cycle root is not a container.
+ */
+ public final void downFocusCycle()
+ {
+ Component focusOwner = getGlobalFocusOwner ();
+ if (focusOwner instanceof Container
+ && ((Container) focusOwner).isFocusCycleRoot ())
+ downFocusCycle ((Container) focusOwner);
+ }
+
+ /**
+ * Retrieve an object from one of the global object {@link
+ * java.util.Map}s, if the object was set by the a thread in the
+ * current {@link java.lang.ThreadGroup}. Otherwise, return null.
+ *
+ * @param globalMap one of the global object Maps
+ *
+ * @return a global object set by the current ThreadGroup, or null
+ *
+ * @see getFocusOwner
+ * @see getPermanentFocusOwner
+ * @see getFocusedWindow
+ * @see getActiveWindow
+ * @see getCurrentFocusCycleRoot
+ */
+ private Object getObject (Map globalMap)
+ {
+ ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+ return globalMap.get (currentGroup);
+ }
+
+ /**
+ * Retrieve an object from one of the global object {@link
+ * java.util.Map}s, regardless of whether or not the object was set
+ * by a thread in the current {@link java.lang.ThreadGroup}.
+ *
+ * @param globalMap one of the global object Maps
+ *
+ * @return a global object set by the current ThreadGroup, or null
+ *
+ * @throws SecurityException if this is not the keyboard focus
+ * manager associated with the current {@link java.lang.ThreadGroup}
+ *
+ * @see getGlobalFocusOwner
+ * @see getGlobalPermanentFocusOwner
+ * @see getGlobalFocusedWindow
+ * @see getGlobalActiveWindow
+ * @see getGlobalCurrentFocusCycleRoot
+ */
+ private Object getGlobalObject (Map globalMap)
+ {
+ ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+ KeyboardFocusManager managerForCallingThread
+ = (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
+
+ if (this != managerForCallingThread)
+ throw new SecurityException ("Attempted to retrieve an object from a "
+ + "keyboard focus manager that isn't "
+ + "associated with the current thread group.");
+
+ synchronized (globalMap)
+ {
+ Collection globalObjects = globalMap.values ();
+ Iterator i = globalObjects.iterator ();
+ Component globalObject;
+
+ while (i.hasNext ())
+ {
+ globalObject = (Component) i.next ();
+ if (globalObject != null)
+ return globalObject;
+ }
+ }
+
+ // No Object was found.
+ return null;
+ }
+
+ /**
+ * Set an object in one of the global object {@link java.util.Map}s,
+ * that will be returned by subsequent calls to getGlobalObject on
+ * the same {@link java.util.Map}.
+ *
+ * @param globalMap one of the global object Maps
+ * @param newObject the object to set
+ * @param property the property that will change
+ *
+ * @see setGlobalFocusOwner
+ * @see setGlobalPermanentFocusOwner
+ * @see setGlobalFocusedWindow
+ * @see setGlobalActiveWindow
+ * @see setGlobalCurrentFocusCycleRoot
+ */
+ private void setGlobalObject (Map globalMap,
+ Object newObject,
+ String property)
+ {
+ synchronized (globalMap)
+ {
+ // Save old object.
+ Object oldObject = getGlobalObject (globalMap);
+
+ // Nullify old object.
+ Collection threadGroups = globalMap.keySet ();
+ Iterator i = threadGroups.iterator ();
+ while (i.hasNext ())
+ {
+ ThreadGroup oldThreadGroup = (ThreadGroup) i.next ();
+ if (globalMap.get (oldThreadGroup) != null)
+ {
+ globalMap.put (oldThreadGroup, null);
+ // There should only be one object set at a time, so
+ // we can short circuit.
+ break;
+ }
+ }
+
+ ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+ firePropertyChange (property, oldObject, newObject);
+ try
+ {
+ fireVetoableChange (property, oldObject, newObject);
+ // Set new object.
+ globalMap.put (currentGroup, newObject);
+ }
+ catch (PropertyVetoException e)
+ {
+ }
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/Label.java b/libjava/classpath/java/awt/Label.java
new file mode 100644
index 0000000..8867fa1
--- /dev/null
+++ b/libjava/classpath/java/awt/Label.java
@@ -0,0 +1,314 @@
+/* Label.java -- Java label widget
+ Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.peer.LabelPeer;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * This component is used for displaying simple text strings that cannot
+ * be edited by the user.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+public class Label extends Component implements Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+/**
+ * Alignment constant aligning the text to the left of its window.
+ */
+public static final int LEFT = 0;
+
+/**
+ * Alignment constant aligning the text in the center of its window.
+ */
+public static final int CENTER = 1;
+
+/**
+ * Alignment constant aligning the text to the right of its window.
+ */
+public static final int RIGHT = 2;
+
+// Serialization version constant:
+private static final long serialVersionUID = 3094126758329070636L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial Indicates the alignment of the text within this label's window.
+ * This is one of the constants in this class. The default value is
+ * <code>LEFT</code>.
+ */
+private int alignment;
+
+/**
+ * @serial The text displayed in the label
+ */
+private String text;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>Label</code> with no text.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+Label()
+{
+ this("", LEFT);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Label</code> with the specified
+ * text that is aligned to the left.
+ *
+ * @param text The text of the label.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+Label(String text)
+{
+ this(text, LEFT);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Label</code> with the specified
+ * text and alignment.
+ *
+ * @param text The text of the label.
+ * @param alignment The desired alignment for the text in this label,
+ * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
+ * <code>RIGHT</code>.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+Label(String text, int alignment)
+{
+ setAlignment (alignment);
+ setText (text);
+
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Returns the constant indicating the alignment of the text in this
+ * label. The value returned will be one of the alignment constants
+ * from this class.
+ *
+ * @return The alignment of the text in the label.
+ */
+public int
+getAlignment()
+{
+ return(alignment);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the text alignment of this label to the specified value.
+ *
+ * @param alignment The desired alignment for the text in this label,
+ * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
+ * <code>RIGHT</code>.
+ */
+public synchronized void
+setAlignment(int alignment)
+{
+ if (alignment != CENTER && alignment != LEFT && alignment != RIGHT)
+ throw new IllegalArgumentException ("invalid alignment: " + alignment);
+ this.alignment = alignment;
+ if (peer != null)
+ {
+ LabelPeer lp = (LabelPeer) peer;
+ lp.setAlignment (alignment);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the text displayed in this label.
+ *
+ * @return The text for this label.
+ */
+public String
+getText()
+{
+ return(text);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the text in this label to the specified value.
+ *
+ * @param text The new text for this label.
+ */
+public synchronized void
+setText(String text)
+{
+ this.text = text;
+
+ if (peer != null)
+ {
+ LabelPeer lp = (LabelPeer) peer;
+ lp.setText (text);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Notifies this label that it has been added to a container, causing
+ * the peer to be created. This method is called internally by the AWT
+ * system.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createLabel (this);
+ super.addNotify ();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a parameter string useful for debugging.
+ *
+ * @return A debugging string.
+ */
+protected String
+paramString()
+{
+ return ("text=" + getText() + ",alignment=" +
+ getAlignment() + "," + super.paramString());
+}
+
+/**
+ * This class provides accessibility support for the label.
+ */
+protected class AccessibleAWTLabel
+ extends AccessibleAWTComponent
+{
+ /**
+ * For compatability with Sun's JDK 1.4.2 rev. 5
+ */
+ private static final long serialVersionUID = -3568967560160480438L;
+
+ /**
+ * Constructor for the accessible label.
+ */
+ public AccessibleAWTLabel()
+ {
+ }
+
+ /**
+ * Returns the accessible name for the label. This is
+ * the text used in the label.
+ *
+ * @return a <code>String</code> containing the accessible
+ * name for this label.
+ */
+ public String getAccessibleName()
+ {
+ return getText();
+ }
+
+ /**
+ * Returns the accessible role for the label.
+ *
+ * @return an instance of <code>AccessibleRole</code>, describing
+ * the role of the label.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.LABEL;
+ }
+
+}
+
+/**
+ * Gets the AccessibleContext associated with this <code>Label</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+public AccessibleContext getAccessibleContext()
+{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTLabel();
+ return accessibleContext;
+}
+
+} // class Label
+
diff --git a/libjava/classpath/java/awt/LayoutManager.java b/libjava/classpath/java/awt/LayoutManager.java
new file mode 100644
index 0000000..62ff808
--- /dev/null
+++ b/libjava/classpath/java/awt/LayoutManager.java
@@ -0,0 +1,92 @@
+/* LayoutManager.java -- lay out elements in a Container
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This interface is for laying out containers in a particular sequence.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see Container
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public interface LayoutManager
+{
+ /**
+ * Adds the specified component to the layout group.
+ *
+ * @param name the name of the component to add
+ * @param component the component to add
+ */
+ void addLayoutComponent(String name, Component component);
+
+ /**
+ * Removes the specified component from the layout group.
+ *
+ * @param component the component to remove
+ */
+ void removeLayoutComponent(Component component);
+
+ /**
+ * Calculates the preferred size for this container, taking into account
+ * the components it contains.
+ *
+ * @param parent the parent container to lay out
+ * @return the preferred dimensions of this container
+ * @see #minimumLayoutSize(Container)
+ */
+ Dimension preferredLayoutSize(Container parent);
+
+ /**
+ * Calculates the minimum size for this container, taking into account
+ * the components it contains.
+ *
+ * @param parent the parent container to lay out
+ * @return the minimum dimensions of this container
+ * @see #preferredLayoutSize(Container)
+ */
+ Dimension minimumLayoutSize(Container parent);
+
+ /**
+ * Lays out the components in the given container.
+ *
+ * @param parent the container to lay out
+ */
+ void layoutContainer(Container parent);
+} // interface LayoutManager
diff --git a/libjava/classpath/java/awt/LayoutManager2.java b/libjava/classpath/java/awt/LayoutManager2.java
new file mode 100644
index 0000000..45fc543
--- /dev/null
+++ b/libjava/classpath/java/awt/LayoutManager2.java
@@ -0,0 +1,100 @@
+/* LayoutManager2.java -- enhanced layout manager
+ Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * Layout manager for laying out containers based on contraints. The
+ * constraints control how the layout will proceed.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see LayoutManager
+ * @see Container
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public interface LayoutManager2 extends LayoutManager
+{
+ /**
+ * Adds the specified component to the layout, with the specified
+ * constraints object.
+ *
+ * @param component the component to add
+ * @param constraints the constraints to satisfy
+ */
+ void addLayoutComponent(Component component, Object constraints);
+
+ /**
+ * Determines the maximum size of the specified target container.
+ *
+ * @param target the container to lay out
+ * @return the maximum size of the container
+ * @see Component#getMaximumSize()
+ */
+ Dimension maximumLayoutSize(Container target);
+
+ /**
+ * Returns the preferred X axis alignment for the specified target
+ * container. This value will range from 0 to 1 where 0 is alignment
+ * closest to the origin, 0.5 is centered, and 1 is aligned furthest
+ * from the origin.
+ *
+ * @param target the target container
+ * @return the x-axis alignment preference
+ */
+ float getLayoutAlignmentX(Container target);
+
+ /**
+ * Returns the preferred Y axis alignment for the specified target
+ * container. This value will range from 0 to 1 where 0 is alignment
+ * closest to the origin, 0.5 is centered, and 1 is aligned furthest
+ * from the origin.
+ *
+ * @param target the target container
+ * @return the y-axis alignment preference
+ */
+ float getLayoutAlignmentY(Container target);
+
+ /**
+ * Forces the layout manager to purge any cached information about the
+ * layout of the target container. This will force it to be recalculated.
+ *
+ * @param target the target container
+ */
+ void invalidateLayout(Container target);
+} // interface LayoutManager2
diff --git a/libjava/classpath/java/awt/List.java b/libjava/classpath/java/awt/List.java
new file mode 100644
index 0000000..5fcc79b
--- /dev/null
+++ b/libjava/classpath/java/awt/List.java
@@ -0,0 +1,1263 @@
+/* List.java -- A listbox widget
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.peer.ListPeer;
+import java.util.EventListener;
+import java.util.Vector;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+
+/**
+ * Class that implements a listbox widget
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class List extends Component
+ implements ItemSelectable, Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization constant
+private static final long serialVersionUID = -3304312411574666869L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+// FIXME: Need read/writeObject
+
+/**
+ * @serial The items in the list.
+ */
+private Vector items = new Vector();
+
+/**
+ * @serial Indicates whether or not multiple items can be selected
+ * simultaneously.
+ */
+private boolean multipleMode;
+
+/**
+ * @serial The number of rows in the list. This is set on creation
+ * only and cannot be modified.
+ */
+private int rows;
+
+/**
+ * @serial An array of the item indices that are selected.
+ */
+private int[] selected;
+
+/**
+ * @serial An index value used by <code>makeVisible()</code> and
+ * <code>getVisibleIndex</code>.
+ */
+private int visibleIndex;
+
+// The list of ItemListeners for this object.
+private ItemListener item_listeners;
+
+// The list of ActionListeners for this object.
+private ActionListener action_listeners;
+
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>List</code> with no visible lines
+ * and multi-select disabled.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+List()
+{
+ this(4, false);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>List</code> with the specified
+ * number of visible lines and multi-select disabled.
+ *
+ * @param rows The number of visible rows in the list.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+List(int rows)
+{
+ this(rows, false);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>List</code> with the specified
+ * number of lines and the specified multi-select setting.
+ *
+ * @param rows The number of visible rows in the list.
+ * @param multipleMode <code>true</code> if multiple lines can be selected
+ * simultaneously, <code>false</code> otherwise.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+List(int rows, boolean multipleMode)
+{
+ this.rows = rows;
+ this.multipleMode = multipleMode;
+
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Returns the number of items in this list.
+ *
+ * @return The number of items in this list.
+ */
+public int
+getItemCount()
+{
+ return countItems ();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the number of items in this list.
+ *
+ * @return The number of items in this list.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getItemCount()</code>
+ */
+public int
+countItems()
+{
+ return items.size ();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the complete list of items.
+ *
+ * @return The complete list of items in the list.
+ */
+public synchronized String[]
+getItems()
+{
+ String[] l_items = new String[getItemCount()];
+
+ items.copyInto(l_items);
+ return(l_items);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the item at the specified index.
+ *
+ * @param index The index of the item to retrieve.
+ *
+ * @exception IndexOutOfBoundsException If the index value is not valid.
+ */
+public String
+getItem(int index)
+{
+ return((String)items.elementAt(index));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the number of visible rows in the list.
+ *
+ * @return The number of visible rows in the list.
+ */
+public int
+getRows()
+{
+ return(rows);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not multi-select mode is enabled.
+ *
+ * @return <code>true</code> if multi-select mode is enabled,
+ * <code>false</code> otherwise.
+ */
+public boolean
+isMultipleMode()
+{
+ return allowsMultipleSelections ();
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not multi-select mode is enabled.
+ *
+ * @return <code>true</code> if multi-select mode is enabled,
+ * <code>false</code> otherwise.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>isMultipleMode()</code>.
+ */
+public boolean
+allowsMultipleSelections()
+{
+ return multipleMode;
+}
+
+/*************************************************************************/
+
+/**
+ * This method enables or disables multiple selection mode for this
+ * list.
+ *
+ * @param multipleMode <code>true</code> to enable multiple mode,
+ * <code>false</code> otherwise.
+ */
+public void
+setMultipleMode(boolean multipleMode)
+{
+ setMultipleSelections (multipleMode);
+}
+
+/*************************************************************************/
+
+/**
+ * This method enables or disables multiple selection mode for this
+ * list.
+ *
+ * @param multipleMode <code>true</code> to enable multiple mode,
+ * <code>false</code> otherwise.
+ *
+ * @deprecated
+ */
+public void
+setMultipleSelections(boolean multipleMode)
+{
+ this.multipleMode = multipleMode;
+
+ ListPeer peer = (ListPeer) getPeer ();
+ if (peer != null)
+ peer.setMultipleMode (multipleMode);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size of this component.
+ *
+ * @return The minimum size of this component.
+ */
+public Dimension
+getMinimumSize()
+{
+ return getMinimumSize (getRows ());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size of this component.
+ *
+ * @return The minimum size of this component.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMinimumSize</code>.
+ */
+public Dimension
+minimumSize()
+{
+ return minimumSize (getRows ());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size of this component assuming it had the specified
+ * number of rows.
+ *
+ * @param rows The number of rows to size for.
+ *
+ * @return The minimum size of this component.
+ */
+public Dimension
+getMinimumSize(int rows)
+{
+ return minimumSize (rows);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size of this component assuming it had the specified
+ * number of rows.
+ *
+ * @param rows The number of rows to size for.
+ *
+ * @return The minimum size of this component.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMinimumSize(int)</code>>
+ */
+public Dimension
+minimumSize(int rows)
+{
+ ListPeer peer = (ListPeer) getPeer ();
+ if (peer != null)
+ return peer.minimumSize (rows);
+ else
+ return new Dimension (0, 0);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size of this component.
+ *
+ * @return The preferred size of this component.
+ */
+public Dimension
+getPreferredSize()
+{
+ return getPreferredSize (getRows ());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size of this component.
+ *
+ * @return The preferred size of this component.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getPreferredSize</code>.
+ */
+public Dimension
+preferredSize()
+{
+ return preferredSize (getRows ());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size of this component assuming it had the specified
+ * number of rows.
+ *
+ * @param rows The number of rows to size for.
+ *
+ * @return The preferred size of this component.
+ */
+public Dimension
+getPreferredSize(int rows)
+{
+ return preferredSize (rows);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size of this component assuming it had the specified
+ * number of rows.
+ *
+ * @param rows The number of rows to size for.
+ *
+ * @return The preferred size of this component.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getPreferredSize(int)</code>>
+ */
+public Dimension
+preferredSize(int rows)
+{
+ ListPeer peer = (ListPeer) getPeer ();
+ if (peer != null)
+ return peer.preferredSize (rows);
+ else
+ return new Dimension (0, 0);
+}
+
+/*************************************************************************/
+
+/**
+ * This method adds the specified item to the end of the list.
+ *
+ * @param item The item to add to the list.
+ */
+public void
+add(String item)
+{
+ add (item, -1);
+}
+
+/*************************************************************************/
+
+/**
+ * This method adds the specified item to the end of the list.
+ *
+ * @param item The item to add to the list.
+ *
+ * @deprecated Use add() instead.
+ */
+public void
+addItem(String item)
+{
+ addItem (item, -1);
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified item to the specified location in the list.
+ * If the desired index is -1 or greater than the number of rows
+ * in the list, then the item is added to the end.
+ *
+ * @param item The item to add to the list.
+ * @param index The location in the list to add the item, or -1 to add
+ * to the end.
+ */
+public void
+add(String item, int index)
+{
+ addItem (item, index);
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified item to the specified location in the list.
+ * If the desired index is -1 or greater than the number of rows
+ * in the list, then the item is added to the end.
+ *
+ * @param item The item to add to the list.
+ * @param index The location in the list to add the item, or -1 to add
+ * to the end.
+ *
+ * @deprecated Use add() instead.
+ */
+public void
+addItem(String item, int index)
+{
+ if ((index == -1) || (index >= items.size ()))
+ items.addElement (item);
+ else
+ items.insertElementAt (item, index);
+
+ ListPeer peer = (ListPeer) getPeer ();
+ if (peer != null)
+ peer.add (item, index);
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes the item at the specified index.
+ *
+ * @param index The index of the item to delete.
+ *
+ * @exception IllegalArgumentException If the index is not valid
+ *
+ * @deprecated
+ */
+public void
+delItem(int index) throws IllegalArgumentException
+{
+ items.removeElementAt (index);
+
+ ListPeer peer = (ListPeer) getPeer ();
+ if (peer != null)
+ peer.delItems (index, index);
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes the item at the specified index.
+ *
+ * @param index The index of the item to delete.
+ *
+ * @exception IllegalArgumentException If the index is not valid
+ */
+public void
+remove(int index) throws IllegalArgumentException
+{
+ delItem (index);
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes all items in the specified index range.
+ *
+ * @param start The beginning index of the range to delete.
+ * @param end The ending index of the range to delete.
+ *
+ * @exception IllegalArgumentException If the indexes are not valid
+ *
+ * @deprecated This method is deprecated for some unknown reason.
+ */
+public synchronized void
+delItems(int start, int end) throws IllegalArgumentException
+{
+ if ((start < 0) || (start >= items.size()))
+ throw new IllegalArgumentException("Bad list start index value: " + start);
+
+ if ((start < 0) || (start >= items.size()))
+ throw new IllegalArgumentException("Bad list start index value: " + start);
+
+ if (start > end)
+ throw new IllegalArgumentException("Start is greater than end!");
+
+ // We must run the loop in reverse direction.
+ for (int i = end; i >= start; --i)
+ items.removeElementAt (i);
+ if (peer != null)
+ {
+ ListPeer l = (ListPeer) peer;
+ l.delItems (start, end);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes the first occurrence of the specified item from the list.
+ *
+ * @param item The item to delete.
+ *
+ * @exception IllegalArgumentException If the specified item does not exist.
+ */
+public synchronized void
+remove(String item) throws IllegalArgumentException
+{
+ int index = items.indexOf(item);
+ if (index == -1)
+ throw new IllegalArgumentException("List element to delete not found");
+
+ remove(index);
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes all of the items from the list.
+ */
+public synchronized void
+removeAll()
+{
+ clear ();
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes all of the items from the list.
+ *
+ * @deprecated This method is deprecated in favor of <code>removeAll()</code>.
+ */
+public void
+clear()
+{
+ items.clear();
+
+ ListPeer peer = (ListPeer) getPeer ();
+ if (peer != null)
+ peer.removeAll ();
+}
+
+/*************************************************************************/
+
+/**
+ * Replaces the item at the specified index with the specified item.
+ *
+ * @param item The new item value.
+ * @param index The index of the item to replace.
+ *
+ * @exception IllegalArgumentException If the index is not valid.
+ */
+public synchronized void
+replaceItem(String item, int index) throws IllegalArgumentException
+{
+ if ((index < 0) || (index >= items.size()))
+ throw new IllegalArgumentException("Bad list index: " + index);
+
+ items.insertElementAt(item, index + 1);
+ items.removeElementAt (index);
+
+ if (peer != null)
+ {
+ ListPeer l = (ListPeer) peer;
+
+ /* We add first and then remove so that the selected
+ item remains the same */
+ l.add (item, index + 1);
+ l.delItems (index, index);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the index of the currently selected item. -1 will be returned
+ * if there are no selected rows or if there are multiple selected rows.
+ *
+ * @return The index of the selected row.
+ */
+public synchronized int
+getSelectedIndex()
+{
+ if (peer != null)
+ {
+ ListPeer l = (ListPeer) peer;
+ selected = l.getSelectedIndexes ();
+ }
+
+ if (selected == null || selected.length != 1)
+ return -1;
+ return selected[0];
+}
+
+/*************************************************************************/
+
+/**
+ * Returns an array containing the indexes of the rows that are
+ * currently selected.
+ *
+ * @return A list of indexes of selected rows.
+ */
+public synchronized int[]
+getSelectedIndexes()
+{
+ if (peer != null)
+ {
+ ListPeer l = (ListPeer) peer;
+ selected = l.getSelectedIndexes ();
+ }
+ return selected;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the item that is currently selected, or <code>null</code> if there
+ * is no item selected. FIXME: What happens if multiple items selected?
+ *
+ * @return The selected item, or <code>null</code> if there is no
+ * selected item.
+ */
+public synchronized String
+getSelectedItem()
+{
+ int index = getSelectedIndex();
+ if (index == -1)
+ return(null);
+
+ return((String)items.elementAt(index));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the list of items that are currently selected in this list.
+ *
+ * @return The list of currently selected items.
+ */
+public synchronized String[]
+getSelectedItems()
+{
+ int[] indexes = getSelectedIndexes();
+ if (indexes == null)
+ return(new String[0]);
+
+ String[] retvals = new String[indexes.length];
+ if (retvals.length > 0)
+ for (int i = 0 ; i < retvals.length; i++)
+ retvals[i] = (String)items.elementAt(indexes[i]);
+
+ return(retvals);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the list of items that are currently selected in this list as
+ * an array of type <code>Object[]</code> instead of <code>String[]</code>.
+ *
+ * @return The list of currently selected items.
+ */
+public synchronized Object[]
+getSelectedObjects()
+{
+ int[] indexes = getSelectedIndexes();
+ if (indexes == null)
+ return(new Object[0]);
+
+ Object[] retvals = new Object[indexes.length];
+ if (retvals.length > 0)
+ for (int i = 0 ; i < retvals.length; i++)
+ retvals[i] = items.elementAt(indexes[i]);
+
+ return(retvals);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not the specified index is selected.
+ *
+ * @param index The index to test.
+ *
+ * @return <code>true</code> if the index is selected, <code>false</code>
+ * otherwise.
+ */
+public boolean
+isIndexSelected(int index)
+{
+ return isSelected (index);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not the specified index is selected.
+ *
+ * @param index The index to test.
+ *
+ * @return <code>true</code> if the index is selected, <code>false</code>
+ * otherwise.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>isIndexSelected(int)</code>.
+ */
+public boolean
+isSelected(int index)
+{
+ int[] indexes = getSelectedIndexes ();
+
+ for (int i = 0; i < indexes.length; i++)
+ if (indexes[i] == index)
+ return true;
+
+ return false;
+}
+
+/*************************************************************************/
+
+/**
+ * This method ensures that the item at the specified index is visible.
+ *
+ * @exception IllegalArgumentException If the specified index is out of
+ * range.
+ */
+public synchronized void
+makeVisible(int index) throws IllegalArgumentException
+{
+ if ((index < 0) || (index >= items.size()))
+ throw new IllegalArgumentException("Bad list index: " + index);
+
+ visibleIndex = index;
+ if (peer != null)
+ {
+ ListPeer l = (ListPeer) peer;
+ l.makeVisible (index);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the index of the last item that was made visible via the
+ * <code>makeVisible()</code> method.
+ *
+ * @return The index of the last item made visible via the
+ * <code>makeVisible()</code> method.
+ */
+public int
+getVisibleIndex()
+{
+ return(visibleIndex);
+}
+
+/*************************************************************************/
+
+/**
+ * Makes the item at the specified index selected.
+ *
+ * @param index The index of the item to select.
+ */
+public synchronized void
+select(int index)
+{
+ ListPeer lp = (ListPeer)getPeer();
+ if (lp != null)
+ lp.select(index);
+}
+
+/*************************************************************************/
+
+/**
+ * Makes the item at the specified index not selected.
+ *
+ * @param index The index of the item to unselect.
+ */
+public synchronized void
+deselect(int index)
+{
+ ListPeer lp = (ListPeer)getPeer();
+ if (lp != null)
+ lp.deselect(index);
+}
+
+/*************************************************************************/
+
+/**
+ * Notifies this object to create its native peer.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createList (this);
+ super.addNotify ();
+}
+
+/*************************************************************************/
+
+/**
+ * Notifies this object to destroy its native peer.
+ */
+public void
+removeNotify()
+{
+ super.removeNotify();
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified <code>ActionListener</code> to the list of
+ * registered listeners for this object.
+ *
+ * @param listener The listener to add.
+ */
+public synchronized void
+addActionListener(ActionListener listener)
+{
+ action_listeners = AWTEventMulticaster.add(action_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified <code>ActionListener</code> from the list of
+ * registers listeners for this object.
+ *
+ * @param listener The listener to remove.
+ */
+public synchronized void
+removeActionListener(ActionListener listener)
+{
+ action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified <code>ItemListener</code> to the list of
+ * registered listeners for this object.
+ *
+ * @param listener The listener to add.
+ */
+public synchronized void
+addItemListener(ItemListener listener)
+{
+ item_listeners = AWTEventMulticaster.add(item_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified <code>ItemListener</code> from the list of
+ * registers listeners for this object.
+ *
+ * @param listener The listener to remove.
+ */
+public synchronized void
+removeItemListener(ItemListener listener)
+{
+ item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes the specified event for this object. If the event is an
+ * instance of <code>ActionEvent</code> then the
+ * <code>processActionEvent()</code> method is called. Similarly, if the
+ * even is an instance of <code>ItemEvent</code> then the
+ * <code>processItemEvent()</code> method is called. Otherwise the
+ * superclass method is called to process this event.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ if (event instanceof ActionEvent)
+ processActionEvent((ActionEvent)event);
+ else if (event instanceof ItemEvent)
+ processItemEvent((ItemEvent)event);
+ else
+ super.processEvent(event);
+}
+
+/*************************************************************************/
+
+/**
+ * This method processes the specified event by dispatching it to any
+ * registered listeners. Note that this method will only get called if
+ * action events are enabled. This will happen automatically if any
+ * listeners are added, or it can be done "manually" by calling
+ * the <code>enableEvents()</code> method.
+ *
+ * @param event The event to process.
+ */
+protected void
+processActionEvent(ActionEvent event)
+{
+ if (action_listeners != null)
+ action_listeners.actionPerformed(event);
+}
+
+/*************************************************************************/
+
+/**
+ * This method processes the specified event by dispatching it to any
+ * registered listeners. Note that this method will only get called if
+ * item events are enabled. This will happen automatically if any
+ * listeners are added, or it can be done "manually" by calling
+ * the <code>enableEvents()</code> method.
+ *
+ * @param event The event to process.
+ */
+protected void
+processItemEvent(ItemEvent event)
+{
+ if (item_listeners != null)
+ item_listeners.itemStateChanged(event);
+}
+
+void
+dispatchEventImpl(AWTEvent e)
+{
+ if (e.id <= ItemEvent.ITEM_LAST
+ && e.id >= ItemEvent.ITEM_FIRST
+ && (item_listeners != null
+ || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
+ processEvent(e);
+ else if (e.id <= ActionEvent.ACTION_LAST
+ && e.id >= ActionEvent.ACTION_FIRST
+ && (action_listeners != null
+ || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this object.
+ *
+ * @return A debugging string for this object.
+ */
+protected String
+paramString()
+{
+ return "multiple=" + multipleMode + ",rows=" + rows + super.paramString();
+}
+
+ /**
+ * Returns an array of all the objects currently registered as FooListeners
+ * upon this <code>List</code>. FooListeners are registered using the
+ * addFooListener method.
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements java.util.EventListener.
+ */
+ public EventListener[] getListeners (Class listenerType)
+ {
+ if (listenerType == ActionListener.class)
+ return AWTEventMulticaster.getListeners (action_listeners, listenerType);
+
+ if (listenerType == ItemListener.class)
+ return AWTEventMulticaster.getListeners (item_listeners, listenerType);
+
+ return super.getListeners (listenerType);
+ }
+
+ /**
+ * Returns all action listeners registered to this object.
+ */
+ public ActionListener[] getActionListeners ()
+ {
+ return (ActionListener[]) getListeners (ActionListener.class);
+ }
+
+ /**
+ * Returns all action listeners registered to this object.
+ */
+ public ItemListener[] getItemListeners ()
+ {
+ return (ItemListener[]) getListeners (ItemListener.class);
+ }
+
+ // Accessibility internal class
+ protected class AccessibleAWTList extends AccessibleAWTComponent
+ implements AccessibleSelection, ItemListener, ActionListener
+ {
+ protected class AccessibleAWTListChild extends AccessibleAWTComponent
+ implements Accessible
+ {
+ private int index;
+ private List parent;
+
+ public AccessibleAWTListChild(List parent, int indexInParent)
+ {
+ this.parent = parent;
+ index = indexInParent;
+ if (parent == null)
+ index = -1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.Accessible#getAccessibleContext()
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ return this;
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.LIST_ITEM;
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet states = super.getAccessibleStateSet();
+ if (parent.isIndexSelected(index))
+ states.add(AccessibleState.SELECTED);
+ return states;
+ }
+
+ public int getAccessibleIndexInParent()
+ {
+ return index;
+ }
+
+ }
+
+ public AccessibleAWTList()
+ {
+ addItemListener(this);
+ addActionListener(this);
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.LIST;
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet states = super.getAccessibleStateSet();
+ states.add(AccessibleState.SELECTABLE);
+ if (isMultipleMode())
+ states.add(AccessibleState.MULTISELECTABLE);
+ return states;
+ }
+
+ public int getAccessibleChildrenCount()
+ {
+ return getItemCount();
+ }
+
+ public Accessible getAccessibleChild(int i)
+ {
+ if (i >= getItemCount())
+ return null;
+ return new AccessibleAWTListChild(List.this, i);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleSelection#getAccessibleSelectionCount()
+ */
+ public int getAccessibleSelectionCount()
+ {
+ return getSelectedIndexes().length;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleSelection#getAccessibleSelection()
+ */
+ public AccessibleSelection getAccessibleSelection()
+ {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleSelection#getAccessibleSelection(int)
+ */
+ public Accessible getAccessibleSelection(int i)
+ {
+ int[] items = getSelectedIndexes();
+ if (i >= items.length)
+ return null;
+ return new AccessibleAWTListChild(List.this, items[i]);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleSelection#isAccessibleChildSelected(int)
+ */
+ public boolean isAccessibleChildSelected(int i)
+ {
+ return isIndexSelected(i);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleSelection#addAccessibleSelection(int)
+ */
+ public void addAccessibleSelection(int i)
+ {
+ select(i);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleSelection#removeAccessibleSelection(int)
+ */
+ public void removeAccessibleSelection(int i)
+ {
+ deselect(i);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleSelection#clearAccessibleSelection()
+ */
+ public void clearAccessibleSelection()
+ {
+ for (int i = 0; i < getItemCount(); i++)
+ deselect(i);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleSelection#selectAllAccessibleSelection()
+ */
+ public void selectAllAccessibleSelection()
+ {
+ if (isMultipleMode())
+ for (int i = 0; i < getItemCount(); i++)
+ select(i);
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
+ */
+ public void itemStateChanged(ItemEvent event)
+ {
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ }
+
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>List</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTList();
+ return accessibleContext;
+ }
+} // class List
diff --git a/libjava/classpath/java/awt/MediaTracker.java b/libjava/classpath/java/awt/MediaTracker.java
new file mode 100644
index 0000000..9abfde6
--- /dev/null
+++ b/libjava/classpath/java/awt/MediaTracker.java
@@ -0,0 +1,697 @@
+/* MediaTracker.java -- Class used for keeping track of images
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.ImageObserver;
+import java.util.ArrayList;
+
+/**
+ * This class is used for keeping track of the status of various media
+ * objects.
+ *
+ * Media objects are tracked by assigning them an ID. It is possible
+ * to assign the same ID to mutliple objects, effectivly grouping them
+ * together. In this case the status flags ({@link #statusID}) and error flag
+ * (@link #isErrorID} and {@link #getErrorsID}) are ORed together. This
+ * means that you cannot say exactly which media object has which status,
+ * at most you can say that there <em>are</em> certain media objects with
+ * some certain status.
+ *
+ * At the moment only images are supported by this class.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Bryce McKinlay
+ */
+public class MediaTracker implements java.io.Serializable
+{
+ /** Indicates that the media is still loading. */
+ public static final int LOADING = 1 << 0;
+
+ /** Indicates that the loading operation has been aborted. */
+ public static final int ABORTED = 1 << 1;
+
+ /** Indicates that an error has occured during loading of the media. */
+ public static final int ERRORED = 1 << 2;
+
+ /** Indicates that the media has been successfully and completely loaded. */
+ public static final int COMPLETE = 1 << 3;
+
+ /** The component on which the media is eventually been drawn. */
+ Component target;
+
+ /** The head of the linked list of tracked media objects. */
+ MediaEntry head;
+
+ /** Our serialVersionUID for serialization. */
+ static final long serialVersionUID = -483174189758638095L;
+
+ /**
+ * This represents a media object that is tracked by a MediaTracker.
+ * It also implements a simple linked list.
+ */
+ // FIXME: The serialized form documentation says MediaEntry is a
+ // serializable field, but the serialized form of MediaEntry itself
+ // doesn't appear to be documented.
+ class MediaEntry implements ImageObserver
+ {
+ /** The ID of the media object. */
+ int id;
+
+ /** The media object. (only images are supported ATM). */
+ Image image;
+
+ /** The link to the next entry in the list. */
+ MediaEntry next;
+
+ /** The tracking status. */
+ int status;
+
+ /** The width of the image. */
+ int width;
+
+ /** The height of the image. */
+ int height;
+
+ /**
+ * Receives notification from an {@link java.awt.image.ImageProducer}
+ * that more data of the image is available.
+ *
+ * @param img the image that is updated
+ * @param flags flags from the ImageProducer that indicate the status
+ * of the loading process
+ * @param x the X coordinate of the upper left corner of the image
+ * @param y the Y coordinate of the upper left corner of the image
+ * @param width the width of the image
+ * @param height the height of the image
+ *
+ * @return <code>true</code> if more data is needed, <code>false</code>
+ * otherwise
+ *
+ * @see java.awt.image.ImageObserver
+ */
+ public boolean imageUpdate(Image img, int flags, int x, int y,
+ int width, int height)
+ {
+ if ((flags & ABORT) != 0)
+ status = ABORTED;
+ else if ((flags & ERROR) != 0)
+ status = ERRORED;
+ else if ((flags & ALLBITS) != 0)
+ status = COMPLETE;
+ else
+ status = 0;
+
+ synchronized (MediaTracker.this)
+ {
+ MediaTracker.this.notifyAll();
+ }
+
+ // If status is not COMPLETE then we need more updates.
+ return ((status & (COMPLETE | ERRORED | ABORTED)) == 0);
+ }
+ }
+
+ /**
+ * Constructs a new MediaTracker for the component <code>c</code>. The
+ * component should be the component that uses the media (i.e. draws it).
+ *
+ * @param c the Component that wants to use the media
+ */
+ public MediaTracker(Component c)
+ {
+ target = c;
+ }
+
+ /**
+ * Adds an image to the tracker with the specified <code>ID</code>.
+ *
+ * @param image the image to be added
+ * @param id the ID of the tracker list to which the image is added
+ */
+ public void addImage(Image image, int id)
+ {
+ MediaEntry e = new MediaEntry();
+ e.id = id;
+ e.image = image;
+ synchronized(this)
+ {
+ e.next = head;
+ head = e;
+ }
+ }
+
+ /**
+ * Adds an image to the tracker with the specified <code>ID</code>.
+ * The image is expected to be rendered with the specified width and
+ * height.
+ *
+ * @param image the image to be added
+ * @param id the ID of the tracker list to which the image is added
+ * @param width the width of the image
+ * @param height the height of the image
+ */
+ public void addImage(Image image, int id, int width, int height)
+ {
+ MediaEntry e = new MediaEntry();
+ e.id = id;
+ e.image = image;
+ e.width = width;
+ e.height = height;
+ synchronized(this)
+ {
+ e.next = head;
+ head = e;
+ }
+ }
+
+ /**
+ * Checks if all media objects have finished loading, i.e. are
+ * {@link #COMPLETE}, {@link #ABORTED} or {@link #ERRORED}.
+ *
+ * If the media objects are not already loading, a call to this
+ * method does <em>not</em> start loading. This is equivalent to
+ * a call to <code>checkAll(false)</code>.
+ *
+ * @return if all media objects have finished loading either by beeing
+ * complete, have been aborted or errored.
+ */
+ public boolean checkAll()
+ {
+ return checkAll(false);
+ }
+
+ /**
+ * Checks if all media objects have finished loading, i.e. are
+ * {@link #COMPLETE}, {@link #ABORTED} or {@link #ERRORED}.
+ *
+ * If the media objects are not already loading, and <code>load</code>
+ * is <code>true</code> then a call to this
+ * method starts loading the media objects.
+ *
+ * @param load if <code>true</code> this method starts loading objects
+ * that are not already loading
+ *
+ * @return if all media objects have finished loading either by beeing
+ * complete, have been aborted or errored.
+ */
+ public boolean checkAll(boolean load)
+ {
+ MediaEntry e = head;
+ boolean result = true;
+
+ while (e != null)
+ {
+ if ((e.status & (COMPLETE | ERRORED | ABORTED)) == 0)
+ {
+ if (load && ((e.status & LOADING) == 0))
+ {
+ if (target.prepareImage(e.image, e))
+ e.status = COMPLETE;
+ else
+ {
+ e.status = LOADING;
+ int flags = target.checkImage(e.image, e);
+ if ((flags & ImageObserver.ABORT) != 0)
+ e.status = ABORTED;
+ else if ((flags & ImageObserver.ERROR) != 0)
+ e.status = ERRORED;
+ else if ((flags & ImageObserver.ALLBITS) != 0)
+ e.status = COMPLETE;
+ }
+ boolean complete = (e.status
+ & (COMPLETE | ABORTED | ERRORED)) != 0;
+ if (!complete)
+ result = false;
+ }
+ else
+ result = false;
+ }
+ e = e.next;
+ }
+ return result;
+ }
+
+ /**
+ * Checks if any of the registered media objects has encountered an error
+ * during loading.
+ *
+ * @return <code>true</code> if at least one media object has encountered
+ * an error during loading, <code>false</code> otherwise
+ *
+ */
+ public boolean isErrorAny()
+ {
+ MediaEntry e = head;
+ while (e != null)
+ {
+ if ((e.status & ERRORED) != 0)
+ return true;
+ e = e.next;
+ }
+ return false;
+ }
+
+ /**
+ * Returns all media objects that have encountered errors during loading.
+ *
+ * @return an array of all media objects that have encountered errors
+ * or <code>null</code> if there were no errors at all
+ */
+ public Object[] getErrorsAny()
+ {
+ MediaEntry e = head;
+ ArrayList result = null;
+ while (e != null)
+ {
+ if ((e.status & ERRORED) != 0)
+ {
+ if (result == null)
+ result = new ArrayList();
+ result.add(e.image);
+ }
+ e = e.next;
+ }
+ if (result == null)
+ return null;
+ else
+ return result.toArray();
+ }
+
+ /**
+ * Waits for all media objects to finish loading, either by completing
+ * successfully or by aborting or encountering an error.
+ *
+ * @throws InterruptedException if another thread interrupted the
+ * current thread while waiting
+ */
+ public void waitForAll() throws InterruptedException
+ {
+ synchronized (this)
+ {
+ while (checkAll(true) == false)
+ wait();
+ }
+ }
+
+ /**
+ * Waits for all media objects to finish loading, either by completing
+ * successfully or by aborting or encountering an error.
+ *
+ * This method waits at most <code>ms</code> milliseconds. If the
+ * media objects have not completed loading within this timeframe, this
+ * method returns <code>false</code>, otherwise <code>true</code>.
+ *
+ * @param ms timeframe in milliseconds to wait for the media objects to
+ * finish
+ *
+ * @return <code>true</code> if all media objects have successfully loaded
+ * within the timeframe, <code>false</code> otherwise
+ *
+ * @throws InterruptedException if another thread interrupted the
+ * current thread while waiting
+ */
+ public boolean waitForAll(long ms) throws InterruptedException
+ {
+ long start = System.currentTimeMillis();
+ boolean result = checkAll(true);
+ synchronized (this)
+ {
+ while (result == false)
+ {
+ wait(ms);
+ result = checkAll(true);
+ if ((System.currentTimeMillis() - start) > ms)
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the status flags of all registered media objects ORed together.
+ * If <code>load</code> is <code>true</code> then media objects that
+ * are not already loading will be started to load.
+ *
+ * @param load if set to <code>true</code> then media objects that are
+ * not already loading are started
+ *
+ * @return the status flags of all tracked media objects ORed together
+ */
+ public int statusAll(boolean load)
+ {
+ int result = 0;
+ MediaEntry e = head;
+ while (e != null)
+ {
+ if (load && e.status == 0)
+ {
+ if (target.prepareImage(e.image, e))
+ e.status = COMPLETE;
+ else
+ {
+ e.status = LOADING;
+ int flags = target.checkImage(e.image, e);
+ if ((flags & ImageObserver.ABORT) != 0)
+ e.status = ABORTED;
+ else if ((flags & ImageObserver.ERROR) != 0)
+ e.status = ERRORED;
+ else if ((flags & ImageObserver.ALLBITS) != 0)
+ e.status = COMPLETE;
+ }
+ }
+ result |= e.status;
+ e = e.next;
+ }
+ return result;
+ }
+
+ /**
+ * Checks if the media objects with <code>ID</code> have completed loading.
+ *
+ * @param id the ID of the media objects to check
+ *
+ * @return <code>true</code> if all media objects with <code>ID</code>
+ * have successfully finished
+ */
+ public boolean checkID(int id)
+ {
+ return checkID(id, false);
+ }
+
+ /**
+ * Checks if the media objects with <code>ID</code> have completed loading.
+ * If <code>load</code> is <code>true</code> then media objects that
+ * are not already loading will be started to load.
+ *
+ * @param id the ID of the media objects to check
+ * @param load if set to <code>true</code> then media objects that are
+ * not already loading are started
+ *
+ * @return <code>true</code> if all media objects with <code>ID</code>
+ * have successfully finished
+ */
+ public boolean checkID(int id, boolean load)
+ {
+ MediaEntry e = head;
+ boolean result = true;
+
+ while (e != null)
+ {
+ if (e.id == id && ((e.status & (COMPLETE | ABORTED | ERRORED)) == 0))
+ {
+ if (load && ((e.status & LOADING) == 0))
+ {
+ e.status = LOADING;
+ if (target.prepareImage(e.image, e))
+ e.status = COMPLETE;
+ else
+ {
+ int flags = target.checkImage(e.image, e);
+ if ((flags & ImageObserver.ABORT) != 0)
+ e.status = ABORTED;
+ else if ((flags & ImageObserver.ERROR) != 0)
+ e.status = ERRORED;
+ else if ((flags & ImageObserver.ALLBITS) != 0)
+ e.status = COMPLETE;
+ }
+ boolean complete = (e.status
+ & (COMPLETE | ABORTED | ERRORED)) != 0;
+ if (!complete)
+ result = false;
+ }
+ else
+ result = false;
+ }
+ e = e.next;
+ }
+ return result;
+ }
+
+ /**
+ * Returns <code>true</code> if any of the media objects with <code>ID</code>
+ * have encountered errors during loading, false otherwise.
+ *
+ * @param id the ID of the media objects to check
+ *
+ * @return <code>true</code> if any of the media objects with <code>ID</code>
+ * have encountered errors during loading, false otherwise
+ */
+ public boolean isErrorID(int id)
+ {
+ MediaEntry e = head;
+ while (e != null)
+ {
+ if (e.id == id && ((e.status & ERRORED) != 0))
+ return true;
+ e = e.next;
+ }
+ return false;
+ }
+
+ /**
+ * Returns all media objects with the specified ID that have encountered
+ * an error.
+ *
+ * @param id the ID of the media objects to check
+ *
+ * @return an array of all media objects with the specified ID that
+ * have encountered an error
+ */
+ public Object[] getErrorsID(int id)
+ {
+ MediaEntry e = head;
+ ArrayList result = null;
+ while (e != null)
+ {
+ if (e.id == id && ((e.status & ERRORED) != 0))
+ {
+ if (result == null)
+ result = new ArrayList();
+ result.add(e.image);
+ }
+ e = e.next;
+ }
+ if (result == null)
+ return null;
+ else
+ return result.toArray();
+ }
+
+ /**
+ * Waits for all media objects with the specified ID to finish loading,
+ * either by completing successfully or by aborting or encountering an error.
+ *
+ * @param id the ID of the media objects to wait for
+ *
+ * @throws InterruptedException if another thread interrupted the
+ * current thread while waiting
+ */
+ public void waitForID(int id) throws InterruptedException
+ {
+ MediaEntry e = head;
+ synchronized (this)
+ {
+ while (checkID (id, true) == false)
+ wait();
+ }
+ }
+
+ /**
+ * Waits for all media objects with the specified ID to finish loading,
+ * either by completing successfully or by aborting or encountering an error.
+ *
+ * This method waits at most <code>ms</code> milliseconds. If the
+ * media objects have not completed loading within this timeframe, this
+ * method returns <code>false</code>, otherwise <code>true</code>.
+ *
+ * @param id the ID of the media objects to wait for
+ * @param ms timeframe in milliseconds to wait for the media objects to
+ * finish
+ *
+ * @return <code>true</code> if all media objects have successfully loaded
+ * within the timeframe, <code>false</code> otherwise
+ *
+ * @throws InterruptedException if another thread interrupted the
+ * current thread while waiting
+ */
+ public boolean waitForID(int id, long ms) throws InterruptedException
+ {
+ MediaEntry e = head;
+ long start = System.currentTimeMillis();
+ boolean result = checkID(id, true);
+
+ synchronized (this)
+ {
+ while (result == false)
+ {
+ wait(ms);
+ result = checkID(id, true);
+ if ((System.currentTimeMillis() - start) > ms)
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the status flags of the media objects with the specified ID
+ * ORed together.
+ *
+ * If <code>load</code> is <code>true</code> then media objects that
+ * are not already loading will be started to load.
+ *
+ * @param load if set to <code>true</code> then media objects that are
+ * not already loading are started
+ *
+ * @return the status flags of all tracked media objects ORed together
+ */
+ public int statusID(int id, boolean load)
+ {
+ int result = 0;
+ MediaEntry e = head;
+ while (e != null)
+ {
+ if (e.id == id)
+ {
+ if (load && e.status == 0)
+ {
+ if (target.prepareImage(e.image, e))
+ e.status = COMPLETE;
+ else
+ {
+ e.status = LOADING;
+ int flags = target.checkImage(e.image, e);
+ if ((flags & ImageObserver.ABORT) != 0)
+ e.status = ABORTED;
+ else if ((flags & ImageObserver.ERROR) != 0)
+ e.status = ERRORED;
+ else if ((flags & ImageObserver.ALLBITS) != 0)
+ e.status = COMPLETE;
+ }
+ }
+ result |= e.status;
+ }
+ e = e.next;
+ }
+ return result;
+ }
+
+ /**
+ * Removes an image from this MediaTracker.
+ *
+ * @param image the image to be removed
+ */
+ public void removeImage(Image image)
+ {
+ synchronized (this)
+ {
+ MediaEntry e = head;
+ MediaEntry prev = null;
+ while (e != null)
+ {
+ if (e.image == image)
+ {
+ if (prev == null)
+ head = e.next;
+ else
+ prev.next = e.next;
+ }
+ prev = e;
+ e = e.next;
+ }
+ }
+ }
+
+ /**
+ * Removes an image with the specified ID from this MediaTracker.
+ *
+ * @param image the image to be removed
+ */
+ public void removeImage(Image image, int id)
+ {
+ synchronized (this)
+ {
+ MediaEntry e = head;
+ MediaEntry prev = null;
+ while (e != null)
+ {
+ if (e.id == id && e.image == image)
+ {
+ if (prev == null)
+ head = e.next;
+ else
+ prev.next = e.next;
+ }
+ else
+ prev = e;
+ e = e.next;
+ }
+ }
+ }
+
+ /**
+ * Removes an image with the specified ID and scale from this MediaTracker.
+ *
+ * @param image the image to be removed
+ */
+ public void removeImage(Image image, int id, int width, int height)
+ {
+ synchronized (this)
+ {
+ MediaEntry e = head;
+ MediaEntry prev = null;
+ while (e != null)
+ {
+ if (e.id == id && e.image == image
+ && e.width == width && e.height == height)
+ {
+ if (prev == null)
+ head = e.next;
+ else
+ prev.next = e.next;
+ }
+ else
+ prev = e;
+ e = e.next;
+ }
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/Menu.java b/libjava/classpath/java/awt/Menu.java
new file mode 100644
index 0000000..56ceccf
--- /dev/null
+++ b/libjava/classpath/java/awt/Menu.java
@@ -0,0 +1,468 @@
+/* Menu.java -- A Java AWT Menu
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.peer.MenuPeer;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * This class represents a pull down or tear off menu in Java's AWT.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class Menu extends MenuItem implements MenuContainer, Serializable
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization Constant
+private static final long serialVersionUID = -8809584163345499784L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The actual items in the menu
+ */
+private Vector items = new Vector();
+
+/**
+ * @serial Flag indicating whether or not this menu is a tear off
+ */
+private boolean tearOff;
+
+/**
+ * @serial Indicates whether or not this is a help menu.
+ */
+private boolean isHelpMenu;
+
+ /*
+ * @serial Unused in this implementation, but present in Sun's
+ * serialization spec. Value obtained via reflection.
+ */
+ private int menuSerializedDataVersion = 1;
+
+static final transient String separatorLabel = "-";
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>Menu</code> with no label and that
+ * is not a tearoff;
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+Menu()
+{
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Menu</code> that is not a tearoff and
+ * that has the specified label.
+ *
+ * @param label The menu label.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+Menu(String label)
+{
+ this(label, false);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>Menu</code> with the specified
+ * label and tearoff status.
+ *
+ * @param label The label for this menu
+ * @param isTearOff <code>true</code> if this menu is a tear off menu,
+ * <code>false</code> otherwise.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+Menu(String label, boolean isTearOff)
+{
+ super(label);
+
+ tearOff = isTearOff;
+
+ if (label.equals("Help"))
+ isHelpMenu = true;
+
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Tests whether or not this menu is a tearoff.
+ *
+ * @return <code>true</code> if this menu is a tearoff, <code>false</code>
+ * otherwise.
+ */
+public boolean
+isTearOff()
+{
+ return(tearOff);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the number of items in this menu.
+ *
+ * @return The number of items in this menu.
+ */
+public int
+getItemCount()
+{
+ return countItems ();
+}
+
+/**
+ * Returns the number of items in this menu.
+ *
+ * @return The number of items in this menu.
+ *
+ * @deprecated As of JDK 1.1, replaced by getItemCount().
+ */
+public int countItems ()
+{
+ return items.size ();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the item at the specified index.
+ *
+ * @return The item at the specified index.
+ *
+ * @exception ArrayIndexOutOfBoundsException If the index value is not valid.
+ */
+public MenuItem
+getItem(int index)
+{
+ return((MenuItem)items.elementAt(index));
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified item to this menu. If it was previously part of
+ * another menu, it is first removed from that menu.
+ *
+ * @param item The new item to add.
+ *
+ * @return The item that was added.
+ */
+public MenuItem
+add(MenuItem item)
+{
+ items.addElement(item);
+ if (item.parent != null)
+ {
+ item.parent.remove(item);
+ }
+ item.parent = this;
+
+ if (peer != null)
+ {
+ MenuPeer mp = (MenuPeer) peer;
+ mp.addItem(item);
+ }
+
+ return item;
+}
+
+/*************************************************************************/
+
+/**
+ * Add an item with the specified label to this menu.
+ *
+ * @param label The label of the menu item to add.
+ */
+public void
+add(String label)
+{
+ add(new MenuItem(label));
+}
+
+/*************************************************************************/
+
+/**
+ * Inserts the specified menu item into this menu at the specified index.
+ *
+ * @param item The menu item to add.
+ * @param index The index of the menu item.
+ *
+ * @exception IllegalArgumentException If the index is less than zero.
+ * @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid.
+ */
+public void
+insert(MenuItem item, int index)
+{
+ if (index < 0)
+ throw new IllegalArgumentException("Index is less than zero");
+
+ MenuPeer peer = (MenuPeer) getPeer();
+ if (peer == null)
+ return;
+
+ int count = getItemCount ();
+
+ if (index >= count)
+ peer.addItem (item);
+ else
+ {
+ for (int i = count - 1; i >= index; i--)
+ peer.delItem (i);
+
+ peer.addItem (item);
+
+ for (int i = index; i < count; i++)
+ peer.addItem ((MenuItem) items.elementAt (i));
+ }
+
+ items.insertElementAt(item, index);
+}
+
+/*************************************************************************/
+
+/**
+ * Inserts an item with the specified label into this menu at the specified index.
+ *
+ * @param label The label of the item to add.
+ * @param index The index of the menu item.
+ *
+ * @exception IllegalArgumentException If the index is less than zero.
+ * @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid.
+ */
+public void
+insert(String label, int index)
+{
+ insert(new MenuItem(label), index);
+}
+
+/*************************************************************************/
+
+/**
+ * Adds a separator bar at the current menu location.
+ */
+public void
+addSeparator()
+{
+ add(new MenuItem(separatorLabel));
+}
+
+/*************************************************************************/
+
+/**
+ * Inserts a separator bar at the specified index value.
+ *
+ * @param index The index at which to insert a separator bar.
+ *
+ * @exception IllegalArgumentException If the index is less than zero.
+ * @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid.
+ */
+public void
+insertSeparator(int index)
+{
+ insert(new MenuItem(separatorLabel), index);
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes the item at the specified index from this menu.
+ *
+ * @param index The index of the item to remove.
+ *
+ * @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid.
+ */
+public synchronized void
+remove(int index)
+{
+ items.removeElementAt(index);
+
+ MenuPeer mp = (MenuPeer)getPeer();
+ if (mp != null)
+ mp.delItem(index);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specifed item from the menu. If the specified component
+ * does not exist, this method does nothing.
+ *
+ * @param item The component to remove.
+ */
+public void
+remove(MenuComponent item)
+{
+ int index = items.indexOf(item);
+ if (index == -1)
+ return;
+
+ remove(index);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes all the elements from this menu.
+ */
+public synchronized void
+removeAll()
+{
+ int count = getItemCount();
+ for(int i = 0; i < count; i++)
+ {
+ // We must always remove item 0.
+ remove(0);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Creates the native peer for this object.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit().createMenu(this);
+ Enumeration e = items.elements();
+ while (e.hasMoreElements())
+ {
+ MenuItem mi = (MenuItem)e.nextElement();
+ mi.addNotify();
+ }
+ super.addNotify ();
+}
+
+/*************************************************************************/
+
+/**
+ * Destroys the native peer for this object.
+ */
+public void
+removeNotify()
+{
+ Enumeration e = items.elements();
+ while (e.hasMoreElements())
+ {
+ MenuItem mi = (MenuItem) e.nextElement();
+ mi.removeNotify();
+ }
+ super.removeNotify();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this menu.
+ *
+ * @return A debugging string for this menu.
+ */
+public String
+paramString()
+{
+ return (",tearOff=" + tearOff + ",isHelpMenu=" + isHelpMenu
+ + super.paramString());
+}
+
+ /**
+ * Basic Accessibility class for Menu. Details get provided in derived
+ * classes.
+ */
+ protected class AccessibleAWTMenu extends AccessibleAWTMenuItem
+ {
+ protected AccessibleAWTMenu()
+ {
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.MENU;
+ }
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>Menu</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTMenu();
+ return accessibleContext;
+ }
+
+} // class Menu
diff --git a/libjava/classpath/java/awt/MenuBar.java b/libjava/classpath/java/awt/MenuBar.java
new file mode 100644
index 0000000..4089fe1
--- /dev/null
+++ b/libjava/classpath/java/awt/MenuBar.java
@@ -0,0 +1,423 @@
+/* MenuBar.java -- An AWT menu bar class
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.peer.MenuBarPeer;
+import java.awt.peer.MenuComponentPeer;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * This class implements a menu bar in the AWT system.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+public class MenuBar extends MenuComponent
+ implements MenuContainer, Serializable, Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization Constant
+private static final long serialVersionUID = -4930327919388951260L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The menu used for providing help information
+ */
+private Menu helpMenu;
+
+/**
+ * @serial The menus contained in this menu bar.
+ */
+private Vector menus = new Vector();
+
+ /**
+ * The accessible context for this component.
+ *
+ * @see #getAccessibleContext()
+ * @serial ignored.
+ */
+ private transient AccessibleContext accessibleContext;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>MenuBar</code>.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+MenuBar()
+{
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the help menu for this menu bar. This may be <code>null</code>.
+ *
+ * @return The help menu for this menu bar.
+ */
+public Menu
+getHelpMenu()
+{
+ return(helpMenu);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the help menu for this menu bar.
+ *
+ * @param menu The new help menu for this menu bar.
+ */
+public synchronized void
+setHelpMenu(Menu menu)
+{
+ if (helpMenu != null)
+ {
+ helpMenu.removeNotify ();
+ helpMenu.parent = null;
+ }
+ helpMenu = menu;
+
+ if (menu.parent != null)
+ menu.parent.remove (menu);
+ menu.parent = this;
+
+ MenuBarPeer peer = (MenuBarPeer) getPeer ();
+ if (peer != null)
+ {
+ menu.addNotify();
+ peer.addHelpMenu (menu);
+ }
+}
+
+/*************************************************************************/
+
+/** Add a menu to this MenuBar. If the menu has already has a
+ * parent, it is first removed from its old parent before being
+ * added.
+ *
+ * @param menu The menu to add.
+ *
+ * @return The menu that was added.
+ */
+public synchronized Menu
+add(Menu menu)
+{
+ if (menu.parent != null)
+ menu.parent.remove (menu);
+
+ menu.parent = this;
+ menus.addElement(menu);
+
+ if (peer != null)
+ {
+ menu.addNotify();
+ }
+
+ return(menu);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the menu at the specified index.
+ *
+ * @param index The index of the menu to remove from the menu bar.
+ */
+public synchronized void
+remove(int index)
+{
+ Menu m = (Menu) menus.get (index);
+ menus.remove (index);
+ m.removeNotify ();
+ m.parent = null;
+
+ if (peer != null)
+ {
+ MenuBarPeer mp = (MenuBarPeer) peer;
+ mp.delMenu (index);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified menu from the menu bar.
+ *
+ * @param menu The menu to remove from the menu bar.
+ */
+public void
+remove(MenuComponent menu)
+{
+ int index = menus.indexOf(menu);
+ if (index == -1)
+ return;
+
+ remove(index);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the number of elements in this menu bar.
+ *
+ * @return The number of elements in the menu bar.
+ */
+public int
+getMenuCount()
+{
+ return countMenus ();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the number of elements in this menu bar.
+ *
+ * @return The number of elements in the menu bar.
+ *
+ * @deprecated This method is deprecated in favor of <code>getMenuCount()</code>.
+ */
+public int
+countMenus()
+{
+ return menus.size () + (getHelpMenu () == null ? 0 : 1);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the menu at the specified index.
+ *
+ * @param index the index of the menu
+ *
+ * @return The requested menu.
+ *
+ * @exception ArrayIndexOutOfBoundsException If the index is not valid.
+ */
+public Menu
+getMenu(int index)
+{
+ return((Menu)menus.elementAt(index));
+}
+
+/*************************************************************************/
+
+/**
+ * Creates this object's native peer.
+ */
+public void
+addNotify()
+{
+ if (getPeer() == null)
+ setPeer((MenuComponentPeer)getToolkit().createMenuBar(this));
+ Enumeration e = menus.elements();
+ while (e.hasMoreElements())
+ {
+ Menu mi = (Menu)e.nextElement();
+ mi.addNotify();
+ }
+ if (helpMenu != null)
+ {
+ helpMenu.addNotify();
+ ((MenuBarPeer) peer).addHelpMenu(helpMenu);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Destroys this object's native peer.
+ */
+public void
+removeNotify()
+{
+ Enumeration e = menus.elements();
+ while (e.hasMoreElements())
+ {
+ Menu mi = (Menu) e.nextElement();
+ mi.removeNotify();
+ }
+ super.removeNotify();
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a list of all shortcuts for the menus in this menu bar.
+ *
+ * @return A list of all shortcuts for the menus in this menu bar.
+ */
+public synchronized Enumeration
+shortcuts()
+{
+ Vector shortcuts = new Vector();
+ Enumeration e = menus.elements();
+
+ while (e.hasMoreElements())
+ {
+ Menu menu = (Menu)e.nextElement();
+ if (menu.getShortcut() != null)
+ shortcuts.addElement(menu.getShortcut());
+ }
+
+ return(shortcuts.elements());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the menu item for the specified shortcut, or <code>null</code>
+ * if no such item exists.
+ *
+ * @param shortcut The shortcut to return the menu item for.
+ *
+ * @return The menu item for the specified shortcut.
+ */
+public MenuItem
+getShortcutMenuItem(MenuShortcut shortcut)
+{
+ Enumeration e = menus.elements();
+
+ while (e.hasMoreElements())
+ {
+ Menu menu = (Menu)e.nextElement();
+ MenuShortcut s = menu.getShortcut();
+ if ((s != null) && (s.equals(shortcut)))
+ return(menu);
+ }
+
+ return(null);
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes the specified menu shortcut.
+ *
+ * @param shortcut The shortcut to delete.
+ */
+public void
+deleteShortcut(MenuShortcut shortcut)
+{
+ MenuItem it;
+ // This is a slow implementation, but it probably doesn't matter.
+ while ((it = getShortcutMenuItem (shortcut)) != null)
+ it.deleteShortcut ();
+}
+
+/**
+ * Gets the AccessibleContext associated with this <code>MenuBar</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+public AccessibleContext getAccessibleContext()
+{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTMenuBar();
+ return accessibleContext;
+}
+
+/**
+ * This class provides accessibility support for AWT menu bars.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+protected class AccessibleAWTMenuBar
+ extends AccessibleAWTMenuComponent
+{
+
+ /**
+ * Compatible with JDK 1.4.2 revision 5
+ */
+ private static final long serialVersionUID = -8577604491830083815L;
+
+ /**
+ * This is the default constructor, which simply calls the default
+ * constructor of the superclass.
+ */
+ protected AccessibleAWTMenuBar()
+ {
+ super();
+ }
+
+ /**
+ * Returns the accessible role relating to the menu bar.
+ *
+ * @return <code>AccessibleRole.MENU_BAR</code>.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.MENU_BAR;
+ }
+
+} // class AccessibleAWTMenuBar
+
+} // class MenuBar
diff --git a/libjava/classpath/java/awt/MenuComponent.java b/libjava/classpath/java/awt/MenuComponent.java
new file mode 100644
index 0000000..ec6980e1
--- /dev/null
+++ b/libjava/classpath/java/awt/MenuComponent.java
@@ -0,0 +1,1324 @@
+/* MenuComponent.java -- Superclass of all AWT menu components
+ Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.peer.MenuComponentPeer;
+import java.io.Serializable;
+import java.util.Locale;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleStateSet;
+
+/**
+ * This is the superclass of all menu AWT widgets.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+public abstract class MenuComponent implements Serializable
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization Constant
+private static final long serialVersionUID = -4536902356223894379L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * The font for this component.
+ *
+ * @see #getFont()
+ * @see #setFont(java.awt.Font)
+ * @serial the component's font.
+ */
+ private Font font;
+
+ /**
+ * The name of the component.
+ *
+ * @see #getName()
+ * @see #setName(String)
+ * @serial the component's name.
+ */
+ private String name;
+
+ /**
+ * The parent of this component.
+ *
+ * @see #getParent()
+ * @see #setParent(java.awt.MenuContainer)
+ * @serial ignored.
+ */
+ transient MenuContainer parent;
+
+ /**
+ * The native peer for this component.
+ *
+ * @see #getPeer()
+ * @see #setPeer(java.awt.peer.MenuComponentPeer)
+ * @serial ignored.
+ */
+ transient MenuComponentPeer peer;
+
+ /**
+ * The synchronization locking object for this component.
+ *
+ * @serial ignored.
+ */
+ private transient Object tree_lock = this;
+
+ /**
+ * The toolkit for this object.
+ *
+ * @see #getToolkit()
+ * @serial ignored.
+ */
+ private static transient Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+ /**
+ * The accessible context for this component.
+ *
+ * @see #getAccessibleContext()
+ * @serial the accessibility information for this component.
+ */
+ AccessibleContext accessibleContext;
+
+ /**
+ * Was the name of the component set? This value defaults
+ * to false and becomes true after a call to <code>setName()</code>.
+ * Please note that this does not guarantee that name will then
+ * be non-null, as this may be the value passed to <code>setName()</code>.
+ *
+ * @see #setName(String)
+ * @serial true if the name value has been explicitly set by calling
+ * <code>setName()</code>.
+ */
+ private boolean nameExplicitlySet;
+
+ /**
+ * Does this component handle new events? Events will be handled
+ * by this component if this is true. Otherwise, they will be forwarded
+ * up the component hierarchy. This implementation does not use this
+ * variable; it is merely provided for serialization compatability.
+ *
+ * @see #dispatchEvent(AWTEvent)
+ * @serial true if events are to be processed locally. Unused.
+ */
+ private boolean newEventsOnly;
+
+ /**
+ * The focus listener chain handler which deals with focus events for
+ * the accessible context of this component.
+ *
+ * @see AccessibleAWTMenuComponent#addFocusListener(java.awt.event.FocusListener)
+ * @serial ignored.
+ * This is package-private to avoid an accessor method.
+ */
+ transient FocusListener focusListener;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Default constructor for subclasses.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+MenuComponent()
+{
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the font in use for this component.
+ *
+ * @return The font for this component.
+ */
+public Font
+getFont()
+{
+ if (font != null)
+ return font;
+
+ if (parent != null)
+ return parent.getFont ();
+
+ return null;
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the font for this component to the specified font.
+ *
+ * @param font The new font for this component.
+ */
+public void
+setFont(Font font)
+{
+ this.font = font;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the name of this component.
+ *
+ * @return The name of this component.
+ */
+public String
+getName()
+{
+ return(name);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the name of this component to the specified name.
+ *
+ * @param name The new name of this component.
+ */
+public void
+setName(String name)
+{
+ this.name = name;
+ nameExplicitlySet = true;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the parent of this component.
+ *
+ * @return The parent of this component.
+ */
+public MenuContainer
+getParent()
+{
+ return(parent);
+}
+
+/*************************************************************************/
+
+// Sets the parent of this component.
+final void
+setParent(MenuContainer parent)
+{
+ this.parent = parent;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the native windowing system peer for this component.
+ *
+ * @return The peer for this component.
+ *
+ * @deprecated
+ */
+public MenuComponentPeer
+getPeer()
+{
+ return(peer);
+}
+
+/*************************************************************************/
+
+// Sets the peer for this component.
+final void
+setPeer(MenuComponentPeer peer)
+{
+ this.peer = peer;
+}
+
+/*************************************************************************/
+
+/**
+ * Destroys this component's native peer
+ */
+public void
+removeNotify()
+{
+ if (peer != null)
+ peer.dispose();
+ peer = null;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the toolkit in use for this component.
+ *
+ * @return The toolkit for this component.
+ */
+final Toolkit
+getToolkit()
+{
+ return(toolkit);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the object used for synchronization locks on this component
+ * when performing tree and layout functions.
+ *
+ * @return The synchronization lock for this component.
+ */
+protected final Object
+getTreeLock()
+{
+ return(tree_lock);
+}
+
+/*************************************************************************/
+
+// The sync lock object for this component.
+final void
+setTreeLock(Object tree_lock)
+{
+ this.tree_lock = tree_lock;
+}
+
+/*************************************************************************/
+
+/**
+ * AWT 1.0 event dispatcher.
+ *
+ * @deprecated Deprecated in favor of <code>dispatchEvent()</code>.
+ * @return true if the event was dispatched, false otherwise.
+ */
+public boolean
+postEvent(Event event)
+{
+ // This is overridden by subclasses that support events.
+ return false;
+}
+/*************************************************************************/
+
+/**
+ * Sends this event to this component or a subcomponent for processing.
+ *
+ * @param event The event to dispatch
+ */
+public final void dispatchEvent(AWTEvent event)
+{
+ // See comment in Component.dispatchEvent().
+ dispatchEventImpl(event);
+}
+
+
+/**
+ * Implementation of dispatchEvent. Allows trusted package classes
+ * to dispatch additional events first. This implementation first
+ * translates <code>event</code> to an AWT 1.0 event and sends the
+ * result to {@link #postEvent}. The event is then
+ * passed on to {@link #processEvent} for local processing.
+ *
+ * @param event the event to dispatch.
+ */
+void dispatchEventImpl(AWTEvent event)
+{
+ Event oldStyleEvent;
+
+ // This is overridden by subclasses that support events.
+ /* Convert AWT 1.1 event to AWT 1.0 event */
+ oldStyleEvent = Component.translateEvent(event);
+ if (oldStyleEvent != null)
+ {
+ postEvent(oldStyleEvent);
+ }
+ /* Do local processing */
+ processEvent(event);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes the specified event. In this class, this method simply
+ * calls one of the more specific event handlers.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ /*
+ Pass a focus event to the focus listener for
+ the accessibility context.
+ */
+ if (event instanceof FocusEvent)
+ {
+ if (focusListener != null)
+ {
+ switch (event.id)
+ {
+ case FocusEvent.FOCUS_GAINED:
+ focusListener.focusGained((FocusEvent) event);
+ break;
+ case FocusEvent.FOCUS_LOST:
+ focusListener.focusLost((FocusEvent) event);
+ break;
+ }
+ }
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a string representation of this component.
+ *
+ * @return A string representation of this component
+ */
+public String
+toString()
+{
+ return this.getClass().getName() + "[" + paramString() + "]";
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this component
+ */
+protected String
+paramString()
+{
+ return "name=" + getName();
+}
+
+/**
+ * Gets the AccessibleContext associated with this <code>MenuComponent</code>.
+ * As an abstract class, we return null. Concrete subclasses should return
+ * their implementation of the accessibility context.
+ *
+ * @return null.
+ */
+
+public AccessibleContext getAccessibleContext()
+{
+ return null;
+}
+
+/**
+ * This class provides a base for the accessibility support of menu
+ * components.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+protected abstract class AccessibleAWTMenuComponent
+ extends AccessibleContext
+ implements Serializable, AccessibleComponent, AccessibleSelection
+{
+
+ /**
+ * Compatible with JDK 1.4.2 revision 5
+ */
+ private static final long serialVersionUID = -4269533416223798698L;
+
+ /**
+ * This is the default constructor. It should be called by
+ * concrete subclasses to ensure necessary groundwork is completed.
+ */
+ protected AccessibleAWTMenuComponent()
+ {
+ }
+
+ /**
+ * Replaces or supplements the component's selection with the
+ * <code>Accessible</code> child at the supplied index. If
+ * the component supports multiple selection, the child is
+ * added to the current selection. Otherwise, the current
+ * selection becomes the specified child. If the child is
+ * already selected, nothing happens.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the specified child within a
+ * zero-based list of the component's children.
+ */
+ public void addAccessibleSelection(int index)
+ {
+ /* Subclasses with children should implement this */
+ }
+
+ /**
+ * Registers the specified focus listener to receive
+ * focus events from this component.
+ *
+ * @param listener the new focus listener.
+ */
+ public void addFocusListener(FocusListener listener)
+ {
+ /*
+ * Chain the new focus listener to the existing chain
+ * of focus listeners. Each new focus listener is
+ * coupled via multicasting to the existing chain.
+ */
+ focusListener = AWTEventMulticaster.add(focusListener, listener);
+ }
+
+ /**
+ * Clears the component's current selection. Following
+ * the calling of this method, no children of the component
+ * will be selected.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ */
+ public void clearAccessibleSelection()
+ {
+ }
+
+ /**
+ * Returns true if the specified point lies within the
+ * component. The supplied co-ordinates are assumed to
+ * be relative to the co-ordinate system of the component
+ * itself. Thus, the point (0,0) is the upper left corner
+ * of this component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @param point the point to check against this component.
+ * @return true if the point is within this component.
+ * @see #getBounds()
+ */
+ public boolean contains(Point point)
+ {
+ /*
+ We can simply return the result of a
+ test for containment in the bounding rectangle
+ */
+ return getBounds().contains(point);
+ }
+
+ /**
+ * Returns the <code>Accessible</code> child of this component present
+ * at the specified point. The supplied co-ordinates are
+ * assumed to be relative to the co-ordinate system of this
+ * component (the parent of any returned accessible). Thus,
+ * the point (0,0) is the upper left corner of this menu
+ * component.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param point the point at which the returned accessible
+ * is located.
+ * @return null.
+ */
+ public Accessible getAccessibleAt(Point point)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the <code>Accessible</code> child at the supplied
+ * index within the list of children of this component.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the <code>Accessible</code> child
+ * to retrieve.
+ * @return null.
+ */
+ public Accessible getAccessibleChild(int index)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the number of children of this component which
+ * implement the <code>Accessible</code> interface. If
+ * all children of this component are accessible, then
+ * the returned value will be the same as the number of
+ * children.
+ * <br />
+ * <br />
+ *
+ * @return 0.
+ */
+ public int getAccessibleChildrenCount()
+ {
+ return 0;
+ }
+
+ /**
+ * Retrieves the <code>AccessibleComponent</code> associated
+ * with this accessible context and its component. As the
+ * context itself implements <code>AccessibleComponent</code>,
+ * this is the return value.
+ *
+ * @return the context itself.
+ */
+ public AccessibleComponent getAccessibleComponent()
+ {
+ return this;
+ }
+
+ /**
+ * Returns the accessible name for this menu component. This
+ * is the name given to the component, which may be null if
+ * not set using <code>setName()</code>.
+ * <br />
+ * <br />
+ * The name is not the most appropriate description of this
+ * object. Subclasses should preferably provide a more
+ * accurate description. For example, a File menu could
+ * have the description `Lists commands related to the
+ * file system'.
+ *
+ * @return a description of the component. Currently,
+ * this is just the contents of the name property.
+ * @see MenuComponent#setName(String)
+ */
+ public String getAccessibleDescription()
+ {
+ return MenuComponent.this.getName();
+ }
+
+ /**
+ * Retrieves the index of this component within its parent.
+ * If no parent exists, -1 is returned.
+ *
+ * @return -1 as the parent, a <code>MenuContainer</code>
+ * is not <code>Accessible</code>.
+ */
+ public int getAccessibleIndexInParent()
+ {
+ return -1;
+ }
+
+ /**
+ * Returns the accessible name of this component. This
+ * is the name given to the component, which may be null if
+ * not set using <code>setName()</code>.
+ * <br />
+ * <br />
+ * The name property is not the most suitable string to return
+ * for this method. The string should be localized, and
+ * relevant to the operation of the component. For example,
+ * it could be the text of a menu item. However, this can
+ * not be used at this level of abstraction, so it is the
+ * responsibility of subclasses to provide a more appropriate
+ * name.
+ *
+ * @return a localized name for this component. Currently, this
+ * is just the contents of the name property.
+ * @see MenuComponent#setName(String)
+ */
+ public String getAccessibleName()
+ {
+ return MenuComponent.this.getName();
+ }
+
+ /**
+ * Returns the <code>Accessible</code> parent of this component.
+ * As the parent of a <code>MenuComponent</code> is a
+ * <code>MenuContainer</code>, which doesn't implement
+ * <code>Accessible</code>, this method returns null.
+ *
+ * @return null.
+ */
+ public Accessible getAccessibleParent()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the accessible role of this component.
+ * <br />
+ * <br />
+ * The abstract implementation of this method returns
+ * <code>AccessibleRole.AWT_COMPONENT</code>,
+ * as the abstract component has no specific role. This
+ * method should be overridden by concrete subclasses, so
+ * as to return an appropriate role for the component.
+ *
+ * @return <code>AccessibleRole.AWT_COMPONENT</code>.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.AWT_COMPONENT;
+ }
+
+ /**
+ * Retrieves the <code>AccessibleSelection</code> associated
+ * with this accessible context and its component. As the
+ * context itself implements <code>AccessibleSelection</code>,
+ * this is the return value.
+ *
+ * @return the context itself.
+ */
+ public AccessibleSelection getAccessibleSelection()
+ {
+ return this;
+ }
+
+ /**
+ * Retrieves the <code>Accessible</code> selected child
+ * at the specified index. If there are no selected children
+ * or the index is outside the range of selected children,
+ * null is returned. Please note that the index refers
+ * to the index of the child in the list of <strong>selected
+ * children</strong>, and not the index of the child in
+ * the list of all <code>Accessible</code> children.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the selected <code>Accessible</code>
+ * child.
+ */
+ public Accessible getAccessibleSelection(int index)
+ {
+ return null;
+ }
+
+ /**
+ * Returns a count of the number of <code>Accessible</code>
+ * children of this component which are currently selected.
+ * If there are no children currently selected, 0 is returned.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @return 0.
+ */
+ public int getAccessibleSelectionCount()
+ {
+ return 0;
+ }
+
+ /**
+ * Retrieves the current state of this component
+ * in an accessible form. For example, a given component
+ * may be visible, selected, disabled, etc.
+ * <br />
+ * <br />
+ * As this class tells us virtually nothing about the component,
+ * except for its name and font, no state information can be
+ * provided. This implementation thus returns an empty
+ * state set, and it is left to concrete subclasses to provide
+ * a more acceptable and relevant state set. Changes to these
+ * properties also need to be handled using
+ * <code>PropertyChangeListener</code>s.
+ *
+ * @return an empty <code>AccessibleStateSet</code>.
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ return new AccessibleStateSet();
+ }
+
+ /**
+ * Returns the background color of the component, or null
+ * if this property is unsupported.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns the
+ * default system background color used for rendering menus.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @return the default system background color for menus.
+ * @see #setBackground(java.awt.Color)
+ */
+ public Color getBackground()
+ {
+ return SystemColor.menu;
+ }
+
+ /**
+ * Returns a <code>Rectangle</code> which represents the
+ * bounds of this component. The returned rectangle has the
+ * height and width of the component's bounds, and is positioned
+ * at a location relative to this component's parent, the
+ * <code>MenuContainer</code>. null is returned if bounds
+ * are not supported by the component.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns null.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @return null.
+ * @see #setBounds(java.awt.Rectangle)
+ */
+ public Rectangle getBounds()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the <code>Cursor</code> displayed when the pointer
+ * is positioned over this component. Alternatively, null
+ * is returned if the component doesn't support the cursor
+ * property.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns the default
+ * system cursor. Concrete subclasses which handle the drawing
+ * of an onscreen menu component may override this method and provide
+ * the appropriate information.
+ *
+ * @return the default system cursor.
+ * @see #setCursor(java.awt.Cursor)
+ */
+ public Cursor getCursor()
+ {
+ return Cursor.getDefaultCursor();
+ }
+
+ /**
+ * Returns the <code>Font</code> used for text created by this component.
+ *
+ * @return the current font.
+ * @see #setFont(java.awt.Font)
+ */
+ public Font getFont()
+ {
+ return MenuComponent.this.getFont();
+ }
+
+ /**
+ * Retrieves information on the rendering and metrics of the supplied
+ * font. If font metrics are not supported by this component, null
+ * is returned.
+ * <br />
+ * <br />
+ * The abstract implementation of this method simply uses the toolkit
+ * to obtain the <code>FontMetrics</code>. Concrete subclasses may
+ * find it more efficient to invoke their peer class directly, if one
+ * is available.
+ *
+ * @param font the font about which to retrieve rendering and metric
+ * information.
+ * @return the metrics of the given font, as provided by the system
+ * toolkit.
+ * @throws NullPointerException if the supplied font was null.
+ */
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return MenuComponent.this.getToolkit().getFontMetrics(font);
+ }
+
+ /**
+ * Returns the foreground color of the component, or null
+ * if this property is unsupported.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns the
+ * default system text color used for rendering menus.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @return the default system text color for menus.
+ * @see #setForeground(java.awt.Color)
+ */
+ public Color getForeground()
+ {
+ return SystemColor.menuText;
+ }
+
+ /**
+ * Returns the locale currently in use by this component.
+ * <br />
+ * <br />
+ * This abstract class has no property relating to the
+ * locale used by the component, so this method simply
+ * returns the default locale for the current instance
+ * of the Java Virtual Machine (JVM). Concrete subclasses
+ * which maintain such a property should override this method
+ * and provide the locale information more accurately.
+ *
+ * @return the default locale for this JVM instance.
+ */
+ public Locale getLocale()
+ {
+ return Locale.getDefault();
+ }
+
+ /**
+ * Returns the location of the component, with co-ordinates
+ * relative to the parent component and using the co-ordinate
+ * space of the screen. Thus, the point (0,0) is the upper
+ * left corner of the parent component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @return the location of the component, relative to its parent.
+ * @see #setLocation(java.awt.Point)
+ */
+ public Point getLocation()
+ {
+ /* Simply return the location of the bounding rectangle */
+ return getBounds().getLocation();
+ }
+
+ /**
+ * Returns the location of the component, with co-ordinates
+ * relative to the screen. Thus, the point (0,0) is the upper
+ * left corner of the screen. null is returned if the component
+ * is either not on screen or if this property is unsupported.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns null.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @return the location of the component, relative to the screen.
+ */
+ public Point getLocationOnScreen()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the size of the component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @return the size of the component.
+ * @see #setSize(java.awt.Dimension)
+ */
+ public Dimension getSize()
+ {
+ /* Simply return the size of the bounding rectangle */
+ return getBounds().getSize();
+ }
+
+ /**
+ * Returns true if the accessible child specified by the supplied index
+ * is currently selected.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the accessible child to check for selection.
+ * @return false.
+ */
+ public boolean isAccessibleChildSelected(int index)
+ {
+ return false;
+ }
+
+ /**
+ * Returns true if this component is currently enabled.
+ * <br />
+ * <br />
+ * As this abstract component has no properties related to
+ * its enabled or disabled state, the implementation of this
+ * method is left to subclasses.
+ *
+ * @return false.
+ * @see #setEnabled(boolean)
+ */
+ public boolean isEnabled()
+ {
+ return false;
+ }
+
+ /**
+ * Returns true if this component is included in the traversal
+ * of the current focus from one component to the other.
+ * <br />
+ * <br />
+ * As this abstract component has no properties related to
+ * its ability to accept the focus, the implementation of this
+ * method is left to subclasses.
+ *
+ * @return false.
+ */
+ public boolean isFocusTraversable()
+ {
+ return false;
+ }
+
+ /**
+ * Returns true if the component is being shown on screen.
+ * A component is determined to be shown if it is visible,
+ * and each parent component is also visible. Please note
+ * that, even when a component is showing, it may still be
+ * obscured by other components in front. This method only
+ * determines if the component is being drawn on the screen.
+ * <br />
+ * <br />
+ * As this abstract component and its parent have no properties
+ * relating to visibility, the implementation of this method is
+ * left to subclasses.
+ *
+ * @return false.
+ * @see #isVisible()
+ */
+ public boolean isShowing()
+ {
+ return false;
+ }
+
+ /**
+ * Returns true if the component is visible. A component may
+ * be visible but not drawn on the screen if one of its parent
+ * components is not visible. To determine if the component is
+ * actually drawn on screen, <code>isShowing()</code> should be
+ * used.
+ * <br />
+ * <br />
+ * As this abstract component has no properties relating to its
+ * visibility, the implementation of this method is left to subclasses.
+ *
+ * @return false.
+ * @see #isShowing()
+ * @see #setVisible(boolean)
+ */
+ public boolean isVisible()
+ {
+ return false;
+ }
+
+ /**
+ * Removes the accessible child specified by the supplied index from
+ * the list of currently selected children. If the child specified
+ * is not selected, nothing happens.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the <code>Accessible</code> child.
+ */
+ public void removeAccessibleSelection(int index)
+ {
+ /* Subclasses with children should implement this */
+ }
+
+ /**
+ * Removes the specified focus listener from the list of registered
+ * focus listeners for this component.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeFocusListener(FocusListener listener)
+ {
+ /* Remove the focus listener from the chain */
+ focusListener = AWTEventMulticaster.remove(focusListener, listener);
+ }
+
+ /**
+ * Requests that this component gains focus. This depends on the
+ * component being focus traversable.
+ * <br />
+ * <br />
+ * As this abstract component has no properties relating to its
+ * focus traversability, or access to a peer with request focusing
+ * abilities, the implementation of this method is left to subclasses.
+ */
+ public void requestFocus()
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Selects all <code>Accessible</code> children of this component which
+ * it is possible to select. The component needs to support multiple
+ * selections.
+ * <br />
+ * <br />
+ * This abstract component provides a simplistic implementation of this
+ * method, which ignores the ability of the component to support multiple
+ * selections and simply uses <code>addAccessibleSelection</code> to
+ * add each <code>Accessible</code> child to the selection. The last
+ * <code>Accessible</code> component is thus selected for components
+ * which don't support multiple selections. Concrete implementations should
+ * override this with a more appopriate and efficient implementation, which
+ * properly takes into account the ability of the component to support multiple
+ * selections.
+ */
+ public void selectAllAccessibleSelection()
+ {
+ /* Simply call addAccessibleSelection() on all accessible children */
+ for (int a = 0; a < getAccessibleChildrenCount(); ++a)
+ {
+ addAccessibleSelection(a);
+ }
+ }
+
+ /**
+ * Sets the background color of the component to that specified.
+ * Unspecified behaviour occurs when null is given as the new
+ * background color.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply ignores the supplied
+ * color and continues to use the default system color.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @param color the new color to use for the background.
+ * @see getBackground()
+ */
+ public void setBackground(Color color)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the height and width of the component, and its position
+ * relative to this component's parent, to the values specified
+ * by the supplied rectangle. Unspecified behaviour occurs when
+ * null is given as the new bounds.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply ignores the new
+ * rectangle and continues to return null from <code>getBounds()</code>.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @param rectangle a rectangle which specifies the new bounds of
+ * the component.
+ * @see #getBounds()
+ */
+ public void setBounds(Rectangle rectangle)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the <code>Cursor</code> used when the pointer is positioned over the
+ * component. Unspecified behaviour occurs when null is given as the new
+ * cursor.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply ignores the new cursor
+ * and continues to return the default system cursor. Concrete
+ * subclasses which handle the drawing of an onscreen menu component
+ * may override this method and provide the appropriate information.
+ *
+ * @param cursor the new cursor to use.
+ * @see #getCursor()
+ */
+ public void setCursor(Cursor cursor)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the enabled/disabled state of this component.
+ * <br />
+ * <br />
+ * As this abstract component has no properties related to
+ * its enabled or disabled state, the implementation of this
+ * method is left to subclasses.
+ *
+ * @param enabled true if the component should be enabled,
+ * false otherwise.
+ * @see #getEnabled()
+ */
+ public void setEnabled(boolean enabled)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the <code>Font</code> used for text created by this component.
+ * Unspecified behaviour occurs when null is given as the new
+ * font.
+ *
+ * @param font the new font to use for text.
+ * @see #getFont()
+ */
+ public void setFont(Font font)
+ {
+ /* Call the method of the enclosing component */
+ MenuComponent.this.setFont(font);
+ }
+
+ /**
+ * Sets the foreground color of the component to that specified.
+ * Unspecified behaviour occurs when null is given as the new
+ * background color.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply ignores the supplied
+ * color and continues to return the default system text color used
+ * for rendering menus.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @param color the new foreground color.
+ * @see #getForeground()
+ */
+ public void setForeground(Color color)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the location of the component, with co-ordinates
+ * relative to the parent component and using the co-ordinate
+ * space of the screen. Thus, the point (0,0) is the upper
+ * left corner of the parent component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @param point the location of the component, relative to its parent.
+ * @see #getLocation()
+ */
+ public void setLocation(Point point)
+ {
+ getBounds().setLocation(point);
+ }
+
+ /**
+ * Sets the size of the component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @param size the new size of the component.
+ * @see #getSize()
+ */
+ public void setSize(Dimension size)
+ {
+ getBounds().setSize(size);
+ }
+
+ /**
+ * Sets the visibility state of the component. A component may
+ * be visible but not drawn on the screen if one of its parent
+ * components is not visible. To determine if the component is
+ * actually drawn on screen, <code>isShowing()</code> should be
+ * used.
+ * <br />
+ * <br />
+ * As this abstract component has no properties relating to its
+ * visibility, the implementation of this method is left to subclasses.
+ *
+ * @param visibility the new visibility of the component -- true if
+ * the component is visible, false if not.
+ * @see #isShowing()
+ * @see #isVisible()
+ */
+ public void setVisible(boolean visibility)
+ {
+ /* Ignored */
+ }
+
+} /* class AccessibleAWTMenuComponent */
+
+
+} // class MenuComponent
diff --git a/libjava/classpath/java/awt/MenuContainer.java b/libjava/classpath/java/awt/MenuContainer.java
new file mode 100644
index 0000000..c76ec96
--- /dev/null
+++ b/libjava/classpath/java/awt/MenuContainer.java
@@ -0,0 +1,71 @@
+/* MenuContainer.java -- container for menu items
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This interface is a container for menu components.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public interface MenuContainer
+{
+ /**
+ * Returns the font in use by this container.
+ *
+ * @return the menu font
+ */
+ Font getFont();
+
+ /**
+ * Removes the specified menu component from the menu.
+ *
+ * @param component the menu component to remove
+ */
+ void remove(MenuComponent component);
+
+ /**
+ * Posts an event to the listeners.
+ *
+ * @param event the event to dispatch
+ * @deprecated use {@link MenuComponent#dispatchEvent(AWTEvent)} instead
+ */
+ boolean postEvent(Event event);
+} // interface MenuContainer
diff --git a/libjava/classpath/java/awt/MenuItem.java b/libjava/classpath/java/awt/MenuItem.java
new file mode 100644
index 0000000..66798c8
--- /dev/null
+++ b/libjava/classpath/java/awt/MenuItem.java
@@ -0,0 +1,603 @@
+/* MenuItem.java -- An item in a menu
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.peer.MenuItemPeer;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleValue;
+
+/**
+ * This class represents an item in a menu.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class MenuItem extends MenuComponent
+ implements Serializable, Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization Constant
+private static final long serialVersionUID = -21757335363267194L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The name of the action command generated by this item.
+ * This is package-private to avoid an accessor method.
+ */
+String actionCommand;
+
+/**
+ * @serial Indicates whether or not this menu item is enabled.
+ * This is package-private to avoid an accessor method.
+ */
+boolean enabled = true;
+
+/**
+ * @serial The mask of events that are enabled for this menu item.
+ */
+long eventMask;
+
+/**
+ * @serial This menu item's label
+ * This is package-private to avoid an accessor method.
+ */
+String label = "";
+
+/**
+ * @serial The shortcut for this menu item, if any
+ */
+private MenuShortcut shortcut;
+
+// The list of action listeners for this menu item.
+private transient ActionListener action_listeners;
+
+ protected class AccessibleAWTMenuItem
+ extends MenuComponent.AccessibleAWTMenuComponent
+ implements AccessibleAction, AccessibleValue
+ {
+ /** Constructor */
+ public AccessibleAWTMenuItem()
+ {
+ super();
+ }
+
+
+
+ public String getAccessibleName()
+ {
+ return label;
+ }
+
+ public AccessibleAction getAccessibleAction()
+ {
+ return this;
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.MENU_ITEM;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
+ */
+ public int getAccessibleActionCount()
+ {
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ if (i == 0)
+ return label;
+ else
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ if (i != 0)
+ return false;
+ processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
+ return true;
+ }
+
+ public AccessibleValue getAccessibleValue()
+ {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
+ */
+ public Number getCurrentAccessibleValue()
+ {
+ return (enabled) ? new Integer(1) : new Integer(0);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
+ */
+ public boolean setCurrentAccessibleValue(Number number)
+ {
+ if (number.intValue() == 0)
+ {
+ setEnabled(false);
+ return false;
+ }
+
+ setEnabled(true);
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
+ */
+ public Number getMinimumAccessibleValue()
+ {
+ return new Integer(0);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
+ */
+ public Number getMaximumAccessibleValue()
+ {
+ return new Integer(0);
+ }
+
+ }
+
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>MenuItem</code> with no label
+ * and no shortcut.
+ */
+public
+MenuItem()
+{
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>MenuItem</code> with the specified
+ * label and no shortcut.
+ *
+ * @param label The label for this menu item.
+ */
+public
+MenuItem(String label)
+{
+ this.label = label;
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>MenuItem</code> with the specified
+ * label and shortcut.
+ *
+ * @param label The label for this menu item.
+ * @param shortcut The shortcut for this menu item.
+ */
+public
+MenuItem(String label, MenuShortcut shortcut)
+{
+ this.label = label;
+ this.shortcut = shortcut;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the label for this menu item, which may be <code>null</code>.
+ *
+ * @return The label for this menu item.
+ */
+public String
+getLabel()
+{
+ return(label);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the label for this menu to the specified value.
+ *
+ * @param label The new label for this menu item.
+ */
+public synchronized void
+setLabel(String label)
+{
+ this.label = label;
+ if (peer != null)
+ {
+ MenuItemPeer mp = (MenuItemPeer) peer;
+ mp.setLabel (label);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this menu item is enabled.
+ *
+ * @return <code>true</code> if this menu item is enabled, <code>false</code>
+ * otherwise.
+ */
+public boolean
+isEnabled()
+{
+ return(enabled);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the enabled status of this menu item.
+ *
+ * @param enabled <code>true</code> to enable this menu item,
+ * <code>false</code> otherwise.
+ */
+public synchronized void
+setEnabled(boolean enabled)
+{
+ enable (enabled);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the enabled status of this menu item.
+ *
+ * @param enabled <code>true</code> to enable this menu item,
+ * <code>false</code> otherwise.
+ *
+ * @deprecated This method is deprecated in favor of <code>setEnabled()</code>.
+ */
+public void
+enable(boolean enabled)
+{
+ if (enabled)
+ enable ();
+ else
+ disable ();
+}
+
+/*************************************************************************/
+
+/**
+ * Enables this menu item.
+ *
+ * @deprecated This method is deprecated in favor of <code>setEnabled()</code>.
+ */
+public void
+enable()
+{
+ if (enabled)
+ return;
+
+ this.enabled = true;
+ if (peer != null)
+ ((MenuItemPeer) peer).setEnabled (true);
+}
+
+/*************************************************************************/
+
+/**
+ * Disables this menu item.
+ *
+ * @deprecated This method is deprecated in favor of <code>setEnabled()</code>.
+ */
+public void
+disable()
+{
+ if (!enabled)
+ return;
+
+ this.enabled = false;
+ if (peer != null)
+ ((MenuItemPeer) peer).setEnabled (false);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the shortcut for this menu item, which may be <code>null</code>.
+ *
+ * @return The shortcut for this menu item.
+ */
+public MenuShortcut
+getShortcut()
+{
+ return(shortcut);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the shortcut for this menu item to the specified value. This
+ * must be done before the native peer is created.
+ *
+ * @param shortcut The new shortcut for this menu item.
+ */
+public void
+setShortcut(MenuShortcut shortcut)
+{
+ this.shortcut = shortcut;
+}
+
+/*************************************************************************/
+
+/**
+ * Deletes the shortcut for this menu item if one exists. This must be
+ * done before the native peer is created.
+ */
+public void
+deleteShortcut()
+{
+ shortcut = null;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the name of the action command in the action events
+ * generated by this menu item.
+ *
+ * @return The action command name
+ */
+public String
+getActionCommand()
+{
+ if (actionCommand == null)
+ return label;
+ else
+ return actionCommand;
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the name of the action command in the action events generated by
+ * this menu item.
+ *
+ * @param actionCommand The new action command name.
+ */
+public void
+setActionCommand(String actionCommand)
+{
+ this.actionCommand = actionCommand;
+}
+
+/*************************************************************************/
+
+/**
+ * Enables the specified events. This is done automatically when a
+ * listener is added and does not normally need to be done by
+ * application code.
+ *
+ * @param events The events to enable, which should be the bit masks
+ * from <code>AWTEvent</code>.
+ */
+protected final void
+enableEvents(long events)
+{
+ eventMask |= events;
+ // TODO: see comment in Component.enableEvents().
+}
+
+/*************************************************************************/
+
+/**
+ * Disables the specified events.
+ *
+ * @param events The events to enable, which should be the bit masks
+ * from <code>AWTEvent</code>.
+ */
+protected final void
+disableEvents(long events)
+{
+ eventMask &= ~events;
+}
+
+/*************************************************************************/
+
+/**
+ * Creates the native peer for this object.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createMenuItem (this);
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified listener to the list of registered action listeners
+ * for this component.
+ *
+ * @param listener The listener to add.
+ */
+public synchronized void
+addActionListener(ActionListener listener)
+{
+ action_listeners = AWTEventMulticaster.add(action_listeners, listener);
+
+ enableEvents(AWTEvent.ACTION_EVENT_MASK);
+}
+
+public synchronized void
+removeActionListener(ActionListener l)
+{
+ action_listeners = AWTEventMulticaster.remove(action_listeners, l);
+}
+
+ public synchronized ActionListener[] getActionListeners()
+ {
+ return (ActionListener[])
+ AWTEventMulticaster.getListeners(action_listeners,
+ ActionListener.class);
+ }
+
+/** Returns all registered EventListers of the given listenerType.
+ * listenerType must be a subclass of EventListener, or a
+ * ClassClassException is thrown.
+ * @since 1.3
+ */
+ public EventListener[] getListeners(Class listenerType)
+ {
+ if (listenerType == ActionListener.class)
+ return getActionListeners();
+ return (EventListener[]) Array.newInstance(listenerType, 0);
+ }
+
+/*************************************************************************/
+
+void
+dispatchEventImpl(AWTEvent e)
+{
+ if (e.id <= ActionEvent.ACTION_LAST
+ && e.id >= ActionEvent.ACTION_FIRST
+ && (action_listeners != null
+ || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
+ processEvent(e);
+
+ // Send the event to the parent menu if it has not yet been
+ // consumed.
+ if (!e.isConsumed ())
+ ((Menu) getParent ()).processEvent (e);
+}
+
+/**
+ * Processes the specified event by calling <code>processActionEvent()</code>
+ * if it is an instance of <code>ActionEvent</code>.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ if (event instanceof ActionEvent)
+ processActionEvent((ActionEvent)event);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes the specified event by dispatching it to any registered listeners.
+ *
+ * @param event The event to process.
+ */
+protected void
+processActionEvent(ActionEvent event)
+{
+ if (action_listeners != null)
+ {
+ event.setSource(this);
+ action_listeners.actionPerformed(event);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this object.
+ *
+ * @return A debugging string for this object.
+ */
+public String
+paramString()
+{
+ return ("label=" + label + ",enabled=" + enabled +
+ ",actionCommand=" + actionCommand + "," + super.paramString());
+}
+
+/**
+ * Gets the AccessibleContext associated with this <code>MenuItem</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+public AccessibleContext getAccessibleContext()
+{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTMenuItem();
+ return accessibleContext;
+}
+
+} // class MenuItem
diff --git a/libjava/classpath/java/awt/MenuShortcut.java b/libjava/classpath/java/awt/MenuShortcut.java
new file mode 100644
index 0000000..adfd1d3
--- /dev/null
+++ b/libjava/classpath/java/awt/MenuShortcut.java
@@ -0,0 +1,207 @@
+/* MenuShortcut.java -- A class for menu accelerators
+ Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This class implements a keyboard accelerator for a menu item.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class MenuShortcut implements java.io.Serializable
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization Constant
+private static final long serialVersionUID = 143448358473180225L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The virtual keycode for the shortcut.
+ */
+private int key;
+
+/**
+ * @serial <code>true</code> if the shift key was used with this shortcut,
+ * or <code>false</code> otherwise.
+ */
+private boolean usesShift;
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>MenuShortcut</code> with the
+ * specified virtual key value.
+ *
+ * @param key The virtual keycode for the shortcut.
+ */
+public
+MenuShortcut(int key)
+{
+ this(key, false);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>MenuShortcut</code> with the
+ * specified virtual key value and shift setting.
+ *
+ * @param key The virtual keycode for the shortcut.
+ * @param usesShift <code>true</code> if the shift key was pressed,
+ * <code>false</code> otherwise.
+ */
+public
+MenuShortcut(int key, boolean usesShift)
+{
+ this.key = key;
+ this.usesShift = usesShift;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the virtual keycode for this shortcut.
+ *
+ * @return The virtual keycode for this shortcut.
+ */
+public int
+getKey()
+{
+ return(key);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the shift setting for this shortcut.
+ *
+ * @return <code>true</code> if the shift key was pressed, <code>false</code>
+ * otherwise.
+ */
+public boolean
+usesShiftModifier()
+{
+ return(usesShift);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests this object for equality against the specified object. The two
+ * objects will be considered equal if and only if the specified object
+ * is an instance of <code>MenuShortcut</code> and has the same key value
+ * and shift setting as this object.
+ *
+ * @param obj The object to test for equality against.
+ *
+ * @return <code>true</code> if the two objects are equal, <code>false</code>
+ * otherwise.
+ */
+public boolean
+equals(MenuShortcut obj)
+{
+ if (obj == null)
+ return(false);
+
+ if (obj.key != this.key)
+ return(false);
+
+ if (obj.usesShift != this.usesShift)
+ return(false);
+
+ return(true);
+}
+
+public boolean
+equals(Object obj)
+{
+ if (obj instanceof MenuShortcut)
+ {
+ MenuShortcut ms = (MenuShortcut) obj;
+ return (ms.key == key && ms.usesShift == usesShift);
+ }
+ return false;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a string representation of this shortcut.
+ *
+ * @return A string representation of this shortcut.
+ */
+public String
+toString()
+{
+ return(getClass().getName() + "[" + paramString () + "]");
+}
+
+public int
+hashCode()
+{
+ // Arbitrary.
+ return key + (usesShift ? 23 : 57);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string for this object.
+ *
+ * @return A debugging string for this object.
+ */
+protected String
+paramString()
+{
+ return "key=" + key + ",usesShift=" + usesShift;
+}
+
+} // class MenuShortcut
diff --git a/libjava/classpath/java/awt/PageAttributes.java b/libjava/classpath/java/awt/PageAttributes.java
new file mode 100644
index 0000000..38fb696
--- /dev/null
+++ b/libjava/classpath/java/awt/PageAttributes.java
@@ -0,0 +1,482 @@
+/* PageAttributes.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.util.Locale;
+
+/**
+ * Missing Documentation
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ * @status updated to 1.4, but missing documentation
+ */
+public final class PageAttributes implements Cloneable
+{
+ public static final class ColorType extends AttributeValue
+ {
+ private static final String[] NAMES = { "color", "monochrome" };
+ public static final ColorType COLOR = new ColorType(0);
+ public static final ColorType MONOCHROME = new ColorType(1);
+ private ColorType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class ColorType
+ public static final class MediaType extends AttributeValue
+ {
+ private static final String[] NAMES
+ = { "iso-4a0", "iso-2a0", "iso-a0", "iso-a1", "iso-a2", "iso-a3",
+ "iso-a4", "iso-a5", "iso-a6", "iso-a7", "iso-a8", "iso-a9",
+ "iso-a10", "iso-b0", "iso-b1", "iso-b2", "iso-b3", "iso-b4",
+ "iso-b5", "iso-b6", "iso-b7", "iso-b8", "iso-b9", "iso-b10",
+ "jis-b0", "jis-b1", "jis-b2", "jis-b3", "jis-b4", "jis-b5",
+ "jis-b6", "jis-b7", "jis-b8", "jis-b9", "jis-b10", "iso-c0",
+ "iso-c1", "iso-c2", "iso-c3", "iso-c4", "iso-c5", "iso-c6",
+ "iso-c7", "iso-c8", "iso-c9", "iso-c10", "iso-designated-long",
+ "executive", "folio", "invoice", "ledger", "na-letter", "na-legal",
+ "quarto", "a", "b", "c", "d", "e", "na-10x15-envelope",
+ "na-10x14-envelope", "na-10x13-envelope", "na-9x12-envelope",
+ "na-9x11-envelope", "na-7x9-envelope", "na-6x9-envelope",
+ "na-number-9-envelope", "na-number-10-envelope",
+ "na-number-11-envelope", "na-number-12-envelope",
+ "na-number-14-envelope", "invite-envelope", "italy-envelope",
+ "monarch-envelope", "personal-envelope" };
+ public static final MediaType ISO_4A0 = new MediaType(0);
+ public static final MediaType ISO_2A0 = new MediaType(1);
+ public static final MediaType ISO_A0 = new MediaType(2);
+ public static final MediaType ISO_A1 = new MediaType(3);
+ public static final MediaType ISO_A2 = new MediaType(4);
+ public static final MediaType ISO_A3 = new MediaType(5);
+ public static final MediaType ISO_A4 = new MediaType(6);
+ public static final MediaType ISO_A5 = new MediaType(7);
+ public static final MediaType ISO_A6 = new MediaType(8);
+ public static final MediaType ISO_A7 = new MediaType(9);
+ public static final MediaType ISO_A8 = new MediaType(10);
+ public static final MediaType ISO_A9 = new MediaType(11);
+ public static final MediaType ISO_A10 = new MediaType(12);
+ public static final MediaType ISO_B0 = new MediaType(13);
+ public static final MediaType ISO_B1 = new MediaType(14);
+ public static final MediaType ISO_B2 = new MediaType(15);
+ public static final MediaType ISO_B3 = new MediaType(16);
+ public static final MediaType ISO_B4 = new MediaType(17);
+ public static final MediaType ISO_B5 = new MediaType(18);
+ public static final MediaType ISO_B6 = new MediaType(19);
+ public static final MediaType ISO_B7 = new MediaType(20);
+ public static final MediaType ISO_B8 = new MediaType(21);
+ public static final MediaType ISO_B9 = new MediaType(22);
+ public static final MediaType ISO_B10 = new MediaType(23);
+ public static final MediaType JIS_B0 = new MediaType(24);
+ public static final MediaType JIS_B1 = new MediaType(25);
+ public static final MediaType JIS_B2 = new MediaType(26);
+ public static final MediaType JIS_B3 = new MediaType(27);
+ public static final MediaType JIS_B4 = new MediaType(28);
+ public static final MediaType JIS_B5 = new MediaType(29);
+ public static final MediaType JIS_B6 = new MediaType(30);
+ public static final MediaType JIS_B7 = new MediaType(31);
+ public static final MediaType JIS_B8 = new MediaType(32);
+ public static final MediaType JIS_B9 = new MediaType(33);
+ public static final MediaType JIS_B10 = new MediaType(34);
+ public static final MediaType ISO_C0 = new MediaType(35);
+ public static final MediaType ISO_C1 = new MediaType(36);
+ public static final MediaType ISO_C2 = new MediaType(37);
+ public static final MediaType ISO_C3 = new MediaType(38);
+ public static final MediaType ISO_C4 = new MediaType(39);
+ public static final MediaType ISO_C5 = new MediaType(40);
+ public static final MediaType ISO_C6 = new MediaType(41);
+ public static final MediaType ISO_C7 = new MediaType(42);
+ public static final MediaType ISO_C8 = new MediaType(43);
+ public static final MediaType ISO_C9 = new MediaType(44);
+ public static final MediaType ISO_C10 = new MediaType(45);
+ public static final MediaType ISO_DESIGNATED_LONG = new MediaType(46);
+ public static final MediaType EXECUTIVE = new MediaType(47);
+ public static final MediaType FOLIO = new MediaType(48);
+ public static final MediaType INVOICE = new MediaType(49);
+ public static final MediaType LEDGER = new MediaType(50);
+ public static final MediaType NA_LETTER = new MediaType(51);
+ public static final MediaType NA_LEGAL = new MediaType(52);
+ public static final MediaType QUARTO = new MediaType(53);
+ public static final MediaType A = new MediaType(54);
+ public static final MediaType B = new MediaType(55);
+ public static final MediaType C = new MediaType(56);
+ public static final MediaType D = new MediaType(57);
+ public static final MediaType E = new MediaType(58);
+ public static final MediaType NA_10X15_ENVELOPE = new MediaType(59);
+ public static final MediaType NA_10X14_ENVELOPE = new MediaType(60);
+ public static final MediaType NA_10X13_ENVELOPE = new MediaType(61);
+ public static final MediaType NA_9X12_ENVELOPE = new MediaType(62);
+ public static final MediaType NA_9X11_ENVELOPE = new MediaType(63);
+ public static final MediaType NA_7X9_ENVELOPE = new MediaType(64);
+ public static final MediaType NA_6X9_ENVELOPE = new MediaType(65);
+ public static final MediaType NA_NUMBER_9_ENVELOPE = new MediaType(66);
+ public static final MediaType NA_NUMBER_10_ENVELOPE = new MediaType(67);
+ public static final MediaType NA_NUMBER_11_ENVELOPE = new MediaType(68);
+ public static final MediaType NA_NUMBER_12_ENVELOPE = new MediaType(69);
+ public static final MediaType NA_NUMBER_14_ENVELOPE = new MediaType(70);
+ public static final MediaType INVITE_ENVELOPE = new MediaType(71);
+ public static final MediaType ITALY_ENVELOPE = new MediaType(72);
+ public static final MediaType MONARCH_ENVELOPE = new MediaType(73);
+ public static final MediaType PERSONAL_ENVELOPE = new MediaType(74);
+ public static final MediaType A0 = ISO_A0;
+ public static final MediaType A1 = ISO_A1;
+ public static final MediaType A2 = ISO_A2;
+ public static final MediaType A3 = ISO_A3;
+ public static final MediaType A4 = ISO_A4;
+ public static final MediaType A5 = ISO_A5;
+ public static final MediaType A6 = ISO_A6;
+ public static final MediaType A7 = ISO_A7;
+ public static final MediaType A8 = ISO_A8;
+ public static final MediaType A9 = ISO_A9;
+ public static final MediaType A10 = ISO_A10;
+ public static final MediaType B0 = ISO_B0;
+ public static final MediaType B1 = ISO_B1;
+ public static final MediaType B2 = ISO_B2;
+ public static final MediaType B3 = ISO_B3;
+ public static final MediaType B4 = ISO_B4;
+ public static final MediaType ISO_B4_ENVELOPE = ISO_B4;
+ public static final MediaType B5 = ISO_B5;
+ public static final MediaType ISO_B5_ENVELOPE = ISO_B4;
+ public static final MediaType B6 = ISO_B6;
+ public static final MediaType B7 = ISO_B7;
+ public static final MediaType B8 = ISO_B8;
+ public static final MediaType B9 = ISO_B9;
+ public static final MediaType B10 = ISO_B10;
+ public static final MediaType C0 = ISO_B0;
+ public static final MediaType ISO_C0_ENVELOPE = ISO_C0;
+ public static final MediaType C1 = ISO_C1;
+ public static final MediaType ISO_C1_ENVELOPE = ISO_C1;
+ public static final MediaType C2 = ISO_C2;
+ public static final MediaType ISO_C2_ENVELOPE = ISO_C2;
+ public static final MediaType C3 = ISO_C3;
+ public static final MediaType ISO_C3_ENVELOPE = ISO_C3;
+ public static final MediaType C4 = ISO_C4;
+ public static final MediaType ISO_C4_ENVELOPE = ISO_C4;
+ public static final MediaType C5 = ISO_C5;
+ public static final MediaType ISO_C5_ENVELOPE = ISO_C5;
+ public static final MediaType C6 = ISO_C6;
+ public static final MediaType ISO_C6_ENVELOPE = ISO_C6;
+ public static final MediaType C7 = ISO_C7;
+ public static final MediaType ISO_C7_ENVELOPE = ISO_C7;
+ public static final MediaType C8 = ISO_C8;
+ public static final MediaType ISO_C8_ENVELOPE = ISO_C8;
+ public static final MediaType C9 = ISO_C9;
+ public static final MediaType ISO_C9_ENVELOPE = ISO_C9;
+ public static final MediaType C10 = ISO_C10;
+ public static final MediaType ISO_C10_ENVELOPE = ISO_C10;
+ public static final MediaType ISO_DESIGNATED_LONG_ENVELOPE
+ = ISO_DESIGNATED_LONG;
+ public static final MediaType STATEMENT = INVOICE;
+ public static final MediaType TABLOID = LEDGER;
+ public static final MediaType LETTER = NA_LETTER;
+ public static final MediaType NOTE = NA_LETTER;
+ public static final MediaType LEGAL = NA_LEGAL;
+ public static final MediaType ENV_10X15 = NA_10X15_ENVELOPE;
+ public static final MediaType ENV_10X14 = NA_10X14_ENVELOPE;
+ public static final MediaType ENV_10X13 = NA_10X13_ENVELOPE;
+ public static final MediaType ENV_9X12 = NA_9X12_ENVELOPE;
+ public static final MediaType ENV_9X11 = NA_9X11_ENVELOPE;
+ public static final MediaType ENV_7X9 = NA_7X9_ENVELOPE;
+ public static final MediaType ENV_6X9 = NA_6X9_ENVELOPE;
+ public static final MediaType ENV_9 = NA_NUMBER_9_ENVELOPE;
+ public static final MediaType ENV_10 = NA_NUMBER_10_ENVELOPE;
+ public static final MediaType ENV_11 = NA_NUMBER_11_ENVELOPE;
+ public static final MediaType ENV_12 = NA_NUMBER_12_ENVELOPE;
+ public static final MediaType ENV_14 = NA_NUMBER_14_ENVELOPE;
+ public static final MediaType ENV_INVITE = INVITE_ENVELOPE;
+ public static final MediaType ENV_ITALY = ITALY_ENVELOPE;
+ public static final MediaType ENV_MONARCH = MONARCH_ENVELOPE;
+ public static final MediaType ENV_PERSONAL = PERSONAL_ENVELOPE;
+ public static final MediaType INVITE = INVITE_ENVELOPE;
+ public static final MediaType ITALY = ITALY_ENVELOPE;
+ public static final MediaType MONARCH = MONARCH_ENVELOPE;
+ public static final MediaType PERSONAL = PERSONAL_ENVELOPE;
+ private MediaType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class MediaType
+ public static final class OrientationRequestedType extends AttributeValue
+ {
+ private static final String[] NAMES = { "portrait", "landscape" };
+ public static final OrientationRequestedType PORTRAIT
+ = new OrientationRequestedType(0);
+ public static final OrientationRequestedType LANDSCAPE
+ = new OrientationRequestedType(1);
+ private OrientationRequestedType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class OrientationRequestedType
+ public static final class OriginType extends AttributeValue
+ {
+ private static final String[] NAMES = { "physical", "printable" };
+ public static final OriginType PHYSICAL = new OriginType(0);
+ public static final OriginType PRINTABLE = new OriginType(1);
+ private OriginType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class OriginType
+ public static final class PrintQualityType extends AttributeValue
+ {
+ private static final String[] NAMES = { "high", "normal", "draft" };
+ public static final PrintQualityType HIGH = new PrintQualityType(0);
+ public static final PrintQualityType NORMAL = new PrintQualityType(1);
+ public static final PrintQualityType DRAFT = new PrintQualityType(2);
+ private PrintQualityType(int value)
+ {
+ super(value, NAMES);
+ }
+ } // class PrintQualityType
+
+
+ private ColorType color;
+ private MediaType media;
+ private OrientationRequestedType orientation;
+ private OriginType origin;
+ private PrintQualityType quality;
+ private int resolutionX;
+ private int resolutionY;
+ private int resolutionScale;
+ public PageAttributes()
+ {
+ color = ColorType.MONOCHROME;
+ setMediaToDefault();
+ orientation = OrientationRequestedType.PORTRAIT;
+ origin = OriginType.PHYSICAL;
+ quality = PrintQualityType.NORMAL;
+ setPrinterResolutionToDefault();
+ }
+
+ public PageAttributes(PageAttributes attr)
+ {
+ set(attr);
+ }
+
+ public PageAttributes(ColorType color, MediaType media,
+ OrientationRequestedType orientation,
+ OriginType origin, PrintQualityType quality,
+ int[] resolution)
+ {
+ if (color == null || media == null || orientation == null
+ || origin == null || quality == null)
+ throw new IllegalArgumentException();
+ setPrinterResolution(resolution);
+ this.color = color;
+ this.media = media;
+ this.orientation = orientation;
+ this.origin = origin;
+ this.quality = quality;
+ }
+
+ public Object clone()
+ {
+ return new PageAttributes(this);
+ }
+
+ public void set(PageAttributes attr)
+ {
+ color = attr.color;
+ media = attr.media;
+ orientation = attr.orientation;
+ origin = attr.origin;
+ quality = attr.quality;
+ resolutionX = attr.resolutionX;
+ resolutionY = attr.resolutionY;
+ resolutionScale = attr.resolutionScale;
+ }
+
+ public ColorType getColor()
+ {
+ return color;
+ }
+
+ public void setColor(ColorType color)
+ {
+ if (color == null)
+ throw new IllegalArgumentException();
+ this.color = color;
+ }
+
+ public MediaType getMedia()
+ {
+ return media;
+ }
+
+ public void setMedia(MediaType media)
+ {
+ if (media == null)
+ throw new IllegalArgumentException();
+ this.media = media;
+ }
+
+ public void setMediaToDefault()
+ {
+ String country = Locale.getDefault().getCountry();
+ media = ("US".equals(country) || "CA".equals(country)) ? MediaType.LETTER
+ : MediaType.A4;
+ }
+
+ public OrientationRequestedType getOrientationRequested()
+ {
+ return orientation;
+ }
+
+ public void setOrientationRequested(OrientationRequestedType orientation)
+ {
+ if (orientation == null)
+ throw new IllegalArgumentException();
+ this.orientation = orientation;
+ }
+
+ public void setOrientationRequested(int orientation)
+ {
+ if (orientation == 3)
+ this.orientation = OrientationRequestedType.PORTRAIT;
+ else if (orientation == 4)
+ this.orientation = OrientationRequestedType.LANDSCAPE;
+ else
+ throw new IllegalArgumentException();
+ }
+
+ public void setOrientationRequestedToDefault()
+ {
+ orientation = OrientationRequestedType.PORTRAIT;
+ }
+
+ public OriginType getOrigin()
+ {
+ return origin;
+ }
+
+ public void setOrigin(OriginType origin)
+ {
+ if (origin == null)
+ throw new IllegalArgumentException();
+ this.origin = origin;
+ }
+
+ public PrintQualityType getPrintQuality()
+ {
+ return quality;
+ }
+
+ public void setPrintQuality(PrintQualityType quality)
+ {
+ if (quality == null)
+ throw new IllegalArgumentException();
+ this.quality = quality;
+ }
+
+ public void setPrintQuality(int quality)
+ {
+ if (quality == 3)
+ this.quality = PrintQualityType.DRAFT;
+ else if (quality == 4)
+ this.quality = PrintQualityType.NORMAL;
+ else if (quality == 5)
+ this.quality = PrintQualityType.HIGH;
+ else
+ throw new IllegalArgumentException();
+ }
+
+ public void setPrintQualityToDefault()
+ {
+ quality = PrintQualityType.NORMAL;
+ }
+
+ public int[] getPrinterResolution()
+ {
+ return new int[] { resolutionX, resolutionY, resolutionScale };
+ }
+
+ public void setPrinterResolution(int[] resolution)
+ {
+ if (resolution == null || resolution.length != 3 || resolution[0] <= 0
+ || resolution[1] <= 0 || resolution[2] < 3 || resolution[2] > 4)
+ throw new IllegalArgumentException();
+ resolutionX = resolution[0];
+ resolutionY = resolution[1];
+ resolutionScale = resolution[2];
+ }
+
+ public void setPrinterResolution(int resolution)
+ {
+ if (resolution <= 0)
+ throw new IllegalArgumentException();
+ resolutionX = resolution;
+ resolutionY = resolution;
+ resolutionScale = 3;
+ }
+
+ public void setPrinterResolutionToDefault()
+ {
+ resolutionX = 72;
+ resolutionY = 72;
+ resolutionScale = 3;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ return true;
+ if (! (o instanceof PageAttributes))
+ return false;
+ PageAttributes pa = (PageAttributes) o;
+ return color == pa.color && media == pa.media
+ && orientation == pa.orientation && origin == pa.origin
+ && quality == pa.quality && resolutionX == pa.resolutionX
+ && resolutionY == pa.resolutionY
+ && resolutionScale == pa.resolutionScale;
+ }
+ public int hashCode()
+ {
+ return (color.value << 31) ^ (media.value << 24)
+ ^ (orientation.value << 23) ^ (origin.value << 22)
+ ^ (quality.value << 20) ^ (resolutionScale << 19)
+ ^ (resolutionY << 10) ^ resolutionX;
+ }
+ public String toString()
+ {
+ return "color=" + color + ",media=" + media + ",orientation-requested="
+ + orientation + ",origin=" + origin + ",print-quality=" + quality
+ + ",printer-resolution=[" + resolutionX + ',' + resolutionY + ','
+ + resolutionScale + ']';
+ }
+} // class PageAttributes
diff --git a/libjava/classpath/java/awt/Paint.java b/libjava/classpath/java/awt/Paint.java
new file mode 100644
index 0000000..0f099cc
--- /dev/null
+++ b/libjava/classpath/java/awt/Paint.java
@@ -0,0 +1,79 @@
+/* Paint.java -- generate colors for Graphics2D operations
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+/**
+ * Defines how color patterns are generated for Graphics2D operations. This
+ * is used to perform the <code>draw</code> and <code>fill</code> methods
+ * of the graphics object. Instances must be immutable, because the graphics
+ * object does not clone them.
+ *
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @see PaintContext
+ * @see Color
+ * @see GradientPaint
+ * @see TexturePaint
+ * @see Graphics2D#setPaint(Paint)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface Paint extends Transparency
+{
+ /**
+ * Create the context necessary for performing the color pattern generation.
+ * The color model is a hint, and may be null for Classpath implementations;
+ * however some legacy code may throw a NullPointerException when passed a
+ * null. Leaving the color model null provides the most efficiency and leeway
+ * in the generation of the color pattern.
+ *
+ * @param cm the color model, used as a hint
+ * @param deviceBounds the device space bounding box of the painted area
+ * @param userBounds the user space bounding box of the painted area
+ * @param xform the transformation from user space to device space
+ * @param hints any hints for choosing between rendering alternatives
+ * @return the context for performing the paint
+ */
+ PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+ Rectangle2D userBounds, AffineTransform xform,
+ RenderingHints hints);
+} // interface Paint
diff --git a/libjava/classpath/java/awt/PaintContext.java b/libjava/classpath/java/awt/PaintContext.java
new file mode 100644
index 0000000..3d5fdcd
--- /dev/null
+++ b/libjava/classpath/java/awt/PaintContext.java
@@ -0,0 +1,76 @@
+/* PaintContext.java -- the environment for performing a paint operation
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+/**
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @see Paint
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface PaintContext
+{
+ /**
+ * Release the resources allocated for the paint.
+ */
+ void dispose();
+
+ /**
+ * Return the color model of this context. It may be different from the
+ * hint specified during createContext, as not all contexts can generate
+ * color patterns in an arbitrary model.
+ *
+ * @return the context color model
+ */
+ ColorModel getColorModel();
+
+ /**
+ * Return a raster containing the colors for the graphics operation.
+ *
+ * @param x the x-coordinate, in device space
+ * @param y the y-coordinate, in device space
+ * @param w the width, in device space
+ * @param h the height, in device space
+ * @return a raster for the given area and color
+ */
+ Raster getRaster(int x, int y, int w, int h);
+} // interface PaintContext
diff --git a/libjava/classpath/java/awt/Panel.java b/libjava/classpath/java/awt/Panel.java
new file mode 100644
index 0000000..cc17eef
--- /dev/null
+++ b/libjava/classpath/java/awt/Panel.java
@@ -0,0 +1,173 @@
+/* Panel.java -- Simple container object
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * A panel is a simple container class. It's default layout is the
+ * <code>FlowLayout</code> manager.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see FlowLayout
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public class Panel extends Container implements Accessible
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -2728009084054400034L;
+
+ /** The cached accessible context. */
+ private transient AccessibleContext context;
+
+ /** Flag set when the first system-requested paint event is
+ dispatched. */
+ private transient boolean initialSystemUpdateDone;
+
+ /** Flag set when the first application-requested paint event is
+ consumed. */
+ private transient boolean initialUpdateConsumed;
+
+ /*
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_panel_number;
+
+ /**
+ * Initializes a new instance of <code>Panel</code> that has a default
+ * layout manager of <code>FlowLayout</code>.
+ */
+ public Panel()
+ {
+ this(new FlowLayout());
+ }
+
+ /**
+ * Initializes a new instance of <code>Panel</code> with the specified
+ * layout manager.
+ *
+ * @param layoutManager the layout manager for this object
+ * @since 1.1
+ */
+ public Panel(LayoutManager layoutManager)
+ {
+ setLayout(layoutManager);
+ }
+
+ /**
+ * Notifies this object to create its native peer.
+ *
+ * @see #isDisplayable()
+ * @see #removeNotify()
+ */
+ public void addNotify()
+ {
+ if (peer == null)
+ peer = getToolkit().createPanel(this);
+ super.addNotify();
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this panel, creating one if
+ * necessary. This always returns an instance of {@link AccessibleAWTPanel}.
+ *
+ * @return the accessibility context of this panel
+ * @since 1.3
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ if (context == null)
+ context = new AccessibleAWTPanel();
+ return context;
+ }
+
+ /**
+ * This class provides accessibility support for Panels, and is the
+ * runtime type returned by {@link #getAccessibleContext()}.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ */
+ protected class AccessibleAWTPanel extends AccessibleAWTContainer
+ {
+ /**
+ * Compatible with JDK 1.4+.
+ */
+ private static final long serialVersionUID = -6409552226660031050L;
+
+ /**
+ * The default constructor.
+ */
+ protected AccessibleAWTPanel()
+ {
+ }
+
+ /**
+ * Get the role of this accessible object, a panel.
+ *
+ * @return the role of the object
+ * @see AccessibleRole#PANEL
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.PANEL;
+ }
+ }
+
+ /**
+ * Generate a unique name for this panel.
+ *
+ * @return A unique name for this panel.
+ */
+ String generateName ()
+ {
+ return "panel" + getUniqueLong ();
+ }
+
+ private static synchronized long getUniqueLong ()
+ {
+ return next_panel_number++;
+ }
+}
diff --git a/libjava/classpath/java/awt/Point.java b/libjava/classpath/java/awt/Point.java
new file mode 100644
index 0000000..492749b
--- /dev/null
+++ b/libjava/classpath/java/awt/Point.java
@@ -0,0 +1,245 @@
+/* Point.java -- represents a point in 2-D space
+ Copyright (C) 1999, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+
+/**
+ * This class represents a point on the screen using cartesian coordinates.
+ * Remember that in screen coordinates, increasing x values go from left to
+ * right, and increasing y values go from top to bottom.
+ *
+ * <p>There are some public fields; if you mess with them in an inconsistent
+ * manner, it is your own fault when you get invalid results. Also, this
+ * class is not threadsafe.
+ *
+ * @author Per Bothner (bothner@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public class Point extends Point2D implements Serializable
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -5276940640259749850L;
+
+ /**
+ * The x coordinate.
+ *
+ * @see #getLocation()
+ * @see #move(int, int)
+ * @serial the X coordinate of the point
+ */
+ public int x;
+
+ /**
+ * The y coordinate.
+ *
+ * @see #getLocation()
+ * @see #move(int, int)
+ * @serial The Y coordinate of the point
+ */
+ public int y;
+
+ /**
+ * Initializes a new instance of <code>Point</code> representing the
+ * coordiates (0,0).
+ *
+ * @since 1.1
+ */
+ public Point()
+ {
+ }
+
+ /**
+ * Initializes a new instance of <code>Point</code> with coordinates
+ * identical to the coordinates of the specified points.
+ *
+ * @param p the point to copy the coordinates from
+ * @throws NullPointerException if p is null
+ */
+ public Point(Point p)
+ {
+ x = p.x;
+ y = p.y;
+ }
+
+ /**
+ * Initializes a new instance of <code>Point</code> with the specified
+ * coordinates.
+ *
+ * @param x the X coordinate
+ * @param y the Y coordinate
+ */
+ public Point(int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Get the x coordinate.
+ *
+ * @return the value of x, as a double
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Get the y coordinate.
+ *
+ * @return the value of y, as a double
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Returns the location of this point. A pretty useless method, as this
+ * is already a point.
+ *
+ * @return a copy of this point
+ * @see #setLocation(Point)
+ * @since 1.1
+ */
+ public Point getLocation()
+ {
+ return new Point(x, y);
+ }
+
+ /**
+ * Sets this object's coordinates to match those of the specified point.
+ *
+ * @param p the point to copy the coordinates from
+ * @throws NullPointerException if p is null
+ * @since 1.1
+ */
+ public void setLocation(Point p)
+ {
+ x = p.x;
+ y = p.y;
+ }
+
+ /**
+ * Sets this object's coordinates to the specified values. This method
+ * is identical to the <code>move()</code> method.
+ *
+ * @param x the new X coordinate
+ * @param y the new Y coordinate
+ */
+ public void setLocation(int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Sets this object's coordinates to the specified values. This method
+ * performs normal casting from double to int, so you may lose precision.
+ *
+ * @param x the new X coordinate
+ * @param y the new Y coordinate
+ */
+ public void setLocation(double x, double y)
+ {
+ this.x = (int) x;
+ this.y = (int) y;
+ }
+
+ /**
+ * Sets this object's coordinates to the specified values. This method
+ * is identical to the <code>setLocation(int, int)</code> method.
+ *
+ * @param x the new X coordinate
+ * @param y the new Y coordinate
+ */
+ public void move(int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Changes the coordinates of this point such that the specified
+ * <code>dx</code> parameter is added to the existing X coordinate and
+ * <code>dy</code> is added to the existing Y coordinate.
+ *
+ * @param dx the amount to add to the X coordinate
+ * @param dy the amount to add to the Y coordinate
+ */
+ public void translate(int dx, int dy)
+ {
+ x += dx;
+ y += dy;
+ }
+
+ /**
+ * Tests whether or not this object is equal to the specified object.
+ * This will be true if and only if the specified object is an instance
+ * of Point2D and has the same X and Y coordinates.
+ *
+ * @param obj the object to test against for equality
+ * @return true if the specified object is equal
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof Point2D))
+ return false;
+ Point2D p = (Point2D) obj;
+ return x == p.getX() && y == p.getY();
+ }
+
+ /**
+ * Returns a string representation of this object. The format is:
+ * <code>getClass().getName() + "[x=" + x + ",y=" + y + ']'</code>.
+ *
+ * @return a string representation of this object
+ */
+ public String toString()
+ {
+ return getClass().getName() + "[x=" + x + ",y=" + y + ']';
+ }
+} // class Point
diff --git a/libjava/classpath/java/awt/Polygon.java b/libjava/classpath/java/awt/Polygon.java
new file mode 100644
index 0000000..a72522c
--- /dev/null
+++ b/libjava/classpath/java/awt/Polygon.java
@@ -0,0 +1,613 @@
+/* Polygon.java -- class representing a polygon
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+
+/**
+ * This class represents a polygon, a closed, two-dimensional region in a
+ * coordinate space. The region is bounded by an arbitrary number of line
+ * segments, between (x,y) coordinate vertices. The polygon has even-odd
+ * winding, meaning that a point is inside the shape if it crosses the
+ * boundary an odd number of times on the way to infinity.
+ *
+ * <p>There are some public fields; if you mess with them in an inconsistent
+ * manner, it is your own fault when you get NullPointerException,
+ * ArrayIndexOutOfBoundsException, or invalid results. Also, this class is
+ * not threadsafe.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public class Polygon implements Shape, Serializable
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -6460061437900069969L;
+
+ /**
+ * This total number of endpoints.
+ *
+ * @serial the number of endpoints, possibly less than the array sizes
+ */
+ public int npoints;
+
+ /**
+ * The array of X coordinates of endpoints. This should not be null.
+ *
+ * @see #addPoint(int, int)
+ * @serial the x coordinates
+ */
+ public int[] xpoints;
+
+ /**
+ * The array of Y coordinates of endpoints. This should not be null.
+ *
+ * @see #addPoint(int, int)
+ * @serial the y coordinates
+ */
+ public int[] ypoints;
+
+ /**
+ * The bounding box of this polygon. This is lazily created and cached, so
+ * it must be invalidated after changing points.
+ *
+ * @see #getBounds()
+ * @serial the bounding box, or null
+ */
+ protected Rectangle bounds;
+
+ /** A big number, but not so big it can't survive a few float operations */
+ private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
+
+ /**
+ * Initializes an empty polygon.
+ */
+ public Polygon()
+ {
+ // Leave room for growth.
+ xpoints = new int[4];
+ ypoints = new int[4];
+ }
+
+ /**
+ * Create a new polygon with the specified endpoints. The arrays are copied,
+ * so that future modifications to the parameters do not affect the polygon.
+ *
+ * @param xpoints the array of X coordinates for this polygon
+ * @param ypoints the array of Y coordinates for this polygon
+ * @param npoints the total number of endpoints in this polygon
+ * @throws NegativeArraySizeException if npoints is negative
+ * @throws IndexOutOfBoundsException if npoints exceeds either array
+ * @throws NullPointerException if xpoints or ypoints is null
+ */
+ public Polygon(int[] xpoints, int[] ypoints, int npoints)
+ {
+ this.xpoints = new int[npoints];
+ this.ypoints = new int[npoints];
+ System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
+ System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);
+ this.npoints = npoints;
+ }
+
+ /**
+ * Reset the polygon to be empty. The arrays are left alone, to avoid object
+ * allocation, but the number of points is set to 0, and all cached data
+ * is discarded. If you are discarding a huge number of points, it may be
+ * more efficient to just create a new Polygon.
+ *
+ * @see #invalidate()
+ * @since 1.4
+ */
+ public void reset()
+ {
+ npoints = 0;
+ invalidate();
+ }
+
+ /**
+ * Invalidate or flush all cached data. After direct manipulation of the
+ * public member fields, this is necessary to avoid inconsistent results
+ * in methods like <code>contains</code>.
+ *
+ * @see #getBounds()
+ * @since 1.4
+ */
+ public void invalidate()
+ {
+ bounds = null;
+ }
+
+ /**
+ * Translates the polygon by adding the specified values to all X and Y
+ * coordinates. This updates the bounding box, if it has been calculated.
+ *
+ * @param dx the amount to add to all X coordinates
+ * @param dy the amount to add to all Y coordinates
+ * @since 1.1
+ */
+ public void translate(int dx, int dy)
+ {
+ int i = npoints;
+ while (--i >= 0)
+ {
+ xpoints[i] += dx;
+ ypoints[i] += dy;
+ }
+ if (bounds != null)
+ {
+ bounds.x += dx;
+ bounds.y += dy;
+ }
+ }
+
+ /**
+ * Adds the specified endpoint to the polygon. This updates the bounding
+ * box, if it has been created.
+ *
+ * @param x the X coordinate of the point to add
+ * @param y the Y coordiante of the point to add
+ */
+ public void addPoint(int x, int y)
+ {
+ if (npoints + 1 > xpoints.length)
+ {
+ int[] newx = new int[npoints + 1];
+ System.arraycopy(xpoints, 0, newx, 0, npoints);
+ xpoints = newx;
+ }
+ if (npoints + 1 > ypoints.length)
+ {
+ int[] newy = new int[npoints + 1];
+ System.arraycopy(ypoints, 0, newy, 0, npoints);
+ ypoints = newy;
+ }
+ xpoints[npoints] = x;
+ ypoints[npoints] = y;
+ npoints++;
+ if (bounds != null)
+ {
+ if (npoints == 1)
+ {
+ bounds.x = x;
+ bounds.y = y;
+ }
+ else
+ {
+ if (x < bounds.x)
+ {
+ bounds.width += bounds.x - x;
+ bounds.x = x;
+ }
+ else if (x > bounds.x + bounds.width)
+ bounds.width = x - bounds.x;
+ if (y < bounds.y)
+ {
+ bounds.height += bounds.y - y;
+ bounds.y = y;
+ }
+ else if (y > bounds.y + bounds.height)
+ bounds.height = y - bounds.y;
+ }
+ }
+ }
+
+ /**
+ * Returns the bounding box of this polygon. This is the smallest
+ * rectangle with sides parallel to the X axis that will contain this
+ * polygon.
+ *
+ * @return the bounding box for this polygon
+ * @see #getBounds2D()
+ * @since 1.1
+ */
+ public Rectangle getBounds()
+ {
+ return getBoundingBox();
+ }
+
+ /**
+ * Returns the bounding box of this polygon. This is the smallest
+ * rectangle with sides parallel to the X axis that will contain this
+ * polygon.
+ *
+ * @return the bounding box for this polygon
+ * @see #getBounds2D()
+ * @deprecated use {@link #getBounds()} instead
+ */
+ public Rectangle getBoundingBox()
+ {
+ if (bounds == null)
+ {
+ if (npoints == 0)
+ return bounds = new Rectangle();
+ int i = npoints - 1;
+ int minx = xpoints[i];
+ int maxx = minx;
+ int miny = ypoints[i];
+ int maxy = miny;
+ while (--i >= 0)
+ {
+ int x = xpoints[i];
+ int y = ypoints[i];
+ if (x < minx)
+ minx = x;
+ else if (x > maxx)
+ maxx = x;
+ if (y < miny)
+ miny = y;
+ else if (y > maxy)
+ maxy = y;
+ }
+ bounds = new Rectangle(minx, miny, maxx - minx, maxy - miny);
+ }
+ return bounds;
+ }
+
+ /**
+ * Tests whether or not the specified point is inside this polygon.
+ *
+ * @param p the point to test
+ * @return true if the point is inside this polygon
+ * @throws NullPointerException if p is null
+ * @see #contains(double, double)
+ */
+ public boolean contains(Point p)
+ {
+ return contains(p.getX(), p.getY());
+ }
+
+ /**
+ * Tests whether or not the specified point is inside this polygon.
+ *
+ * @param x the X coordinate of the point to test
+ * @param y the Y coordinate of the point to test
+ * @return true if the point is inside this polygon
+ * @see #contains(double, double)
+ * @since 1.1
+ */
+ public boolean contains(int x, int y)
+ {
+ return contains((double) x, (double) y);
+ }
+
+ /**
+ * Tests whether or not the specified point is inside this polygon.
+ *
+ * @param x the X coordinate of the point to test
+ * @param y the Y coordinate of the point to test
+ * @return true if the point is inside this polygon
+ * @see #contains(double, double)
+ * @deprecated use {@link #contains(int, int)} instead
+ */
+ public boolean inside(int x, int y)
+ {
+ return contains((double) x, (double) y);
+ }
+
+ /**
+ * Returns a high-precision bounding box of this polygon. This is the
+ * smallest rectangle with sides parallel to the X axis that will contain
+ * this polygon.
+ *
+ * @return the bounding box for this polygon
+ * @see #getBounds()
+ * @since 1.2
+ */
+ public Rectangle2D getBounds2D()
+ {
+ // For polygons, the integer version is exact!
+ return getBounds();
+ }
+
+ /**
+ * Tests whether or not the specified point is inside this polygon.
+ *
+ * @param x the X coordinate of the point to test
+ * @param y the Y coordinate of the point to test
+ * @return true if the point is inside this polygon
+ * @since 1.2
+ */
+ public boolean contains(double x, double y)
+ {
+ return ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0);
+ }
+
+ /**
+ * Tests whether or not the specified point is inside this polygon.
+ *
+ * @param p the point to test
+ * @return true if the point is inside this polygon
+ * @throws NullPointerException if p is null
+ * @see #contains(double, double)
+ * @since 1.2
+ */
+ public boolean contains(Point2D p)
+ {
+ return contains(p.getX(), p.getY());
+ }
+
+ /**
+ * Test if a high-precision rectangle intersects the shape. This is true
+ * if any point in the rectangle is in the shape. This implementation is
+ * precise.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle, treated as point if negative
+ * @param h the height of the rectangle, treated as point if negative
+ * @return true if the rectangle intersects this shape
+ * @since 1.2
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ /* Does any edge intersect? */
+ if (evaluateCrossings(x, y, false, w) != 0 /* top */
+ || evaluateCrossings(x, y + h, false, w) != 0 /* bottom */
+ || evaluateCrossings(x + w, y, true, h) != 0 /* right */
+ || evaluateCrossings(x, y, true, h) != 0) /* left */
+ return true;
+
+ /* No intersections, is any point inside? */
+ if ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Test if a high-precision rectangle intersects the shape. This is true
+ * if any point in the rectangle is in the shape. This implementation is
+ * precise.
+ *
+ * @param r the rectangle
+ * @return true if the rectangle intersects this shape
+ * @throws NullPointerException if r is null
+ * @see #intersects(double, double, double, double)
+ * @since 1.2
+ */
+ public boolean intersects(Rectangle2D r)
+ {
+ return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Test if a high-precision rectangle lies completely in the shape. This is
+ * true if all points in the rectangle are in the shape. This implementation
+ * is precise.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle, treated as point if negative
+ * @param h the height of the rectangle, treated as point if negative
+ * @return true if the rectangle is contained in this shape
+ * @since 1.2
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ if (! getBounds2D().intersects(x, y, w, h))
+ return false;
+
+ /* Does any edge intersect? */
+ if (evaluateCrossings(x, y, false, w) != 0 /* top */
+ || evaluateCrossings(x, y + h, false, w) != 0 /* bottom */
+ || evaluateCrossings(x + w, y, true, h) != 0 /* right */
+ || evaluateCrossings(x, y, true, h) != 0) /* left */
+ return false;
+
+ /* No intersections, is any point inside? */
+ if ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Test if a high-precision rectangle lies completely in the shape. This is
+ * true if all points in the rectangle are in the shape. This implementation
+ * is precise.
+ *
+ * @param r the rectangle
+ * @return true if the rectangle is contained in this shape
+ * @throws NullPointerException if r is null
+ * @see #contains(double, double, double, double)
+ * @since 1.2
+ */
+ public boolean contains(Rectangle2D r)
+ {
+ return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Return an iterator along the shape boundary. If the optional transform
+ * is provided, the iterator is transformed accordingly. Each call returns
+ * a new object, independent from others in use. This class is not
+ * threadsafe to begin with, so the path iterator is not either.
+ *
+ * @param transform an optional transform to apply to the iterator
+ * @return a new iterator over the boundary
+ * @since 1.2
+ */
+ public PathIterator getPathIterator(final AffineTransform transform)
+ {
+ return new PathIterator()
+ {
+ /** The current vertex of iteration. */
+ private int vertex;
+
+ public int getWindingRule()
+ {
+ return WIND_EVEN_ODD;
+ }
+
+ public boolean isDone()
+ {
+ return vertex > npoints;
+ }
+
+ public void next()
+ {
+ vertex++;
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ if (vertex >= npoints)
+ return SEG_CLOSE;
+ coords[0] = xpoints[vertex];
+ coords[1] = ypoints[vertex];
+ if (transform != null)
+ transform.transform(coords, 0, coords, 0, 1);
+ return vertex == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ if (vertex >= npoints)
+ return SEG_CLOSE;
+ coords[0] = xpoints[vertex];
+ coords[1] = ypoints[vertex];
+ if (transform != null)
+ transform.transform(coords, 0, coords, 0, 1);
+ return vertex == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+ };
+ }
+
+ /**
+ * Return an iterator along the flattened version of the shape boundary.
+ * Since polygons are already flat, the flatness parameter is ignored, and
+ * the resulting iterator only has SEG_MOVETO, SEG_LINETO and SEG_CLOSE
+ * points. If the optional transform is provided, the iterator is
+ * transformed accordingly. Each call returns a new object, independent
+ * from others in use. This class is not threadsafe to begin with, so the
+ * path iterator is not either.
+ *
+ * @param transform an optional transform to apply to the iterator
+ * @param flatness the maximum distance for deviation from the real boundary
+ * @return a new iterator over the boundary
+ * @since 1.2
+ */
+ public PathIterator getPathIterator(AffineTransform transform,
+ double flatness)
+ {
+ return getPathIterator(transform);
+ }
+
+ /**
+ * Helper for contains, intersects, calculates the number of intersections
+ * between the polygon and a line extending from the point (x, y) along
+ * the positive X, or Y axis, within a given interval.
+ *
+ * @return the winding number.
+ * @see #condensed
+ * @see #contains(double, double)
+ */
+ private int evaluateCrossings(double x, double y, boolean useYaxis,
+ double distance)
+ {
+ double x0;
+ double x1;
+ double y0;
+ double y1;
+ double epsilon = 0.0;
+ int crossings = 0;
+ int[] xp;
+ int[] yp;
+
+ if (useYaxis)
+ {
+ xp = ypoints;
+ yp = xpoints;
+ double swap;
+ swap = y;
+ y = x;
+ x = swap;
+ }
+ else
+ {
+ xp = xpoints;
+ yp = ypoints;
+ }
+
+ /* Get a value which is small but not insignificant relative the path. */
+ epsilon = 1E-7;
+
+ x0 = xp[0] - x;
+ y0 = yp[0] - y;
+ for (int i = 1; i < npoints; i++)
+ {
+ x1 = xp[i] - x;
+ y1 = yp[i] - y;
+
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y1 == 0.0)
+ y1 -= epsilon;
+ if (y0 * y1 < 0)
+ if (Line2D.linesIntersect(x0, y0, x1, y1, epsilon, 0.0, distance, 0.0))
+ ++crossings;
+
+ x0 = xp[i] - x;
+ y0 = yp[i] - y;
+ }
+
+ // end segment
+ x1 = xp[0] - x;
+ y1 = yp[0] - y;
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y1 == 0.0)
+ y1 -= epsilon;
+ if (y0 * y1 < 0)
+ if (Line2D.linesIntersect(x0, y0, x1, y1, epsilon, 0.0, distance, 0.0))
+ ++crossings;
+
+ return crossings;
+ }
+} // class Polygon
+
diff --git a/libjava/classpath/java/awt/PopupMenu.java b/libjava/classpath/java/awt/PopupMenu.java
new file mode 100644
index 0000000..90d48d9
--- /dev/null
+++ b/libjava/classpath/java/awt/PopupMenu.java
@@ -0,0 +1,169 @@
+/* PopupMenu.java -- An AWT popup menu
+ Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.peer.PopupMenuPeer;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * This class implement an AWT popup menu widget
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class PopupMenu extends Menu
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization Constant
+private static final long serialVersionUID = -4620452533522760060L;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>PopupMenu</code>.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+public
+PopupMenu()
+{
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>PopupMenu</code> with the specified
+ * label.
+ *
+ * @param label The label for this popup menu.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+public
+PopupMenu(String label)
+{
+ super(label);
+
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Creates this object's native peer.
+ */
+public void
+addNotify()
+{
+ if (peer == null)
+ peer = getToolkit ().createPopupMenu (this);
+ super.addNotify ();
+}
+
+/*************************************************************************/
+
+/**
+ * Displays this popup menu at the specified coordinates relative to
+ * the specified component.
+ *
+ * @param component The component to which the display coordinates are relative.
+ * @param x The X coordinate of the menu.
+ * @param y The Y coordinate of the menu.
+ */
+public void
+show(Component component, int x, int y)
+{
+ if (getPeer() == null)
+ this.addNotify();
+ PopupMenuPeer pmp = (PopupMenuPeer)getPeer();
+ if (pmp != null)
+ {
+ /* XXX
+ Event e = new Event (component, Event.ACTION_EVENT, component);
+ e.x = x;
+ e.y = y;*/
+ pmp.show (component, x, y);
+ }
+}
+
+ protected class AccessibleAWTPopupMenu extends AccessibleAWTMenu
+ {
+ protected AccessibleAWTPopupMenu()
+ {
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.POPUP_MENU;
+ }
+
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>PopupMenu</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTPopupMenu();
+ return accessibleContext;
+ }
+
+} // class PopupMenu
+
diff --git a/libjava/classpath/java/awt/PrintGraphics.java b/libjava/classpath/java/awt/PrintGraphics.java
new file mode 100644
index 0000000..e7f8577
--- /dev/null
+++ b/libjava/classpath/java/awt/PrintGraphics.java
@@ -0,0 +1,57 @@
+/* PrintGraphics.java -- a print graphics context
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This interface allows the originating print job to be obtained.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public interface PrintGraphics
+{
+ /**
+ * Returns the <code>PrintJob</code> that this object is being
+ * managed by.
+ *
+ * @return the print job for this object
+ */
+ PrintJob getPrintJob();
+} // interface PrintGraphics
diff --git a/libjava/classpath/java/awt/PrintJob.java b/libjava/classpath/java/awt/PrintJob.java
new file mode 100644
index 0000000..62aa8b1
--- /dev/null
+++ b/libjava/classpath/java/awt/PrintJob.java
@@ -0,0 +1,104 @@
+/* PrintJob.java -- A print job class
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.util.Properties;
+
+/**
+ * This abstract class represents a print job.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see Toolkit#getPrintJob(Frame, String, Properties)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public abstract class PrintJob
+{
+ /**
+ * Create a new PrintJob.
+ */
+ public PrintJob()
+ {
+ }
+
+ /**
+ * Returns a graphics context suitable for rendering the next page. The
+ * return must also implement {@link PrintGraphics}.
+ *
+ * @return a graphics context for printing the next page
+ */
+ public abstract Graphics getGraphics();
+
+ /**
+ * Returns the dimension of the page in pixels. The resolution will be
+ * chosen to be similar to the on screen image.
+ *
+ * @return the page dimensions
+ */
+ public abstract Dimension getPageDimension();
+
+ /**
+ * Returns the resolution of the page in pixels per inch. Note that this is
+ * not necessarily the printer's resolution.
+ *
+ * @return the resolution of the page in pixels per inch
+ */
+ public abstract int getPageResolution();
+
+ /**
+ * Tests whether or not the last page will be printed first.
+ *
+ * @return true if the last page prints first
+ */
+ public abstract boolean lastPageFirst();
+
+ /**
+ * Informs the print job that printing is complete or should be aborted.
+ */
+ public abstract void end();
+
+ /**
+ * This method explicitly ends the print job in the event the job
+ * becomes un-referenced without the application having done so.
+ */
+ public void finalize()
+ {
+ end();
+ }
+} // class PrintJob
diff --git a/libjava/classpath/java/awt/Rectangle.java b/libjava/classpath/java/awt/Rectangle.java
new file mode 100644
index 0000000..0f21d49
--- /dev/null
+++ b/libjava/classpath/java/awt/Rectangle.java
@@ -0,0 +1,749 @@
+/* Rectangle.java -- represents a graphics rectangle
+ Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+
+/**
+ * This class represents a rectangle and all the interesting things you
+ * might want to do with it. Note that the coordinate system uses
+ * the origin (0,0) as the top left of the screen, with the x and y
+ * values increasing as they move to the right and down respectively.
+ *
+ * <p>It is valid for a rectangle to have negative width or height; but it
+ * is considered to have no area or internal points. Therefore, the behavior
+ * in methods like <code>contains</code> or <code>intersects</code> is
+ * undefined unless the rectangle has positive width and height.
+ *
+ * <p>There are some public fields; if you mess with them in an inconsistent
+ * manner, it is your own fault when you get NullPointerException,
+ * ArrayIndexOutOfBoundsException, or invalid results. Also, this class is
+ * not threadsafe.
+ *
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public class Rectangle extends Rectangle2D implements Shape, Serializable
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -4345857070255674764L;
+
+ /**
+ * The X coordinate of the top-left corner of the rectangle.
+ *
+ * @see #setLocation(int, int)
+ * @see #getLocation()
+ * @serial the x coordinate
+ */
+ public int x;
+
+ /**
+ * The Y coordinate of the top-left corner of the rectangle.
+ *
+ * @see #setLocation(int, int)
+ * @see #getLocation()
+ * @serial the y coordinate
+ */
+ public int y;
+
+ /**
+ * The width of the rectangle.
+ *
+ * @see #setSize(int, int)
+ * @see #getSize()
+ * @serial
+ */
+ public int width;
+
+ /**
+ * The height of the rectangle.
+ *
+ * @see #setSize(int, int)
+ * @see #getSize()
+ * @serial
+ */
+ public int height;
+
+ /**
+ * Initializes a new instance of <code>Rectangle</code> with a top
+ * left corner at (0,0) and a width and height of 0.
+ */
+ public Rectangle()
+ {
+ }
+
+ /**
+ * Initializes a new instance of <code>Rectangle</code> from the
+ * coordinates of the specified rectangle.
+ *
+ * @param r the rectangle to copy from
+ * @throws NullPointerException if r is null
+ * @since 1.1
+ */
+ public Rectangle(Rectangle r)
+ {
+ x = r.x;
+ y = r.y;
+ width = r.width;
+ height = r.height;
+ }
+
+ /**
+ * Initializes a new instance of <code>Rectangle</code> from the specified
+ * inputs.
+ *
+ * @param x the X coordinate of the top left corner
+ * @param y the Y coordinate of the top left corner
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ public Rectangle(int x, int y, int width, int height)
+ {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Initializes a new instance of <code>Rectangle</code> with the specified
+ * width and height. The upper left corner of the rectangle will be at
+ * the origin (0,0).
+ *
+ * @param width the width of the rectangle
+ * @param height the height of the rectange
+ */
+ public Rectangle(int width, int height)
+ {
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Initializes a new instance of <code>Rectangle</code> with a top-left
+ * corner represented by the specified point and the width and height
+ * represented by the specified dimension.
+ *
+ * @param p the upper left corner of the rectangle
+ * @param d the width and height of the rectangle
+ * @throws NullPointerException if p or d is null
+ */
+ public Rectangle(Point p, Dimension d)
+ {
+ x = p.x;
+ y = p.y;
+ width = d.width;
+ height = d.height;
+ }
+
+ /**
+ * Initializes a new instance of <code>Rectangle</code> with a top left
+ * corner at the specified point and a width and height of zero.
+ *
+ * @param p the upper left corner of the rectangle
+ */
+ public Rectangle(Point p)
+ {
+ x = p.x;
+ y = p.y;
+ }
+
+ /**
+ * Initializes a new instance of <code>Rectangle</code> with an
+ * upper left corner at the origin (0,0) and a width and height represented
+ * by the specified dimension.
+ *
+ * @param d the width and height of the rectangle
+ */
+ public Rectangle(Dimension d)
+ {
+ width = d.width;
+ height = d.height;
+ }
+
+ /**
+ * Get the X coordinate of the upper-left corner.
+ *
+ * @return the value of x, as a double
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Get the Y coordinate of the upper-left corner.
+ *
+ * @return the value of y, as a double
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Get the width of the rectangle.
+ *
+ * @return the value of width, as a double
+ */
+ public double getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Get the height of the rectangle.
+ *
+ * @return the value of height, as a double
+ */
+ public double getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Returns the bounds of this rectangle. A pretty useless method, as this
+ * is already a rectangle; it is included to mimic the
+ * <code>getBounds</code> method in Component.
+ *
+ * @return a copy of this rectangle
+ * @see #setBounds(Rectangle)
+ * @since 1.1
+ */
+ public Rectangle getBounds()
+ {
+ return new Rectangle(this);
+ }
+
+ /**
+ * Returns the high-precision bounds of this rectangle. A pretty useless
+ * method, as this is already a rectangle.
+ *
+ * @return a copy of this rectangle
+ * @see #setBounds(Rectangle)
+ * @since 1.2
+ */
+ public Rectangle2D getBounds2D()
+ {
+ return new Rectangle(x, y, width, height);
+ }
+
+ /**
+ * Updates this rectangle to match the dimensions of the specified
+ * rectangle.
+ *
+ * @param r the rectangle to update from
+ * @throws NullPointerException if r is null
+ * @see #setBounds(int, int, int, int)
+ * @since 1.1
+ */
+ public void setBounds(Rectangle r)
+ {
+ setBounds (r.x, r.y, r.width, r.height);
+ }
+
+ /**
+ * Updates this rectangle to have the specified dimensions.
+ *
+ * @param x the new X coordinate of the upper left hand corner
+ * @param y the new Y coordinate of the upper left hand corner
+ * @param width the new width of this rectangle
+ * @param height the new height of this rectangle
+ * @since 1.1
+ */
+ public void setBounds(int x, int y, int width, int height)
+ {
+ reshape (x, y, width, height);
+ }
+
+ /**
+ * Updates this rectangle to have the specified dimensions, as rounded to
+ * integers.
+ *
+ * @param x the new X coordinate of the upper left hand corner
+ * @param y the new Y coordinate of the upper left hand corner
+ * @param width the new width of this rectangle
+ * @param height the new height of this rectangle
+ * @since 1.2
+ */
+ public void setRect(double x, double y, double width, double height)
+ {
+ this.x = (int) x;
+ this.y = (int) y;
+ this.width = (int) width;
+ this.height = (int) height;
+ }
+
+ /**
+ * Updates this rectangle to have the specified dimensions.
+ *
+ * @param x the new X coordinate of the upper left hand corner
+ * @param y the new Y coordinate of the upper left hand corner
+ * @param width the new width of this rectangle
+ * @param height the new height of this rectangle
+ * @deprecated use {@link #setBounds(int, int, int, int)} instead
+ */
+ public void reshape(int x, int y, int width, int height)
+ {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Returns the location of this rectangle, which is the coordinates of
+ * its upper left corner.
+ *
+ * @return the point where this rectangle is located
+ * @see #setLocation(Point)
+ * @since 1.1
+ */
+ public Point getLocation()
+ {
+ return new Point(x,y);
+ }
+
+ /**
+ * Moves the location of this rectangle by setting its upper left
+ * corner to the specified point.
+ *
+ * @param p the point to move the rectangle to
+ * @throws NullPointerException if p is null
+ * @see #getLocation()
+ * @since 1.1
+ */
+ public void setLocation(Point p)
+ {
+ setLocation (p.x, p.y);
+ }
+
+ /**
+ * Moves the location of this rectangle by setting its upper left
+ * corner to the specified coordinates.
+ *
+ * @param x the new X coordinate for this rectangle
+ * @param y the new Y coordinate for this rectangle
+ * @since 1.1
+ */
+ public void setLocation(int x, int y)
+ {
+ move (x, y);
+ }
+
+ /**
+ * Moves the location of this rectangle by setting its upper left
+ * corner to the specified coordinates.
+ *
+ * @param x the new X coordinate for this rectangle
+ * @param y the new Y coordinate for this rectangle
+ * @deprecated use {@link #setLocation(int, int)} instead
+ */
+ public void move(int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Translate the location of this rectangle by the given amounts.
+ *
+ * @param dx the x distance to move by
+ * @param dy the y distance to move by
+ * @see #setLocation(int, int)
+ */
+ public void translate(int dx, int dy)
+ {
+ x += dx;
+ y += dy;
+ }
+
+ /**
+ * Returns the size of this rectangle.
+ *
+ * @return the size of this rectangle
+ * @see #setSize(Dimension)
+ * @since 1.1
+ */
+ public Dimension getSize()
+ {
+ return new Dimension(width, height);
+ }
+
+ /**
+ * Sets the size of this rectangle based on the specified dimensions.
+ *
+ * @param d the new dimensions of the rectangle
+ * @throws NullPointerException if d is null
+ * @see #getSize()
+ * @since 1.1
+ */
+ public void setSize(Dimension d)
+ {
+ setSize (d.width, d.height);
+ }
+
+ /**
+ * Sets the size of this rectangle based on the specified dimensions.
+ *
+ * @param width the new width of the rectangle
+ * @param height the new height of the rectangle
+ * @since 1.1
+ */
+ public void setSize(int width, int height)
+ {
+ resize (width, height);
+ }
+
+ /**
+ * Sets the size of this rectangle based on the specified dimensions.
+ *
+ * @param width the new width of the rectangle
+ * @param height the new height of the rectangle
+ * @deprecated use {@link #setSize(int, int)} instead
+ */
+ public void resize(int width, int height)
+ {
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Tests whether or not the specified point is inside this rectangle.
+ * According to the contract of Shape, a point on the border is in only if
+ * it has an adjacent point inside the rectangle in either the increasing
+ * x or y direction.
+ *
+ * @param p the point to test
+ * @return true if the point is inside the rectangle
+ * @throws NullPointerException if p is null
+ * @see #contains(int, int)
+ * @since 1.1
+ */
+ public boolean contains(Point p)
+ {
+ return contains (p.x, p.y);
+ }
+
+ /**
+ * Tests whether or not the specified point is inside this rectangle.
+ * According to the contract of Shape, a point on the border is in only if
+ * it has an adjacent point inside the rectangle in either the increasing
+ * x or y direction.
+ *
+ * @param x the X coordinate of the point to test
+ * @param y the Y coordinate of the point to test
+ * @return true if the point is inside the rectangle
+ * @since 1.1
+ */
+ public boolean contains(int x, int y)
+ {
+ return inside (x, y);
+ }
+
+ /**
+ * Checks whether all points in the given rectangle are contained in this
+ * rectangle.
+ *
+ * @param r the rectangle to check
+ * @return true if r is contained in this rectangle
+ * @throws NullPointerException if r is null
+ * @see #contains(int, int, int, int)
+ * @since 1.1
+ */
+ public boolean contains(Rectangle r)
+ {
+ return contains (r.x, r.y, r.width, r.height);
+ }
+
+ /**
+ * Checks whether all points in the given rectangle are contained in this
+ * rectangle.
+ *
+ * @param x the x coordinate of the rectangle to check
+ * @param y the y coordinate of the rectangle to check
+ * @param w the width of the rectangle to check
+ * @param h the height of the rectangle to check
+ * @return true if the parameters are contained in this rectangle
+ * @since 1.1
+ */
+ public boolean contains(int x, int y, int w, int h)
+ {
+ return width > 0 && height > 0 && w > 0 && h > 0
+ && x >= this.x && x + w <= this.x + this.width
+ && y >= this.y && y + h <= this.y + this.height;
+ }
+
+ /**
+ * Tests whether or not the specified point is inside this rectangle.
+ *
+ * @param x the X coordinate of the point to test
+ * @param y the Y coordinate of the point to test
+ * @return true if the point is inside the rectangle
+ * @deprecated use {@link #contains(int, int)} instead
+ */
+ public boolean inside(int x, int y)
+ {
+ return width > 0 && height > 0
+ && x >= this.x && x < this.x + width
+ && y >= this.y && y < this.y + height;
+ }
+
+ /**
+ * Tests whether or not the specified rectangle intersects this rectangle.
+ * This means the two rectangles share at least one internal point.
+ *
+ * @param r the rectangle to test against
+ * @return true if the specified rectangle intersects this one
+ * @throws NullPointerException if r is null
+ * @since 1.2
+ */
+ public boolean intersects(Rectangle r)
+ {
+ return r.width > 0 && r.height > 0 && width > 0 && height > 0
+ && r.x < x + width && r.x + r.width > x
+ && r.y < y + height && r.y + r.height > y;
+ }
+
+ /**
+ * Determines the rectangle which is formed by the intersection of this
+ * rectangle with the specified rectangle. If the two do not intersect,
+ * an empty rectangle will be returned (meaning the width and/or height
+ * will be non-positive).
+ *
+ * @param r the rectange to calculate the intersection with
+ * @return a new rectangle bounding the intersection
+ * @throws NullPointerException if r is null
+ */
+ public Rectangle intersection(Rectangle r)
+ {
+ Rectangle res = new Rectangle();
+ intersect(this, r, res);
+ return res;
+ }
+
+ /**
+ * Returns the smallest rectangle that contains both this rectangle
+ * and the specified rectangle.
+ *
+ * @param r the rectangle to compute the union with
+ * @return the smallest rectangle containing both rectangles
+ * @throws NullPointerException if r is null
+ */
+ public Rectangle union(Rectangle r)
+ {
+ Rectangle res = new Rectangle();
+ union(this, r, res);
+ return res;
+ }
+
+ /**
+ * Modifies this rectangle so that it represents the smallest rectangle
+ * that contains both the existing rectangle and the specified point.
+ * However, if the point falls on one of the two borders which are not
+ * inside the rectangle, a subsequent call to <code>contains</code> may
+ * return false.
+ *
+ * @param x the X coordinate of the point to add to this rectangle
+ * @param y the Y coordinate of the point to add to this rectangle
+ */
+ public void add(int x, int y)
+ {
+ add((double) x, (double) y);
+ }
+
+ /**
+ * Modifies this rectangle so that it represents the smallest rectangle
+ * that contains both the existing rectangle and the specified point.
+ * However, if the point falls on one of the two borders which are not
+ * inside the rectangle, a subsequent call to <code>contains</code> may
+ * return false.
+ *
+ * @param p the point to add to this rectangle
+ * @throws NullPointerException if p is null
+ */
+ public void add(Point p)
+ {
+ add((double) p.x, (double) p.y);
+ }
+
+ /**
+ * Modifies this rectangle so that it represents the smallest rectangle
+ * that contains both the existing rectangle and the specified rectangle.
+ *
+ * @param r the rectangle to add to this rectangle
+ * @throws NullPointerException if r is null
+ * @see #union(Rectangle)
+ */
+ public void add(Rectangle r)
+ {
+ union(this, r, this);
+ }
+
+ /**
+ * Expands the rectangle by the specified amount. The horizontal
+ * and vertical expansion values are applied both to the X,Y coordinate
+ * of this rectangle, and its width and height. Thus the width and
+ * height will increase by 2h and 2v accordingly.
+ *
+ * @param h the horizontal expansion value
+ * @param v the vertical expansion value
+ */
+ public void grow(int h, int v)
+ {
+ x -= h;
+ y -= v;
+ width += h + h;
+ height += v + v;
+ }
+
+ /**
+ * Tests whether or not this rectangle is empty. An empty rectangle
+ * has a non-positive width or height.
+ *
+ * @return true if the rectangle is empty
+ */
+ public boolean isEmpty()
+ {
+ return width <= 0 || height <= 0;
+ }
+
+ /**
+ * Determine where the point lies with respect to this rectangle. The
+ * result will be the binary OR of the appropriate bit masks.
+ *
+ * @param x the x coordinate to check
+ * @param y the y coordinate to check
+ * @return the binary OR of the result
+ * @see #OUT_LEFT
+ * @see #OUT_TOP
+ * @see #OUT_RIGHT
+ * @see #OUT_BOTTOM
+ * @since 1.2
+ */
+ public int outcode(double x, double y)
+ {
+ int result = 0;
+ if (width <= 0)
+ result |= OUT_LEFT | OUT_RIGHT;
+ else if (x < this.x)
+ result |= OUT_LEFT;
+ else if (x > this.x + width)
+ result |= OUT_RIGHT;
+ if (height <= 0)
+ result |= OUT_BOTTOM | OUT_TOP;
+ else if (y < this.y) // Remember that +y heads top-to-bottom.
+ result |= OUT_TOP;
+ else if (y > this.y + height)
+ result |= OUT_BOTTOM;
+ return result;
+ }
+
+ /**
+ * Determines the rectangle which is formed by the intersection of this
+ * rectangle with the specified rectangle. If the two do not intersect,
+ * an empty rectangle will be returned (meaning the width and/or height
+ * will be non-positive).
+ *
+ * @param r the rectange to calculate the intersection with
+ * @return a new rectangle bounding the intersection
+ * @throws NullPointerException if r is null
+ * @since 1.2
+ */
+ public Rectangle2D createIntersection(Rectangle2D r)
+ {
+ // Favor runtime type of other rectangle.
+ Rectangle2D res = r.getBounds2D();
+ intersect(this, r, res);
+ return res;
+ }
+
+ /**
+ * Returns the smallest rectangle that contains both this rectangle
+ * and the specified rectangle.
+ *
+ * @param r the rectangle to compute the union with
+ * @return the smallest rectangle containing both rectangles
+ * @throws NullPointerException if r is null
+ * @since 1.2
+ */
+ public Rectangle2D createUnion(Rectangle2D r)
+ {
+ // Favor runtime type of other rectangle.
+ Rectangle2D res = r.getBounds2D();
+ union(this, r, res);
+ return res;
+ }
+
+ /**
+ * Tests this rectangle for equality against the specified object. This
+ * will be true if an only if the specified object is an instance of
+ * Rectangle2D with the same coordinates and dimensions.
+ *
+ * @param obj the object to test against for equality
+ * @return true if the specified object is equal to this one
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof Rectangle2D))
+ return false;
+ Rectangle2D r = (Rectangle2D) obj;
+ return r.getX() == x && r.getY() == y
+ && r.getWidth() == width && r.getHeight() == height;
+ }
+
+ /**
+ * Returns a string representation of this rectangle. This is in the form
+ * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width
+ * + ",height=" + height + ']'</code>.
+ *
+ * @return a string representation of this rectangle
+ */
+ public String toString()
+ {
+ return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width
+ + ",height=" + height + ']';
+ }
+} // class Rectangle
diff --git a/libjava/classpath/java/awt/RenderingHints.java b/libjava/classpath/java/awt/RenderingHints.java
new file mode 100644
index 0000000..0e1db72
--- /dev/null
+++ b/libjava/classpath/java/awt/RenderingHints.java
@@ -0,0 +1,803 @@
+/* RenderingHints.java --
+ Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A collection of (key, value) items that provide 'hints' for the
+ * {@link java.awt.Graphics2D} rendering pipeline. Because these
+ * items are hints only, they may be ignored by a particular
+ * {@link java.awt.Graphics2D} implementation.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+public class RenderingHints implements Map, Cloneable
+{
+ /**
+ * The base class used to represent keys.
+ */
+ public abstract static class Key
+ {
+ private final int key;
+
+ /**
+ * Creates a new key.
+ *
+ * @param privateKey the private key.
+ */
+ protected Key(int privateKey)
+ {
+ key = privateKey;
+ }
+
+ /**
+ * Returns <code>true</code> if the specified value is compatible with
+ * this key, and <code>false</code> otherwise.
+ *
+ * @param value the value (<code>null</code> permitted).
+ *
+ * @return A boolean.
+ */
+ public abstract boolean isCompatibleValue(Object value);
+
+ /**
+ * Returns the private key for this instance.
+ *
+ * @return The private key.
+ */
+ protected final int intKey()
+ {
+ return key;
+ }
+
+ /**
+ * Returns a hash code for the key.
+ *
+ * @return A hash code.
+ */
+ public final int hashCode()
+ {
+ return System.identityHashCode(this);
+ }
+
+ /**
+ * Checks this key for equality with an arbitrary object.
+ *
+ * @param other the object (<code>null</code> permitted)
+ *
+ * @return A boolean.
+ */
+ public final boolean equals(Object other)
+ {
+ return this == other;
+ }
+ } // class Key
+
+ private static final class KeyImpl extends Key
+ {
+ final String description;
+ final Object v1;
+ final Object v2;
+ final Object v3;
+
+ KeyImpl(int privateKey, String description,
+ Object v1, Object v2, Object v3)
+ {
+ super(privateKey);
+ this.description = description;
+ this.v1 = v1;
+ this.v2 = v2;
+ this.v3 = v3;
+ }
+
+ /**
+ * Returns <code>true</code> if the specified value is compatible with
+ * this key, and <code>false</code> otherwise.
+ *
+ * @param value the value (<code>null</code> permitted).
+ *
+ * @return A boolean.
+ */
+ public boolean isCompatibleValue(Object value)
+ {
+ return value == v1 || value == v2 || value == v3;
+ }
+
+ /**
+ * Returns a string representation of the key.
+ *
+ * @return A string.
+ */
+ public String toString()
+ {
+ return description;
+ }
+ } // class KeyImpl
+
+ private HashMap hintMap = new HashMap();
+
+ /**
+ * A key for the 'antialiasing' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_ANTIALIAS_OFF}</td>
+ * <td>Render without antialiasing (better speed).</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_ANTIALIAS_ON}</td>
+ * <td>Render with antialiasing (better quality).</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_ANTIALIAS_DEFAULT}</td>
+ * <td>Use the default value for antialiasing.</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_ANTIALIASING;
+
+ /**
+ * This value is for use with the {@link #KEY_ANTIALIASING} key.
+ */
+ public static final Object VALUE_ANTIALIAS_ON
+ = "Antialiased rendering mode";
+
+ /**
+ * This value is for use with the {@link #KEY_ANTIALIASING} key.
+ */
+ public static final Object VALUE_ANTIALIAS_OFF
+ = "Nonantialiased rendering mode";
+
+ /**
+ * This value is for use with the {@link #KEY_ANTIALIASING} key.
+ */
+ public static final Object VALUE_ANTIALIAS_DEFAULT
+ = "Default antialiasing rendering mode";
+
+ /**
+ * A key for the 'rendering' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_RENDER_SPEED}</td>
+ * <td>Prefer speed over quality when rendering.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_RENDER_QUALITY}</td>
+ * <td>Prefer quality over speed when rendering.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_RENDER_DEFAULT}</td>
+ * <td>Use the default value for quality vs. speed when rendering.</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_RENDERING;
+
+ /**
+ * This value is for use with the {@link #KEY_RENDERING} key.
+ */
+ public static final Object VALUE_RENDER_SPEED
+ = "Fastest rendering methods";
+
+ /**
+ * This value is for use with the {@link #KEY_RENDERING} key.
+ */
+ public static final Object VALUE_RENDER_QUALITY
+ = "Highest quality rendering methods";
+
+ /**
+ * This value is for use with the {@link #KEY_RENDERING} key.
+ */
+ public static final Object VALUE_RENDER_DEFAULT
+ = "Default rendering methods";
+
+ /**
+ * A key for the 'dithering' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_DITHER_DISABLE}</td>
+ * <td>Disable dithering.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_DITHER_ENABLE}</td>
+ * <td>Enable dithering.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_DITHER_DEFAULT}</td>
+ * <td>Use the default value for dithering.</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_DITHERING;
+
+ /**
+ * This value is for use with the {@link #KEY_DITHERING} key.
+ */
+ public static final Object VALUE_DITHER_DISABLE
+ = "Nondithered rendering mode";
+
+ /**
+ * This value is for use with the {@link #KEY_DITHERING} key.
+ */
+ public static final Object VALUE_DITHER_ENABLE
+ = "Dithered rendering mode";
+
+ /**
+ * This value is for use with the {@link #KEY_DITHERING} key.
+ */
+ public static final Object VALUE_DITHER_DEFAULT
+ = "Default dithering mode";
+
+ /**
+ * A key for the 'text antialiasing' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_TEXT_ANTIALIAS_ON}</td>
+ * <td>Render text with antialiasing (better quality usually).</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_TEXT_ANTIALIAS_OFF}</td>
+ * <td>Render test without antialiasing (better speed).</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_TEXT_ANTIALIAS_DEFAULT}</td>
+ * <td>Use the default value for text antialiasing.</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_TEXT_ANTIALIASING;
+
+ /**
+ * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
+ */
+ public static final Object VALUE_TEXT_ANTIALIAS_ON
+ = "Antialiased text mode";
+
+ /**
+ * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
+ */
+ public static final Object VALUE_TEXT_ANTIALIAS_OFF
+ = "Nonantialiased text mode";
+
+ /**
+ * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
+ */
+ public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT
+ = "Default antialiasing text mode";
+
+ /**
+ * A key for the 'fractional metrics' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_FRACTIONALMETRICS_OFF}</td>
+ * <td>Render text with fractional metrics off.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_FRACTIONALMETRICS_ON}</td>
+ * <td>Render text with fractional metrics on.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_FRACTIONALMETRICS_DEFAULT}</td>
+ * <td>Use the default value for fractional metrics.</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_FRACTIONALMETRICS;
+
+ /**
+ * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
+ */
+ public static final Object VALUE_FRACTIONALMETRICS_OFF
+ = "Integer text metrics mode";
+
+ /**
+ * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
+ */
+ public static final Object VALUE_FRACTIONALMETRICS_ON
+ = "Fractional text metrics mode";
+
+ /**
+ * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
+ */
+ public static final Object VALUE_FRACTIONALMETRICS_DEFAULT
+ = "Default fractional text metrics mode";
+
+ /**
+ * A key for the 'interpolation' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_INTERPOLATION_NEAREST_NEIGHBOR}</td>
+ * <td>Use nearest neighbour interpolation.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_INTERPOLATION_BILINEAR}</td>
+ * <td>Use bilinear interpolation.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_INTERPOLATION_BICUBIC}</td>
+ * <td>Use bicubic interpolation.</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_INTERPOLATION;
+
+ /**
+ * This value is for use with the {@link #KEY_INTERPOLATION} key.
+ */
+ public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR
+ = "Nearest Neighbor image interpolation mode";
+
+ /**
+ * This value is for use with the {@link #KEY_INTERPOLATION} key.
+ */
+ public static final Object VALUE_INTERPOLATION_BILINEAR
+ = "Bilinear image interpolation mode";
+
+ /**
+ * This value is for use with the {@link #KEY_INTERPOLATION} key.
+ */
+ public static final Object VALUE_INTERPOLATION_BICUBIC
+ = "Bicubic image interpolation mode";
+
+ /**
+ * A key for the 'alpha interpolation' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_ALPHA_INTERPOLATION_SPEED}</td>
+ * <td>Prefer speed over quality.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_ALPHA_INTERPOLATION_QUALITY}</td>
+ * <td>Prefer quality over speed.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_ALPHA_INTERPOLATION_DEFAULT}</td>
+ * <td>Use the default setting.</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_ALPHA_INTERPOLATION;
+
+ /**
+ * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
+ */
+ public static final Object VALUE_ALPHA_INTERPOLATION_SPEED
+ = "Fastest alpha blending methods";
+
+ /**
+ * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
+ */
+ public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY
+ = "Highest quality alpha blending methods";
+
+ /**
+ * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
+ */
+ public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT
+ = "Default alpha blending methods";
+
+ /**
+ * A key for the 'color rendering' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_COLOR_RENDER_SPEED}</td>
+ * <td>Prefer speed over quality.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_COLOR_RENDER_QUALITY}</td>
+ * <td>Prefer quality over speed.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_COLOR_RENDER_DEFAULT}</td>
+ * <td>Use the default setting.</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_COLOR_RENDERING;
+
+ /**
+ * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
+ */
+ public static final Object VALUE_COLOR_RENDER_SPEED
+ = "Fastest color rendering mode";
+
+ /**
+ * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
+ */
+ public static final Object VALUE_COLOR_RENDER_QUALITY
+ = "Highest quality color rendering mode";
+
+ /**
+ * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
+ */
+ public static final Object VALUE_COLOR_RENDER_DEFAULT
+ = "Default color rendering mode";
+
+ /**
+ * A key for the 'stroke control' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_STROKE_DEFAULT}</td>
+ * <td>Use the default setting.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_STROKE_NORMALIZE}</td>
+ * <td>XXX</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_STROKE_PURE}</td>
+ * <td>XXX</td>
+ * </tr>
+ * </table>
+ */
+ public static final Key KEY_STROKE_CONTROL;
+
+ /**
+ * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
+ */
+ public static final Object VALUE_STROKE_DEFAULT
+ = "Default stroke normalization";
+
+ /**
+ * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
+ */
+ public static final Object VALUE_STROKE_NORMALIZE
+ = "Normalize strokes for consistent rendering";
+
+ /**
+ * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
+ */
+ public static final Object VALUE_STROKE_PURE
+ = "Pure stroke conversion for accurate paths";
+
+ static
+ {
+ KEY_ANTIALIASING = new KeyImpl(1, "Global antialiasing enable key",
+ VALUE_ANTIALIAS_ON,
+ VALUE_ANTIALIAS_OFF,
+ VALUE_ANTIALIAS_DEFAULT);
+ KEY_RENDERING = new KeyImpl(2, "Global rendering quality key",
+ VALUE_RENDER_SPEED,
+ VALUE_RENDER_QUALITY,
+ VALUE_RENDER_DEFAULT);
+ KEY_DITHERING = new KeyImpl(3, "Dithering quality key",
+ VALUE_DITHER_DISABLE,
+ VALUE_DITHER_ENABLE,
+ VALUE_DITHER_DEFAULT);
+ KEY_TEXT_ANTIALIASING
+ = new KeyImpl(4, "Text-specific antialiasing enable key",
+ VALUE_TEXT_ANTIALIAS_ON,
+ VALUE_TEXT_ANTIALIAS_OFF,
+ VALUE_TEXT_ANTIALIAS_DEFAULT);
+ KEY_FRACTIONALMETRICS = new KeyImpl(5, "Fractional metrics enable key",
+ VALUE_FRACTIONALMETRICS_OFF,
+ VALUE_FRACTIONALMETRICS_ON,
+ VALUE_FRACTIONALMETRICS_DEFAULT);
+ KEY_INTERPOLATION = new KeyImpl(6, "Image interpolation method key",
+ VALUE_INTERPOLATION_NEAREST_NEIGHBOR,
+ VALUE_INTERPOLATION_BILINEAR,
+ VALUE_INTERPOLATION_BICUBIC);
+ KEY_ALPHA_INTERPOLATION
+ = new KeyImpl(7, "Alpha blending interpolation method key",
+ VALUE_ALPHA_INTERPOLATION_SPEED,
+ VALUE_ALPHA_INTERPOLATION_QUALITY,
+ VALUE_ALPHA_INTERPOLATION_DEFAULT);
+ KEY_COLOR_RENDERING = new KeyImpl(8, "Color rendering quality key",
+ VALUE_COLOR_RENDER_SPEED,
+ VALUE_COLOR_RENDER_QUALITY,
+ VALUE_COLOR_RENDER_DEFAULT);
+ KEY_STROKE_CONTROL = new KeyImpl(9, "Stroke normalization control key",
+ VALUE_STROKE_DEFAULT,
+ VALUE_STROKE_NORMALIZE,
+ VALUE_STROKE_PURE);
+ }
+
+ /**
+ * Creates a new collection of hints containing all the (key, value) pairs
+ * in the specified map.
+ *
+ * @param init a map containing a collection of hints (<code>null</code>
+ * permitted).
+ */
+ public RenderingHints(Map init)
+ {
+ if (init != null)
+ putAll(init);
+ }
+
+ /**
+ * Creates a new collection containing a single (key, value) pair.
+ *
+ * @param key the key.
+ * @param value the value.
+ */
+ public RenderingHints(Key key, Object value)
+ {
+ put(key, value);
+ }
+
+ /**
+ * Returns the number of hints in the collection.
+ *
+ * @return The number of hints.
+ */
+ public int size()
+ {
+ return hintMap.size();
+ }
+
+ /**
+ * Returns <code>true</code> if there are no hints in the collection,
+ * and <code>false</code> otherwise.
+ *
+ * @return A boolean.
+ */
+ public boolean isEmpty()
+ {
+ return hintMap.isEmpty();
+ }
+
+ /**
+ * Returns <code>true</code> if the collection of hints contains the
+ * specified key, and <code>false</code> otherwise.
+ *
+ * @param key the key (<code>null</code> not permitted).
+ *
+ * @return A boolean.
+ *
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws ClassCastException if <code>key</code> is not a {@link Key}.
+ */
+ public boolean containsKey(Object key)
+ {
+ if (key == null)
+ throw new NullPointerException();
+ // don't remove the cast, it is necessary to throw the required exception
+ return hintMap.containsKey((Key) key);
+ }
+
+ /**
+ * Returns <code>true</code> if the collection of hints contains the
+ * specified value, and <code>false</code> otherwise.
+ *
+ * @param value the value.
+ *
+ * @return A boolean.
+ */
+ public boolean containsValue(Object value)
+ {
+ return hintMap.containsValue(value);
+ }
+
+ /**
+ * Returns the value associated with the specified key, or <code>null</code>
+ * if there is no value defined for the key.
+ *
+ * @param key the key (<code>null</code> permitted).
+ *
+ * @return The value (possibly <code>null</code>).
+ *
+ * @throws ClassCastException if <code>key</code> is not a {@link Key}.
+ *
+ * @see #containsKey(Object)
+ */
+ public Object get(Object key)
+ {
+ // don't remove the cast, it is necessary to throw the required exception
+ return hintMap.get((Key) key);
+ }
+
+ /**
+ * Adds a (key, value) pair to the collection of hints (if the
+ * collection already contains the specified key, then the
+ * value is updated).
+ *
+ * @param key the key.
+ * @param value the value.
+ *
+ * @return the previous value of the key or <code>null</code> if the key
+ * didn't have a value yet.
+ */
+ public Object put(Object key, Object value)
+ {
+ if (key == null || value == null)
+ throw new NullPointerException();
+ if (! ((Key) key).isCompatibleValue(value))
+ throw new IllegalArgumentException();
+ return hintMap.put(key, value);
+ }
+
+ /**
+ * Adds all the hints from a collection to this collection.
+ *
+ * @param hints the hint collection.
+ */
+ public void add(RenderingHints hints)
+ {
+ hintMap.putAll(hints);
+ }
+
+ /**
+ * Clears all the hints from this collection.
+ */
+ public void clear()
+ {
+ hintMap.clear();
+ }
+
+ /**
+ * Removes a hint from the collection.
+ *
+ * @param key the key.
+ *
+ * @return The value that was associated with the key, or <code>null</code> if
+ * the key was not part of the collection
+ *
+ * @throws ClassCastException if the key is not a subclass of
+ * {@link RenderingHints.Key}.
+ */
+ public Object remove(Object key)
+ {
+ // don't remove the (Key) cast, it is necessary to throw the exception
+ // required by the spec
+ return hintMap.remove((Key) key);
+ }
+
+ /**
+ * Adds a collection of (key, value) pairs to the collection.
+ *
+ * @param m a map containing (key, value) items.
+ *
+ * @throws ClassCastException if the map contains a key that is not
+ * a subclass of {@link RenderingHints.Key}.
+ * @throws IllegalArgumentException if the map contains a value that is
+ * not compatible with its key.
+ */
+ public void putAll(Map m)
+ {
+ // preprocess map to generate appropriate exceptions
+ Iterator iterator = m.keySet().iterator();
+ while (iterator.hasNext())
+ {
+ Key key = (Key) iterator.next();
+ if (!key.isCompatibleValue(m.get(key)))
+ throw new IllegalArgumentException();
+ }
+ // map is OK, update
+ hintMap.putAll(m);
+ }
+
+ /**
+ * Returns a set containing the keys from this collection.
+ *
+ * @return A set of keys.
+ */
+ public Set keySet()
+ {
+ return hintMap.keySet();
+ }
+
+ /**
+ * Returns a collection of the values from this hint collection. The
+ * collection is backed by the <code>RenderingHints</code> instance,
+ * so updates to one will affect the other.
+ *
+ * @return A collection of values.
+ */
+ public Collection values()
+ {
+ return hintMap.values();
+ }
+
+ /**
+ * Returns a set of entries from the collection.
+ *
+ * @return A set of entries.
+ */
+ public Set entrySet()
+ {
+ return Collections.unmodifiableSet(hintMap.entrySet());
+ }
+
+ /**
+ * Checks this collection for equality with an arbitrary object.
+ *
+ * @param o the object (<code>null</code> permitted)
+ *
+ * @return A boolean.
+ */
+ public boolean equals(Object o)
+ {
+ return hintMap.equals(o);
+ }
+
+ /**
+ * Returns a hash code for the collection of hints.
+ *
+ * @return A hash code.
+ */
+ public int hashCode()
+ {
+ return hintMap.hashCode();
+ }
+
+ /**
+ * Creates a clone of this instance.
+ *
+ * @return A clone.
+ */
+ public Object clone()
+ {
+ try
+ {
+ RenderingHints copy = (RenderingHints) super.clone();
+ copy.hintMap = (HashMap) hintMap.clone();
+ return copy;
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+
+ /**
+ * Returns a string representation of this instance.
+ *
+ * @return A string.
+ */
+ public String toString()
+ {
+ return hintMap.toString();
+ }
+} // class RenderingHints
diff --git a/libjava/classpath/java/awt/Robot.java b/libjava/classpath/java/awt/Robot.java
new file mode 100644
index 0000000..485a14e
--- /dev/null
+++ b/libjava/classpath/java/awt/Robot.java
@@ -0,0 +1,423 @@
+/* Robot.java -- a native input event generator
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import gnu.java.awt.ClasspathToolkit;
+
+import java.lang.reflect.InvocationTargetException;
+import java.awt.event.InputEvent;
+import java.awt.image.BufferedImage;
+import java.awt.peer.RobotPeer;
+
+/**
+ * The Robot class is used to simulate user interaction with graphical
+ * programs. It can generate native windowing system input events and
+ * retrieve image data from the current screen. Robot is used to test
+ * the AWT and Swing library implementations; it can also be used to
+ * create self-running demo programs.
+ *
+ * Since Robot generates native windowing system events, rather than
+ * simply inserting {@link AWTEvent}s on the AWT event queue, its use
+ * is not restricted to Java programs. It can be used to
+ * programatically drive any graphical application.
+ *
+ * This implementation requires an X server that supports the XTest
+ * extension.
+ *
+ * @author Thomas Fitzsimmons (fitzsim@redhat.com)
+ *
+ * @since 1.3
+ */
+public class Robot
+{
+ private boolean waitForIdle;
+ private int autoDelay;
+ private RobotPeer peer;
+
+ /**
+ * Construct a Robot object that operates on the default screen.
+ *
+ * @exception AWTException if GraphicsEnvironment.isHeadless()
+ * returns true or if the X server does not support the XTest
+ * extension
+ * @exception SecurityException if createRobot permission is not
+ * granted
+ */
+ public Robot () throws AWTException
+ {
+ if (GraphicsEnvironment.isHeadless ())
+ throw new AWTException ("Robot: headless graphics environment");
+
+ SecurityManager sm = System.getSecurityManager ();
+ if (sm != null)
+ sm.checkPermission (new AWTPermission ("createRobot"));
+
+ ClasspathToolkit tk = (ClasspathToolkit) Toolkit.getDefaultToolkit ();
+
+ // createRobot will throw AWTException if XTest is not supported.
+ peer = tk.createRobot (GraphicsEnvironment.getLocalGraphicsEnvironment ()
+ .getDefaultScreenDevice ());
+ }
+
+ /**
+ * Construct a Robot object that operates on the specified screen.
+ *
+ * @exception AWTException if GraphicsEnvironment.isHeadless()
+ * returns true or if the X server does not support the XTest
+ * extension
+ * @exception IllegalArgumentException if screen is not a screen
+ * GraphicsDevice
+ * @exception SecurityException if createRobot permission is not
+ * granted
+ */
+ public Robot (GraphicsDevice screen) throws AWTException
+ {
+ if (GraphicsEnvironment.isHeadless ())
+ throw new AWTException ("Robot: headless graphics environment");
+
+ if (screen.getType () != GraphicsDevice.TYPE_RASTER_SCREEN)
+ throw new IllegalArgumentException ("Robot: graphics"
+ + " device is not a screen");
+
+ SecurityManager sm = System.getSecurityManager ();
+ if (sm != null)
+ sm.checkPermission (new AWTPermission ("createRobot"));
+
+ ClasspathToolkit tk = (ClasspathToolkit) Toolkit.getDefaultToolkit ();
+
+ // createRobot will throw AWTException if XTest is not supported.
+ peer = tk.createRobot (screen);
+ }
+
+ /**
+ * Move the mouse pointer to absolute coordinates (x, y).
+ *
+ * @param x the destination x coordinate
+ * @param y the destination y coordinate
+ */
+ public void mouseMove(int x, int y)
+ {
+ peer.mouseMove (x, y);
+
+ if (waitForIdle)
+ waitForIdle ();
+
+ if (autoDelay > 0)
+ delay (autoDelay);
+ }
+
+ /**
+ * Press one or more mouse buttons.
+ *
+ * @param buttons the buttons to press; a bitmask of one or more of
+ * these {@link InputEvent} fields:
+ *
+ * <ul>
+ * <li>BUTTON1_MASK</li>
+ * <li>BUTTON2_MASK</li>
+ * <li>BUTTON3_MASK</li>
+ * </ul>
+ *
+ * @exception IllegalArgumentException if the button mask is invalid
+ */
+ public void mousePress (int buttons)
+ {
+ if ((buttons & InputEvent.BUTTON1_MASK) == 0
+ && (buttons & InputEvent.BUTTON2_MASK) == 0
+ && (buttons & InputEvent.BUTTON3_MASK) == 0)
+ throw new IllegalArgumentException ("Robot: mousePress:"
+ + " invalid button mask");
+
+ peer.mousePress (buttons);
+
+ if (waitForIdle)
+ waitForIdle ();
+
+ if (autoDelay > 0)
+ delay (autoDelay);
+ }
+
+ /**
+ * Release one or more mouse buttons.
+ *
+ * @param buttons the buttons to release; a bitmask of one or more
+ * of these {@link InputEvent} fields:
+ *
+ * <ul>
+ * <li>BUTTON1_MASK</li>
+ * <li>BUTTON2_MASK</li>
+ * <li>BUTTON3_MASK</li>
+ * </ul>
+ *
+ * @exception IllegalArgumentException if the button mask is invalid
+ */
+ public void mouseRelease(int buttons)
+ {
+ if ((buttons & InputEvent.BUTTON1_MASK) == 0
+ && (buttons & InputEvent.BUTTON2_MASK) == 0
+ && (buttons & InputEvent.BUTTON3_MASK) == 0)
+ throw new IllegalArgumentException ("Robot: mouseRelease:"
+ + " invalid button mask");
+
+ peer.mouseRelease (buttons);
+
+ if (waitForIdle)
+ waitForIdle ();
+
+ if (autoDelay > 0)
+ delay (autoDelay);
+ }
+
+ /**
+ * Rotate the mouse scroll wheel.
+ *
+ * @param wheelAmt number of steps to rotate mouse wheel. negative
+ * to rotate wheel up (away from the user), positive to rotate wheel
+ * down (toward the user).
+ *
+ * @since 1.4
+ */
+ public void mouseWheel (int wheelAmt)
+ {
+ peer.mouseWheel (wheelAmt);
+
+ if (waitForIdle)
+ waitForIdle ();
+
+ if (autoDelay > 0)
+ delay (autoDelay);
+ }
+
+ /**
+ * Press a key.
+ *
+ * @param keycode key to press, a {@link java.awt.event.KeyEvent} VK_ constant
+ *
+ * @exception IllegalArgumentException if keycode is not a valid key
+ */
+ public void keyPress (int keycode)
+ {
+ peer.keyPress (keycode);
+
+ if (waitForIdle)
+ waitForIdle ();
+
+ if (autoDelay > 0)
+ delay (autoDelay);
+ }
+
+ /**
+ * Release a key.
+ *
+ * @param keycode key to release, a {@link java.awt.event.KeyEvent} VK_
+ * constant
+ *
+ * @exception IllegalArgumentException if keycode is not a valid key
+ */
+ public void keyRelease (int keycode)
+ {
+ peer.keyRelease (keycode);
+
+ if (waitForIdle)
+ waitForIdle ();
+
+ if (autoDelay > 0)
+ delay (autoDelay);
+ }
+
+ /**
+ * Return the color of the pixel at the given screen coordinates.
+ *
+ * @param x the x coordinate of the pixel
+ * @param y the y coordinate of the pixel
+ *
+ * @return the Color of the pixel at screen coodinates <code>(x, y)</code>
+ */
+ public Color getPixelColor (int x, int y)
+ {
+ return new Color (peer.getRGBPixel (x, y));
+ }
+
+ /**
+ * Create an image containing pixels read from the screen. The
+ * image does not include the mouse pointer.
+ *
+ * @param screenRect the rectangle of pixels to capture, in screen
+ * coordinates
+ *
+ * @return a BufferedImage containing the requested pixels
+ *
+ * @exception IllegalArgumentException if requested width and height
+ * are not both greater than zero
+ * @exception SecurityException if readDisplayPixels permission is
+ * not granted
+ */
+ public BufferedImage createScreenCapture (Rectangle screenRect)
+ {
+ if (screenRect.width <= 0)
+ throw new IllegalArgumentException ("Robot: capture width is <= 0");
+
+ if (screenRect.height <= 0)
+ throw new IllegalArgumentException ("Robot: capture height is <= 0");
+
+ SecurityManager sm = System.getSecurityManager ();
+ if (sm != null)
+ sm.checkPermission (new AWTPermission ("readDisplayPixels"));
+
+ int[] pixels = peer.getRGBPixels (screenRect);
+
+ BufferedImage bufferedImage =
+ new BufferedImage (screenRect.width, screenRect.height,
+ BufferedImage.TYPE_INT_ARGB);
+
+ bufferedImage.setRGB (0, 0, screenRect.width, screenRect.height,
+ pixels, 0, screenRect.width);
+
+ return bufferedImage;
+ }
+
+ /**
+ * Check if this Robot automatically calls {@link #waitForIdle()} after
+ * generating an event.
+ *
+ * @return true if waitForIdle is automatically called
+ */
+ public boolean isAutoWaitForIdle ()
+ {
+ return waitForIdle;
+ }
+
+ /**
+ * Set whether or not this Robot automatically calls {@link
+ * #waitForIdle()} after generating an event.
+ *
+ * @param isOn true if waitForIdle should be called automatically
+ */
+ public void setAutoWaitForIdle (boolean isOn)
+ {
+ waitForIdle = isOn;
+ }
+
+ /**
+ * Retrieve the length of time this Robot sleeps after generating an
+ * event.
+ *
+ * @return the length of time in milliseconds
+ */
+ public int getAutoDelay ()
+ {
+ return autoDelay;
+ }
+
+ /**
+ * Set the length of time this Robot sleeps after generating an
+ * event.
+ *
+ * @param ms the length of time in milliseconds
+ *
+ * @exception IllegalArgumentException if ms is not between 0 and
+ * 60,000 milliseconds inclusive
+ */
+ public void setAutoDelay (int ms)
+ {
+ if (ms <= 0 || ms >= 60000)
+ throw new IllegalArgumentException ("Robot: delay length out-of-bounds");
+
+ autoDelay = ms;
+ }
+
+ /**
+ * Sleep for a specified length of time.
+ *
+ * @param ms the length of time in milliseconds
+ *
+ * @exception IllegalArgumentException if ms is not between 0 and
+ * 60,000 milliseconds inclusive
+ */
+ public void delay (int ms)
+ {
+ if (ms < 0 || ms > 60000)
+ throw new IllegalArgumentException ("Robot: delay length out-of-bounds");
+
+ try
+ {
+ Thread.sleep (ms);
+ }
+ catch (InterruptedException e)
+ {
+ System.err.println ("Robot: delay interrupted");
+ }
+ }
+
+ /**
+ * Wait until all events currently on the event queue have been
+ * dispatched.
+ */
+ public void waitForIdle ()
+ {
+ if (EventQueue.isDispatchThread ())
+ throw new IllegalThreadStateException ("Robot: waitForIdle called from "
+ + "the event dispatch thread");
+
+ try
+ {
+ EventQueue.invokeAndWait (new Runnable () { public void run () { } });
+ }
+ catch (InterruptedException e)
+ {
+ System.err.println ("Robot: waitForIdle interrupted");
+ }
+ catch (InvocationTargetException e)
+ {
+ System.err.println ("Robot: waitForIdle cannot invoke target");
+ }
+ }
+
+ /**
+ * Return a string representation of this Robot.
+ *
+ * @return a string representation
+ */
+ public String toString ()
+ {
+ return getClass ().getName ()
+ + "[ autoDelay = " + autoDelay + ", autoWaitForIdle = "
+ + waitForIdle + " ]";
+ }
+}
diff --git a/libjava/classpath/java/awt/ScrollPane.java b/libjava/classpath/java/awt/ScrollPane.java
new file mode 100644
index 0000000..b3ecc59
--- /dev/null
+++ b/libjava/classpath/java/awt/ScrollPane.java
@@ -0,0 +1,615 @@
+/* ScrollPane.java -- Scrolling window
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.MouseEvent;
+import java.awt.peer.ComponentPeer;
+import java.awt.peer.ScrollPanePeer;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * This widget provides a scrollable region that allows a single
+ * subcomponent to be viewed through a smaller window.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class ScrollPane extends Container implements Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+/**
+ * Constant indicating that scrollbars are created as needed in this
+ * windows.
+ */
+public static final int SCROLLBARS_AS_NEEDED = 0;
+
+/**
+ * Constant indicating that scrollbars are always displayed in this
+ * window.
+ */
+public static final int SCROLLBARS_ALWAYS = 1;
+
+/**
+ * Constant indicating that scrollbars are never displayed in this window.
+ */
+public static final int SCROLLBARS_NEVER = 2;
+
+// Serialization constant
+private static final long serialVersionUID = 7956609840827222915L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The horizontal scrollbar for this window. The methods
+ * <code>setMinimum()</code>, <code>setMaximum</code>, and
+ * <code>setVisibleAmount</code> must not be called on this scrollbar.
+ */
+private ScrollPaneAdjustable hAdjustable;
+
+/**
+ * @serial The vertical scrollbar for this window. The methods
+ * <code>setMinimum()</code>, <code>setMaximum</code>, and
+ * <code>setVisibleAmount</code> must not be called on this scrollbar.
+ */
+private ScrollPaneAdjustable vAdjustable;
+
+/**
+ * @serial Indicates when scrollbars are displayed in this window, will
+ * be one of the constants from this class.
+ */
+private int scrollbarDisplayPolicy;
+
+// Current scroll position
+private Point scrollPosition = new Point(0, 0);
+
+private boolean wheelScrollingEnabled;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>ScrollPane</code> with a default
+ * scrollbar policy of <code>SCROLLBARS_AS_NEEDED</code>.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+ScrollPane()
+{
+ this(SCROLLBARS_AS_NEEDED);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>ScrollPane</code> with the
+ * specified scrollbar policy.
+ *
+ * @param scrollbarDisplayPolicy When to display scrollbars, which must
+ * be one of the constants defined in this class.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+public
+ScrollPane(int scrollbarDisplayPolicy)
+{
+ if (GraphicsEnvironment.isHeadless ())
+ throw new HeadlessException ();
+
+ this.scrollbarDisplayPolicy = scrollbarDisplayPolicy;
+
+ if (scrollbarDisplayPolicy != SCROLLBARS_ALWAYS
+ && scrollbarDisplayPolicy != SCROLLBARS_AS_NEEDED
+ && scrollbarDisplayPolicy != SCROLLBARS_NEVER)
+ throw new IllegalArgumentException("Bad scrollbarDisplayPolicy: " +
+ scrollbarDisplayPolicy);
+
+ if (scrollbarDisplayPolicy != SCROLLBARS_NEVER)
+ {
+ hAdjustable = new ScrollPaneAdjustable (this, Scrollbar.HORIZONTAL);
+ vAdjustable = new ScrollPaneAdjustable (this, Scrollbar.VERTICAL);
+ }
+
+ wheelScrollingEnabled = true;
+
+ // Default size.
+ setSize(100,100);
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Returns the current scrollbar display policy.
+ *
+ * @return The current scrollbar display policy.
+ */
+public int
+getScrollbarDisplayPolicy()
+{
+ return(scrollbarDisplayPolicy);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the horizontal scrollbar for this object. If the scrollbar
+ * display policy is set to <code>SCROLLBARS_NEVER</code> then this
+ * will be <code>null</code>.
+ *
+ * @return The horizontal scrollbar for this window.
+ */
+public Adjustable
+getHAdjustable()
+{
+ return(hAdjustable);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the vertical scrollbar for this object. If the scrollbar
+ * display policy is set to <code>SCROLLBARS_NEVER</code> then this
+ * will be <code>null</code>.
+ *
+ * @return The horizontal scrollbar for this window.
+ */
+public Adjustable
+getVAdjustable()
+{
+ return(vAdjustable);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the current viewport size. The viewport is the region of
+ * this object's window where the child is actually displayed.
+ *
+ * @return The viewport size.
+ */
+public Dimension getViewportSize ()
+{
+ Dimension viewsize = getSize ();
+ Insets insets = getInsets ();
+
+ viewsize.width -= (insets.left + insets.right);
+ viewsize.height -= (insets.top + insets.bottom);
+
+ Component[] list = getComponents();
+ if ((list == null) || (list.length <= 0))
+ return viewsize;
+
+ Dimension dim = list[0].getPreferredSize();
+
+ if (dim.width <= 0 && dim.height <= 0)
+ return viewsize;
+
+ int vScrollbarWidth = getVScrollbarWidth ();
+ int hScrollbarHeight = getHScrollbarHeight ();
+
+ if (scrollbarDisplayPolicy == SCROLLBARS_ALWAYS)
+ {
+ viewsize.width -= vScrollbarWidth;
+ viewsize.height -= hScrollbarHeight;
+ return viewsize;
+ }
+
+ if (scrollbarDisplayPolicy == SCROLLBARS_NEVER)
+ return viewsize;
+
+ // The scroll policy is SCROLLBARS_AS_NEEDED, so we need to see if
+ // either scrollbar is needed.
+
+ // Assume we don't need either scrollbar.
+ boolean mayNeedVertical = false;
+ boolean mayNeedHorizontal = false;
+
+ boolean needVertical = false;
+ boolean needHorizontal = false;
+
+ // Check if we need vertical scrollbars. If we do, then we need to
+ // subtract the width of the vertical scrollbar from the viewport's
+ // width.
+ if (dim.height > viewsize.height)
+ needVertical = true;
+ else if (dim.height > (viewsize.height - hScrollbarHeight))
+ // This is tricky. In this case the child is tall enough that its
+ // bottom edge would be covered by a horizontal scrollbar, if one
+ // were present. This means that if there's a horizontal
+ // scrollbar then we need a vertical scrollbar.
+ mayNeedVertical = true;
+
+ if (dim.width > viewsize.width)
+ needHorizontal = true;
+ else if (dim.width > (viewsize.width - vScrollbarWidth))
+ mayNeedHorizontal = true;
+
+ if (needVertical && mayNeedHorizontal)
+ needHorizontal = true;
+
+ if (needHorizontal && mayNeedVertical)
+ needVertical = true;
+
+ if (needHorizontal)
+ viewsize.height -= hScrollbarHeight;
+
+ if (needVertical)
+ viewsize.width -= vScrollbarWidth;
+
+ return viewsize;
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the height of a horizontal scrollbar.
+ *
+ * @return The height of a horizontal scrollbar.
+ */
+public int
+getHScrollbarHeight()
+{
+ ScrollPanePeer spp = (ScrollPanePeer)getPeer();
+ if (spp != null)
+ return(spp.getHScrollbarHeight());
+ else
+ return(0); // FIXME: What to do here?
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the width of a vertical scrollbar.
+ *
+ * @return The width of a vertical scrollbar.
+ */
+public int
+getVScrollbarWidth()
+{
+ ScrollPanePeer spp = (ScrollPanePeer)getPeer();
+ if (spp != null)
+ return(spp.getVScrollbarWidth());
+ else
+ return(0); // FIXME: What to do here?
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the current scroll position of the viewport.
+ *
+ * @return The current scroll position of the viewport.
+ */
+public Point
+getScrollPosition()
+{
+ int x = 0;
+ int y = 0;
+
+ Adjustable v = getVAdjustable();
+ Adjustable h = getHAdjustable();
+
+ if (v != null)
+ y = v.getValue();
+ if (h != null)
+ x = h.getValue();
+
+ return(new Point(x, y));
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the scroll position to the specified value.
+ *
+ * @param scrollPosition The new scrollPosition.
+ *
+ * @exception IllegalArgumentException If the specified value is outside
+ * the legal scrolling range.
+ */
+public void
+setScrollPosition(Point scrollPosition) throws IllegalArgumentException
+{
+ setScrollPosition(scrollPosition.x, scrollPosition.y);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the scroll position to the specified value.
+ *
+ * @param x The new X coordinate of the scroll position.
+ * @param y The new Y coordinate of the scroll position.
+ *
+ * @exception IllegalArgumentException If the specified value is outside
+ * the legal scrolling range.
+ */
+public void
+setScrollPosition(int x, int y)
+{
+ Adjustable h = getHAdjustable();
+ Adjustable v = getVAdjustable();
+
+ if (h != null)
+ h.setValue(x);
+ if (v != null)
+ v.setValue(y);
+
+ ScrollPanePeer spp = (ScrollPanePeer)getPeer();
+ if (spp != null)
+ spp.setScrollPosition(x, y);
+}
+
+/*************************************************************************/
+
+/**
+ * Notifies this object that it should create its native peer.
+ */
+public void
+addNotify()
+{
+ if (!isDisplayable ())
+ return;
+
+ setPeer((ComponentPeer)getToolkit().createScrollPane(this));
+ super.addNotify();
+
+ Component[] list = getComponents();
+ if (list != null && list.length > 0 && ! (list[0] instanceof Panel))
+ {
+ Panel panel = new Panel();
+ panel.setLayout(new BorderLayout());
+ panel.add(list[0], BorderLayout.CENTER);
+ add(panel);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Notifies this object that it should destroy its native peers.
+ */
+public void
+removeNotify()
+{
+ super.removeNotify();
+}
+
+/*************************************************************************/
+
+/**
+ * Adds the specified child component to this container. A
+ * <code>ScrollPane</code> can have at most one child, so if a second
+ * one is added, then first one is removed.
+ *
+ * @param component The component to add to this container.
+ * @param constraints A list of layout constraints for this object.
+ * @param index The index at which to add the child, which is ignored
+ * in this implementation.
+ */
+ protected final void addImpl (Component component, Object constraints,
+ int index)
+{
+ Component[] list = getComponents();
+ if ((list != null) && (list.length > 0))
+ remove(list[0]);
+
+ super.addImpl(component, constraints, -1);
+
+ doLayout();
+}
+
+/*************************************************************************/
+
+/**
+ * Lays out this component. This consists of resizing the sole child
+ * component to its perferred size.
+ */
+public void
+doLayout()
+{
+ layout ();
+}
+
+/*************************************************************************/
+
+/**
+ * Lays out this component. This consists of resizing the sole child
+ * component to its perferred size.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>doLayout()</code>.
+ */
+public void
+layout()
+{
+ Component[] list = getComponents ();
+ if ((list != null) && (list.length > 0))
+ {
+ Dimension dim = list[0].getPreferredSize ();
+ Dimension vp = getViewportSize ();
+
+ if (dim.width < vp.width)
+ dim.width = vp.width;
+
+ if (dim.height < vp.height)
+ dim.height = vp.height;
+
+ ScrollPanePeer peer = (ScrollPanePeer) getPeer ();
+ if (peer != null)
+ peer.childResized (dim.width, dim.height);
+
+ list[0].setSize (dim);
+
+ Point p = getScrollPosition ();
+ if (p.x > dim.width)
+ p.x = dim.width;
+ if (p.y > dim.height)
+ p.y = dim.height;
+
+ setScrollPosition (p);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * This method overrides its superclass method to ensure no layout
+ * manager is set for this container. <code>ScrollPane</code>'s do
+ * not have layout managers.
+ *
+ * @param layoutManager Ignored
+ */
+public final void
+setLayout(LayoutManager layoutManager)
+{
+ return;
+}
+
+/*************************************************************************/
+
+/**
+ * Prints all of the components in this container.
+ *
+ * @param graphics The desired graphics context for printing.
+ */
+public void
+printComponents(Graphics graphics)
+{
+ super.printComponents(graphics);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debug string for this object.
+ *
+ * @return A debug string for this object.
+ */
+public String
+paramString()
+{
+ Insets insets = getInsets();
+ return getName() + ","
+ + getX() + ","
+ + getY() + ","
+ + getWidth() + "x" + getHeight() + ","
+ + "ScrollPosition=(" + scrollPosition.getX() + ","
+ + scrollPosition.getY() + "),"
+ + "Insets=(" + insets.top + ","
+ + insets.left + ","
+ + insets.bottom + ","
+ + insets.right + "),"
+ + "ScrollbarDisplayPolicy=" + getScrollbarDisplayPolicy() + ","
+ + "wheelScrollingEnabled=" + isWheelScrollingEnabled();
+}
+
+ /**
+ * Tells whether or not an event is enabled.
+ *
+ * @since 1.4
+ */
+ protected boolean eventTypeEnabled (int type)
+ {
+ if (type == MouseEvent.MOUSE_WHEEL)
+ return wheelScrollingEnabled;
+
+ return super.eventTypeEnabled (type);
+ }
+
+ /**
+ * Tells whether or not wheel scrolling is enabled.
+ *
+ * @since 1.4
+ */
+ public boolean isWheelScrollingEnabled ()
+ {
+ return wheelScrollingEnabled;
+ }
+
+ /**
+ * Enables/disables wheel scrolling.
+ *
+ * @since 1.4
+ */
+ public void setWheelScrollingEnabled (boolean enable)
+ {
+ wheelScrollingEnabled = enable;
+ }
+
+ protected class AccessibleAWTScrollPane extends AccessibleAWTContainer
+ {
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.SCROLL_PANE;
+ }
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>ScrollPane</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTScrollPane();
+ return accessibleContext;
+ }
+} // class ScrollPane
+
diff --git a/libjava/classpath/java/awt/ScrollPaneAdjustable.java b/libjava/classpath/java/awt/ScrollPaneAdjustable.java
new file mode 100644
index 0000000..cfca19b
--- /dev/null
+++ b/libjava/classpath/java/awt/ScrollPaneAdjustable.java
@@ -0,0 +1,200 @@
+/* ScrollPaneAdjustable.java -- Scrollbars for a ScrollPane
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.AdjustmentListener;
+import java.io.Serializable;
+
+/**
+ * Need this class since the serialization spec for ScrollPane
+ * uses it.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.4
+ */
+public class ScrollPaneAdjustable
+ implements Adjustable, Serializable
+{
+ private static final long serialVersionUID = -3359745691033257079L;
+
+ ScrollPane sp;
+ int orientation;
+ int value;
+ int minimum;
+ int maximum;
+ int visibleAmount;
+ int unitIncrement = 1;
+ int blockIncrement = 1;
+ AdjustmentListener adjustmentListener;
+
+ private transient boolean valueIsAdjusting = false;
+
+ ScrollPaneAdjustable (ScrollPane sp, int orientation)
+ {
+ this.sp = sp;
+ this.orientation = orientation;
+ }
+
+ ScrollPaneAdjustable (ScrollPane sp, int orientation, int value, int minimum,
+ int maximum, int visibleAmount, int unitIncrement,
+ int blockIncrement)
+ {
+ this.sp = sp;
+ this.orientation = orientation;
+ this.value = value;
+ this.minimum = minimum;
+ this.maximum = maximum;
+ this.visibleAmount = visibleAmount;
+ this.unitIncrement = unitIncrement;
+ this.blockIncrement = blockIncrement;
+ }
+
+ public void addAdjustmentListener (AdjustmentListener listener)
+ {
+ AWTEventMulticaster.add (adjustmentListener, listener);
+ }
+
+ public void removeAdjustmentListener (AdjustmentListener listener)
+ {
+ AWTEventMulticaster.remove (adjustmentListener, listener);
+ }
+
+ public AdjustmentListener[] getAdjustmentListeners ()
+ {
+ return (AdjustmentListener[]) AWTEventMulticaster.getListeners
+ (adjustmentListener, AdjustmentListener.class);
+ }
+
+ public int getBlockIncrement ()
+ {
+ return blockIncrement;
+ }
+
+ public int getMaximum ()
+ {
+ return maximum;
+ }
+
+ public int getMinimum ()
+ {
+ return minimum;
+ }
+
+ public int getOrientation ()
+ {
+ return orientation;
+ }
+
+ public int getUnitIncrement ()
+ {
+ return unitIncrement;
+ }
+
+ public int getValue ()
+ {
+ return value;
+ }
+
+ public int getVisibleAmount ()
+ {
+ return visibleAmount;
+ }
+
+ public void setBlockIncrement (int blockIncrement)
+ {
+ this.blockIncrement = blockIncrement;
+ }
+
+ public void setMaximum (int maximum)
+ {
+ this.maximum = maximum;
+ }
+
+ public void setMinimum (int minimum)
+ {
+ this.minimum = minimum;
+ }
+
+ public void setUnitIncrement (int unitIncrement)
+ {
+ this.unitIncrement = unitIncrement;
+ }
+
+ public void setValue (int value)
+ {
+ this.value = value;
+
+ if (value < minimum)
+ minimum = value;
+
+ if (value > maximum)
+ maximum = value;
+ }
+
+ public void setVisibleAmount (int visibleAmount)
+ {
+ this.visibleAmount = visibleAmount;
+ }
+
+ public String paramString ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ /**
+ * Returns true if the value is in the process of changing.
+ *
+ * @since 1.4
+ */
+ public boolean getValueIsAdjusting ()
+ {
+ return valueIsAdjusting;
+ }
+
+ /**
+ * Sets the value of valueIsAdjusting.
+ *
+ * @since 1.4
+ */
+ public void setValueIsAdjusting (boolean valueIsAdjusting)
+ {
+ this.valueIsAdjusting = valueIsAdjusting;
+ }
+} // class ScrollPaneAdjustable
+
diff --git a/libjava/classpath/java/awt/Scrollbar.java b/libjava/classpath/java/awt/Scrollbar.java
new file mode 100644
index 0000000..6e506c7
--- /dev/null
+++ b/libjava/classpath/java/awt/Scrollbar.java
@@ -0,0 +1,825 @@
+/* Scrollbar.java -- AWT Scrollbar widget
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.peer.ScrollbarPeer;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleValue;
+
+/**
+ * This class implements a scrollbar widget.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+public class Scrollbar extends Component implements Accessible, Adjustable
+{
+ // FIXME: Serialization readObject/writeObject
+
+ /**
+ * Constant indicating that a scrollbar is horizontal.
+ */
+ public static final int HORIZONTAL = 0;
+
+ /**
+ * Constant indicating that a scrollbar is vertical.
+ */
+ public static final int VERTICAL = 1;
+
+ /**
+ * Serialization Constant.
+ */
+ private static final long serialVersionUID = 8451667562882310543L;
+
+ /**
+ * @serial The amount by which the value of the scrollbar is changed
+ * when incrementing in line mode.
+ */
+ private int lineIncrement;
+
+ /**
+ * @serial The amount by which the value of the scrollbar is changed
+ * when incrementing in page mode.
+ */
+ private int pageIncrement;
+
+ /**
+ * @serial The maximum value for this scrollbar
+ */
+ private int maximum;
+
+ /**
+ * @serial The minimum value for this scrollbar
+ */
+ private int minimum;
+
+ /**
+ * @serial The orientation of this scrollbar, which will be either
+ * the <code>HORIZONTAL</code> or <code>VERTICAL</code> constant
+ * from this class.
+ */
+ private int orientation;
+
+ /**
+ * @serial The current value of this scrollbar.
+ */
+ private int value;
+
+ /**
+ * @serial The width of the scrollbar's thumb, which is relative
+ * to the minimum and maximum value of the scrollbar.
+ */
+ private int visibleAmount;
+
+ /**
+ * List of AdjustmentListener's.
+ */
+ private AdjustmentListener adjustment_listeners;
+
+ /**
+ * true if the scrollbar is adjusting, false otherwise.
+ */
+ private transient boolean valueIsAdjusting = false;
+
+ /**
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_scrollbar_number;
+
+ /**
+ * Initializes a new instance of <code>Scrollbar</code> with a
+ * vertical orientation and default values for all other parameters.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+ public Scrollbar()
+ {
+ this(VERTICAL);
+ }
+
+ /**
+ * Initializes a new instance of <code>Scrollbar</code> with the
+ * specified orientation and default values for all other parameters.
+ * The orientation must be either the constant <code>HORIZONTAL</code> or
+ * <code>VERTICAL</code> from this class. An incorrect value will throw
+ * an exception.
+ *
+ * @param orientation The orientation of this scrollbar.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ * @exception IllegalArgumentException If the orientation value is not valid.
+ */
+ public Scrollbar(int orientation) throws IllegalArgumentException
+ {
+ this(orientation, 0, 10, 0, 100);
+ }
+
+ /**
+ * Initializes a new instance of <code>Scrollbar</code> with the
+ * specified parameters. The orientation must be either the constant
+ * <code>HORIZONTAL</code> or <code>VERTICAL</code>. An incorrect value
+ * will throw an exception. Inconsistent values for other parameters
+ * are silently corrected to valid values.
+ *
+ * @param orientation The orientation of this scrollbar.
+ * @param value The initial value of the scrollbar.
+ * @param visibleAmount The width of the scrollbar thumb.
+ * @param minimum The minimum value of the scrollbar.
+ * @param maximum The maximum value of the scrollbar.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ * @exception IllegalArgumentException If the orientation value is not valid.
+ */
+ public Scrollbar(int orientation, int value, int visibleAmount, int minimum,
+ int maximum) throws IllegalArgumentException
+ {
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException();
+
+ if ((orientation != HORIZONTAL) && (orientation != VERTICAL))
+ throw new IllegalArgumentException("Bad orientation value: "
+ + orientation);
+
+ this.orientation = orientation;
+
+ setValues(value, visibleAmount, minimum, maximum);
+
+ // Default is 1 according to online docs.
+ lineIncrement = 1;
+
+ // Default is 10 according to javadocs.
+ pageIncrement = 10;
+ }
+
+ /**
+ * Returns the orientation constant for this object.
+ *
+ * @return The orientation constant for this object.
+ */
+ public int getOrientation()
+ {
+ return orientation;
+ }
+
+ /**
+ * Sets the orientation of this scrollbar to the specified value. This
+ * value must be either the constant <code>HORIZONTAL</code> or
+ * <code>VERTICAL</code> from this class or an exception will be thrown.
+ *
+ * @param orientation The new orientation value.
+ *
+ * @exception IllegalArgumentException If the orientation value is not valid.
+ */
+ public void setOrientation(int orientation)
+ {
+ if ((orientation != HORIZONTAL) && (orientation != VERTICAL))
+ throw new IllegalArgumentException("Bad orientation value: "
+ + orientation);
+
+ // FIXME: Communicate to peer? Or must this be called before peer creation?
+ this.orientation = orientation;
+ }
+
+ /**
+ * Returns the current value for this scrollbar.
+ *
+ * @return The current value for this scrollbar.
+ */
+ public int getValue()
+ {
+ return value;
+ }
+
+ /**
+ * Sets the current value for this scrollbar to the specified value.
+ * If this is inconsistent with the minimum and maximum values for this
+ * scrollbar, the value is silently adjusted.
+ *
+ * @param value The new value for this scrollbar.
+ */
+ public void setValue(int value)
+ {
+ setValues(value, visibleAmount, minimum, maximum);
+ }
+
+ /**
+ * Returns the maximum value for this scrollbar.
+ *
+ * @return The maximum value for this scrollbar.
+ */
+ public int getMaximum()
+ {
+ return maximum;
+ }
+
+ /**
+ * Sets the maximum value for this scrollbar to the specified value.
+ * If the value is less than the current minimum value, it is silent
+ * set to equal the minimum value.
+ *
+ * @param maximum The new maximum value for this scrollbar.
+ */
+ public void setMaximum(int maximum)
+ {
+ setValues(value, visibleAmount, minimum, maximum);
+ }
+
+ /**
+ * Returns the minimum value for this scrollbar.
+ *
+ * @return The minimum value for this scrollbar.
+ */
+ public int getMinimum()
+ {
+ return minimum;
+ }
+
+ /**
+ * Sets the minimum value for this scrollbar to the specified value. If
+ * this is not consistent with the current value and maximum, it is
+ * silently adjusted to be consistent.
+ *
+ * @param minimum The new minimum value for this scrollbar.
+ */
+ public void setMinimum(int minimum)
+ {
+ setValues(value, visibleAmount, minimum, maximum);
+ }
+
+ /**
+ * Returns the width of the scrollbar's thumb, in units relative to the
+ * maximum and minimum value of the scrollbar.
+ *
+ * @return The width of the scrollbar's thumb.
+ */
+ public int getVisibleAmount()
+ {
+ return getVisible();
+ }
+
+ /**
+ * Returns the width of the scrollbar's thumb, in units relative to the
+ * maximum and minimum value of the scrollbar.
+ *
+ * @return The width of the scrollbar's thumb.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getVisibleAmount()</code>.
+ */
+ public int getVisible()
+ {
+ return visibleAmount;
+ }
+
+ /**
+ * Sets the width of the scrollbar's thumb, in units relative to the
+ * maximum and minimum value of the scrollbar.
+ *
+ * @param visibleAmount The new visible amount value of the scrollbar.
+ */
+ public void setVisibleAmount(int visibleAmount)
+ {
+ setValues(value, visibleAmount, minimum, maximum);
+ }
+
+ /**
+ * Sets the current value, visible amount, minimum, and maximum for this
+ * scrollbar. These values are adjusted to be internally consistent
+ * if necessary.
+ *
+ * @param value The new value for this scrollbar.
+ * @param visibleAmount The new visible amount for this scrollbar.
+ * @param minimum The new minimum value for this scrollbar.
+ * @param maximum The new maximum value for this scrollbar.
+ */
+ public synchronized void setValues(int value, int visibleAmount,
+ int minimum, int maximum)
+ {
+ if (maximum < minimum)
+ maximum = minimum;
+
+ if (value < minimum)
+ value = minimum;
+
+ if (value > maximum)
+ value = maximum;
+
+ if (visibleAmount > maximum - minimum)
+ visibleAmount = maximum - minimum;
+
+ ScrollbarPeer peer = (ScrollbarPeer) getPeer();
+ if (peer != null
+ && (this.value != value || this.visibleAmount != visibleAmount
+ || this.minimum != minimum || this.maximum != maximum))
+ peer.setValues(value, visibleAmount, minimum, maximum);
+
+ this.value = value;
+ this.visibleAmount = visibleAmount;
+ this.minimum = minimum;
+ this.maximum = maximum;
+
+ int range = maximum - minimum;
+ if (lineIncrement > range)
+ {
+ if (range == 0)
+ lineIncrement = 1;
+ else
+ lineIncrement = range;
+
+ if (peer != null)
+ peer.setLineIncrement(lineIncrement);
+ }
+
+ if (pageIncrement > range)
+ {
+ if (range == 0)
+ pageIncrement = 1;
+ else
+ pageIncrement = range;
+
+ if (peer != null)
+ peer.setPageIncrement(pageIncrement);
+ }
+ }
+
+ /**
+ * Returns the value added or subtracted when the user activates the scrollbar
+ * scroll by a "unit" amount.
+ *
+ * @return The unit increment value.
+ */
+ public int getUnitIncrement()
+ {
+ return getLineIncrement();
+ }
+
+ /**
+ * Returns the value added or subtracted when the user selects the scrollbar
+ * scroll by a "unit" amount control.
+ *
+ * @return The unit increment value.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getUnitIncrement()</code>.
+ */
+ public int getLineIncrement()
+ {
+ return lineIncrement;
+ }
+
+ /**
+ * Sets the value added or subtracted to the scrollbar value when the
+ * user selects the scroll by a "unit" amount control.
+ *
+ * @param unitIncrement The new unit increment amount.
+ */
+ public synchronized void setUnitIncrement(int unitIncrement)
+ {
+ setLineIncrement(unitIncrement);
+ }
+
+ /**
+ * Sets the value added or subtracted to the scrollbar value when the
+ * user selects the scroll by a "unit" amount control.
+ *
+ * @param lineIncrement The new unit increment amount.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>setUnitIncrement()</code>.
+ */
+ public void setLineIncrement(int lineIncrement)
+ {
+ if (lineIncrement < 0)
+ throw new IllegalArgumentException("Unit increment less than zero.");
+
+ int range = maximum - minimum;
+ if (lineIncrement > range)
+ {
+ if (range == 0)
+ lineIncrement = 1;
+ else
+ lineIncrement = range;
+ }
+
+ if (lineIncrement == this.lineIncrement)
+ return;
+
+ this.lineIncrement = lineIncrement;
+
+ ScrollbarPeer peer = (ScrollbarPeer) getPeer();
+ if (peer != null)
+ peer.setLineIncrement(this.lineIncrement);
+ }
+
+ /**
+ * Returns the value added or subtracted when the user activates the scrollbar
+ * scroll by a "block" amount.
+ *
+ * @return The block increment value.
+ */
+ public int getBlockIncrement()
+ {
+ return getPageIncrement();
+ }
+
+ /**
+ * Returns the value added or subtracted when the user selects the scrollbar
+ * scroll by a "block" amount control.
+ *
+ * @return The block increment value.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getBlockIncrement()</code>.
+ */
+ public int getPageIncrement()
+ {
+ return pageIncrement;
+ }
+
+ /**
+ * Sets the value added or subtracted to the scrollbar value when the
+ * user selects the scroll by a "block" amount control.
+ *
+ * @param blockIncrement The new block increment amount.
+ */
+ public synchronized void setBlockIncrement(int blockIncrement)
+ {
+ setPageIncrement(blockIncrement);
+ }
+
+ /**
+ * Sets the value added or subtracted to the scrollbar value when the
+ * user selects the scroll by a "block" amount control.
+ *
+ * @param pageIncrement The new block increment amount.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>setBlockIncrement()</code>.
+ */
+ public void setPageIncrement(int pageIncrement)
+ {
+ if (pageIncrement < 0)
+ throw new IllegalArgumentException("Block increment less than zero.");
+
+ int range = maximum - minimum;
+ if (pageIncrement > range)
+ {
+ if (range == 0)
+ pageIncrement = 1;
+ else
+ pageIncrement = range;
+ }
+
+ if (pageIncrement == this.pageIncrement)
+ return;
+
+ this.pageIncrement = pageIncrement;
+
+ ScrollbarPeer peer = (ScrollbarPeer) getPeer();
+ if (peer != null)
+ peer.setPageIncrement(this.pageIncrement);
+ }
+
+ /**
+ * Notifies this object to create its native peer.
+ */
+ public synchronized void addNotify()
+ {
+ if (peer == null)
+ peer = getToolkit().createScrollbar(this);
+ super.addNotify();
+ }
+
+ /**
+ * Adds a new adjustment listener to the list of registered listeners
+ * for this object.
+ *
+ * @param listener The listener to add.
+ */
+ public synchronized void addAdjustmentListener(AdjustmentListener listener)
+ {
+ adjustment_listeners = AWTEventMulticaster.add(adjustment_listeners,
+ listener);
+ enableEvents(AWTEvent.ADJUSTMENT_EVENT_MASK);
+ }
+
+ /**
+ * Removes the specified listener from the list of registered listeners
+ * for this object.
+ *
+ * @param listener The listener to remove.
+ */
+ public synchronized void removeAdjustmentListener(AdjustmentListener listener)
+ {
+ adjustment_listeners = AWTEventMulticaster.remove(adjustment_listeners,
+ listener);
+ }
+
+ /**
+ * Processes events for this scrollbar. It does this by calling
+ * <code>processAdjustmentEvent()</code> if the event is an instance of
+ * <code>AdjustmentEvent</code>, otherwise it calls the superclass to
+ * process the event.
+ *
+ * @param event The event to process.
+ */
+ protected void processEvent(AWTEvent event)
+ {
+ if (event instanceof AdjustmentEvent)
+ processAdjustmentEvent((AdjustmentEvent) event);
+ else
+ super.processEvent(event);
+ }
+
+ /**
+ * Processes adjustment events for this object by dispatching them to
+ * any registered listeners. Note that this method will only be called
+ * if adjustment events are enabled. This will happen automatically if
+ * any listeners are registered. Otherwise, it can be enabled by a
+ * call to <code>enableEvents()</code>.
+ *
+ * @param event The event to process.
+ */
+ protected void processAdjustmentEvent(AdjustmentEvent event)
+ {
+ value = event.getValue();
+ if (adjustment_listeners != null)
+ adjustment_listeners.adjustmentValueChanged(event);
+ }
+
+ void dispatchEventImpl(AWTEvent e)
+ {
+ if (e.id <= AdjustmentEvent.ADJUSTMENT_LAST
+ && e.id >= AdjustmentEvent.ADJUSTMENT_FIRST
+ && (adjustment_listeners != null
+ || (eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+ }
+
+ /**
+ * Returns a debugging string for this object.
+ *
+ * @return A debugging string for this object.
+ */
+ protected String paramString()
+ {
+ return ("value=" + getValue() + ",visibleAmount=" + getVisibleAmount()
+ + ",minimum=" + getMinimum() + ",maximum=" + getMaximum()
+ + ",pageIncrement=" + pageIncrement + ",lineIncrement="
+ + lineIncrement + ",orientation="
+ + (orientation == HORIZONTAL ? "HORIZONTAL" : "VERTICAL")
+ + super.paramString());
+ }
+
+ /**
+ * Returns an array of all the objects currently registered as FooListeners
+ * upon this <code>Scrollbar</code>. FooListeners are registered using the
+ * addFooListener method.
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements java.util.EventListener.
+ */
+ public EventListener[] getListeners(Class listenerType)
+ {
+ if (listenerType == AdjustmentListener.class)
+ return AWTEventMulticaster.getListeners(adjustment_listeners,
+ listenerType);
+
+ return super.getListeners(listenerType);
+ }
+
+ /**
+ * Returns an array of all registered adjustment listeners.
+ */
+ public AdjustmentListener[] getAdjustmentListeners()
+ {
+ return (AdjustmentListener[]) getListeners(AdjustmentListener.class);
+ }
+
+ /**
+ * Returns true if the value is in the process of changing.
+ *
+ * @since 1.4
+ */
+ public boolean getValueIsAdjusting()
+ {
+ return valueIsAdjusting;
+ }
+
+ /**
+ * Sets the value of valueIsAdjusting.
+ *
+ * @since 1.4
+ */
+ public void setValueIsAdjusting(boolean valueIsAdjusting)
+ {
+ this.valueIsAdjusting = valueIsAdjusting;
+ }
+
+ /**
+ * Generate a unique name for this scroll bar.
+ *
+ * @return A unique name for this scroll bar.
+ */
+ String generateName()
+ {
+ return "scrollbar" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_scrollbar_number++;
+ }
+
+ /**
+ * This class provides accessibility support for the
+ * scrollbar.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ protected class AccessibleAWTScrollBar extends AccessibleAWTComponent
+ implements AccessibleValue
+ {
+ /**
+ * Serialization constant to match JDK 1.5
+ */
+ private static final long serialVersionUID = -344337268523697807L;
+
+ /**
+ * Returns the role of this accessible object.
+ *
+ * @return the instance of <code>AccessibleRole</code>,
+ * which describes this object.
+ *
+ * @see javax.accessibility.AccessibleRole
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.SCROLL_BAR;
+ }
+
+ /**
+ * Returns the state set of this accessible object.
+ *
+ * @return a set of <code>AccessibleState</code>s which
+ * represent the current state of the accessible object.
+ *
+ * @see javax.accessibility.AccessibleState
+ * @see javax.accessibility.AccessibleStateSet
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet states = super.getAccessibleStateSet();
+ if (getOrientation() == HORIZONTAL)
+ states.add(AccessibleState.HORIZONTAL);
+ else
+ states.add(AccessibleState.VERTICAL);
+ if (getValueIsAdjusting())
+ states.add(AccessibleState.BUSY);
+ return states;
+ }
+
+ /**
+ * Returns an implementation of the <code>AccessibleValue</code>
+ * interface for this accessible object. In this case, the
+ * current instance is simply returned (with a more appropriate
+ * type), as it also implements the accessible value as well as
+ * the context.
+ *
+ * @return the accessible value associated with this context.
+ *
+ * @see javax.accessibility.AccessibleValue
+ */
+ public AccessibleValue getAccessibleValue()
+ {
+ return this;
+ }
+
+ /**
+ * Returns the current value of this accessible object.
+ * In this case, this is the same as the value for
+ * the scrollbar, wrapped in an <code>Integer</code>
+ * object.
+ *
+ * @return the numeric value of this scrollbar.
+ *
+ * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
+ */
+ public Number getCurrentAccessibleValue()
+ {
+ return new Integer(getValue());
+ }
+
+ /**
+ * Sets the current value of this accessible object
+ * to that supplied. In this case, the value of the
+ * scrollbar is set, and this method always returns
+ * true.
+ *
+ * @param number the new accessible value.
+ *
+ * @return true if the value was set.
+ *
+ * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
+ */
+ public boolean setCurrentAccessibleValue(Number number)
+ {
+ setValue(number.intValue());
+ return true;
+ }
+
+ /**
+ * Returns the minimum acceptable accessible value used
+ * by this object. In this case, this is the same as
+ * the minimum value of the scrollbar, wrapped in an
+ * object.
+ *
+ * @return the minimum value of this scrollbar.
+ *
+ * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
+ */
+ public Number getMinimumAccessibleValue()
+ {
+ return new Integer(getMinimum());
+ }
+
+ /**
+ * Returns the maximum acceptable accessible value used
+ * by this object. In this case, this is the same as
+ * the maximum value of the scrollbar, wrapped in an
+ * object.
+ *
+ * @return the maximum value of this scrollbar.
+ *
+ * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
+ */
+ public Number getMaximumAccessibleValue()
+ {
+ return new Integer(getMaximum());
+ }
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>Scrollbar</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTScrollBar();
+
+ return accessibleContext;
+ }
+}
diff --git a/libjava/classpath/java/awt/Shape.java b/libjava/classpath/java/awt/Shape.java
new file mode 100644
index 0000000..bd8a434
--- /dev/null
+++ b/libjava/classpath/java/awt/Shape.java
@@ -0,0 +1,203 @@
+/* Shape.java -- the classic Object-Oriented shape interface
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * This interface represents an abstract shape. The shape is described by
+ * a {@link PathIterator}, and has callbacks for determining bounding box,
+ * where points and rectangles lie in relation to the shape, and tracing
+ * the trajectory.
+ *
+ * <p>A point is inside if it is completely inside, or on the boundary and
+ * adjacent points in the increasing x or y direction are completely inside.
+ * Unclosed shapes are considered as implicitly closed when performing
+ * <code>contains</code> or <code>intersects</code>.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see PathIterator
+ * @see AffineTransform
+ * @see java.awt.geom.FlatteningPathIterator
+ * @see java.awt.geom.GeneralPath
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public interface Shape
+{
+ /**
+ * Returns a <code>Rectange</code> that bounds the shape. There is no
+ * guarantee that this is the minimum bounding box, particularly if
+ * the shape overflows the finite integer range of a bound. Generally,
+ * <code>getBounds2D</code> returns a tighter bound.
+ *
+ * @return the shape's bounding box
+ * @see #getBounds2D()
+ */
+ Rectangle getBounds();
+
+ /**
+ * Returns a high precision bounding box of the shape. There is no guarantee
+ * that this is the minimum bounding box, but at least it never overflows.
+ *
+ * @return the shape's bounding box
+ * @see #getBounds()
+ * @since 1.2
+ */
+ Rectangle2D getBounds2D();
+
+ /**
+ * Test if the coordinates lie in the shape.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @return true if (x,y) lies inside the shape
+ * @since 1.2
+ */
+ boolean contains(double x, double y);
+
+ /**
+ * Test if the point lie in the shape.
+ *
+ * @param p the high-precision point
+ * @return true if p lies inside the shape
+ * @throws NullPointerException if p is null
+ * @since 1.2
+ */
+ boolean contains(Point2D p);
+
+ /**
+ * Test if a high-precision rectangle intersects the shape. This is true
+ * if any point in the rectangle is in the shape, with the caveat that the
+ * operation may include high probability estimates when the actual
+ * calculation is prohibitively expensive. The {@link java.awt.geom.Area}
+ * class can be used for more precise answers.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle, undefined results if negative
+ * @param h the height of the rectangle, undefined results if negative
+ * @return true if the rectangle intersects this shape
+ * @see java.awt.geom.Area
+ * @since 1.2
+ */
+ boolean intersects(double x, double y, double w, double h);
+
+ /**
+ * Test if a high-precision rectangle intersects the shape. This is true
+ * if any point in the rectangle is in the shape, with the caveat that the
+ * operation may include high probability estimates when the actual
+ * calculation is prohibitively expensive. The {@link java.awt.geom.Area}
+ * class can be used for more precise answers.
+ *
+ * @param r the rectangle
+ * @return true if the rectangle intersects this shape
+ * @throws NullPointerException if r is null
+ * @see #intersects(double, double, double, double)
+ * @since 1.2
+ */
+ boolean intersects(Rectangle2D r);
+
+ /**
+ * Test if a high-precision rectangle lies completely in the shape. This is
+ * true if all points in the rectangle are in the shape, with the caveat
+ * that the operation may include high probability estimates when the actual
+ * calculation is prohibitively expensive. The {@link java.awt.geom.Area}
+ * class can be used for more precise answers.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle, undefined results if negative
+ * @param h the height of the rectangle, undefined results if negative
+ * @return true if the rectangle is contained in this shape
+ * @see java.awt.geom.Area
+ * @since 1.2
+ */
+ boolean contains(double x, double y, double w, double h);
+
+ /**
+ * Test if a high-precision rectangle lies completely in the shape. This is
+ * true if all points in the rectangle are in the shape, with the caveat
+ * that the operation may include high probability estimates when the actual
+ * calculation is prohibitively expensive. The {@link java.awt.geom.Area}
+ * class can be used for more precise answers.
+ *
+ * @param r the rectangle
+ * @return true if the rectangle is contained in this shape
+ * @throws NullPointerException if r is null
+ * @see #contains(double, double, double, double)
+ * @since 1.2
+ */
+ boolean contains(Rectangle2D r);
+
+ /**
+ * Return an iterator along the shape boundary. If the optional transform
+ * is provided, the iterator is transformed accordingly. Each call returns
+ * a new object, independent from others in use. It is recommended, but
+ * not required, that the Shape isolate iterations from future changes to
+ * the boundary, and document this fact.
+ *
+ * @param transform an optional transform to apply to the iterator
+ * @return a new iterator over the boundary
+ * @since 1.2
+ */
+ PathIterator getPathIterator(AffineTransform transform);
+
+ /**
+ * Return an iterator along the flattened version of the shape boundary.
+ * Only SEG_MOVETO, SEG_LINETO, and SEG_CLOSE points are returned in the
+ * iterator. The flatness paramter controls how far points are allowed to
+ * differ from the real curve; although a limit on accuracy may cause this
+ * parameter to be enlarged if needed.
+ *
+ * <p>If the optional transform is provided, the iterator is transformed
+ * accordingly. Each call returns a new object, independent from others in
+ * use. It is recommended, but not required, that the Shape isolate
+ * iterations from future changes to the boundary, and document this fact.
+ *
+ * @param transform an optional transform to apply to the iterator
+ * @param flatness the maximum distance for deviation from the real boundary
+ * @return a new iterator over the boundary
+ * @since 1.2
+ */
+ PathIterator getPathIterator(AffineTransform transform, double flatness);
+} // interface Shape
diff --git a/libjava/classpath/java/awt/Stroke.java b/libjava/classpath/java/awt/Stroke.java
new file mode 100644
index 0000000..1a4c61c
--- /dev/null
+++ b/libjava/classpath/java/awt/Stroke.java
@@ -0,0 +1,65 @@
+/* Stroke.java -- a stroked outline of a shape
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+/**
+ * This interface allows a Graphics2D to grab the outline of a shape, as if
+ * stroked by a marking pen of appropriate size and shape. The area inked
+ * by the pen is the area of this stroke. Anything in the graphic which
+ * traces an outline will use this stroke, such as <code>drawLine</code>.
+ * Strokes must be immutable, because the graphics object does not clone
+ * them.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see BasicStroke
+ * @see Graphics2D#setStroke(Stroke)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface Stroke
+{
+ /**
+ * Returns a shape which outlines the boundary of the given shape, in
+ * effect converting the infinitely thin line into a new shape.
+ *
+ * @param s the shape to stroke
+ * @return the stroked outline shape
+ */
+ Shape createStrokedShape(Shape s);
+} // interface Stroke
diff --git a/libjava/classpath/java/awt/SystemColor.java b/libjava/classpath/java/awt/SystemColor.java
new file mode 100644
index 0000000..2ead74a
--- /dev/null
+++ b/libjava/classpath/java/awt/SystemColor.java
@@ -0,0 +1,462 @@
+/* SystemColor.java -- access dynamic system color values
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.io.Serializable;
+
+/**
+ * This class contains the various "system colors" in use by the native
+ * windowing system. The <code>getRGB()</code> method is dynamic on systems
+ * which support dynamic system color changes, and most methods in the
+ * superclass are written to use this dynamic value when reporting colors.
+ * However, the <code>equals()</code> method is not dynamic, and does not
+ * track the actual color of instances in this class. This means that equals
+ * may give surprising results; you are better off relying on getRGB.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class SystemColor extends Color implements Serializable
+{
+ // Implementation note: To be serial compatible with JDK, this class must
+ // violate the semantic meaning of super.value to be one of the
+ // NUM_COLORS constants instead of the actual RGB value. Hence there are
+ // a lot of ugly workarounds in Color and in this class. I would have
+ // designed it MUCH differently, making a separate id field in this class.
+
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 4503142729533789064L;
+
+ /**
+ * Array index of the desktop color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #desktop
+ */
+ public static final int DESKTOP = 0;
+
+ /**
+ * Array index of the active caption color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #activeCaption
+ */
+ public static final int ACTIVE_CAPTION = 1;
+
+ /**
+ * Array index of the active caption text color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #activeCaptionText
+ */
+ public static final int ACTIVE_CAPTION_TEXT = 2;
+
+ /**
+ * Array index of the active caption border color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #activeCaptionBorder
+ */
+ public static final int ACTIVE_CAPTION_BORDER = 3;
+
+ /**
+ * Array index of the inactive caption color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #inactiveCaption
+ */
+ public static final int INACTIVE_CAPTION = 4;
+
+ /**
+ * Array index of the inactive caption text color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #inactiveCaptionText
+ */
+ public static final int INACTIVE_CAPTION_TEXT = 5;
+
+ /**
+ * Array index of the inactive caption border color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #inactiveCaptionBorder
+ */
+ public static final int INACTIVE_CAPTION_BORDER = 6;
+
+ /**
+ * Array index of the window background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #window
+ */
+ public static final int WINDOW = 7;
+
+ /**
+ * Array index of the window border color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #windowBorder
+ */
+ public static final int WINDOW_BORDER = 8;
+
+ /**
+ * Array index of the window text color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #windowText
+ */
+ public static final int WINDOW_TEXT = 9;
+
+ /**
+ * Array index of the menu background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #menu
+ */
+ public static final int MENU = 10;
+
+ /**
+ * Array index of the menu text color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #menuText
+ */
+ public static final int MENU_TEXT = 11;
+
+ /**
+ * Array index of the text background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #text
+ */
+ public static final int TEXT = 12;
+
+ /**
+ * Array index of the text foreground color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #textText
+ */
+ public static final int TEXT_TEXT = 13;
+
+ /**
+ * Array index of the highlighted text background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #textHighlight
+ */
+ public static final int TEXT_HIGHLIGHT = 14;
+
+ /**
+ * Array index of the highlighted text foreground color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #textHighlightText
+ */
+ public static final int TEXT_HIGHLIGHT_TEXT = 15;
+
+ /**
+ * Array index of the inactive text foreground color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #textInactiveText
+ */
+ public static final int TEXT_INACTIVE_TEXT = 16;
+
+ /**
+ * Array index of the control background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #control
+ */
+ public static final int CONTROL = 17;
+
+ /**
+ * Array index of the control text color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #controlText
+ */
+ public static final int CONTROL_TEXT = 18;
+
+ /**
+ * Array index of the highlighted control background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #controlHighlight
+ */
+ public static final int CONTROL_HIGHLIGHT = 19;
+
+ /**
+ * Array index of the lightly highlighted control background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #controlLtHighlight
+ */
+ public static final int CONTROL_LT_HIGHLIGHT = 20;
+
+ /**
+ * Array index of the shadowed control background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #controlShadow
+ */
+ public static final int CONTROL_SHADOW = 21;
+
+ /**
+ * Array index of the darkly shadowed control background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #controlDkShadow
+ */
+ public static final int CONTROL_DK_SHADOW = 22;
+
+ /**
+ * Array index of the scrollbar background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #scrollbar
+ */
+ public static final int SCROLLBAR = 23;
+
+ /**
+ * Array index of the info background color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #info
+ */
+ public static final int INFO = 24;
+
+ /**
+ * Array index of the info text color. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ *
+ * @see #infoText
+ */
+ public static final int INFO_TEXT = 25;
+
+ /**
+ * The number of system colors. Used by
+ * {@link Toolkit#loadSystemColors(int[])}.
+ */
+ public static final int NUM_COLORS = 26;
+
+ /**
+ * The internal array used to dynamically update <code>getRGB()</code>.
+ */
+ private static final int[] colors = new int[NUM_COLORS];
+
+ /** The desktop color. */
+ public static final SystemColor desktop
+ = new SystemColor(DESKTOP);
+
+ /** The active caption background color. */
+ public static final SystemColor activeCaption
+ = new SystemColor(ACTIVE_CAPTION);
+
+ /** The active caption text color. */
+ public static final SystemColor activeCaptionText
+ = new SystemColor(ACTIVE_CAPTION_TEXT);
+
+ /** The active caption border color. */
+ public static final SystemColor activeCaptionBorder
+ = new SystemColor(ACTIVE_CAPTION_BORDER);
+
+ /** The inactive caption background color. */
+ public static final SystemColor inactiveCaption
+ = new SystemColor(INACTIVE_CAPTION);
+
+ /** The inactive caption text color. */
+ public static final SystemColor inactiveCaptionText
+ = new SystemColor(INACTIVE_CAPTION_TEXT);
+
+ /** The inactive caption border color. */
+ public static final SystemColor inactiveCaptionBorder
+ = new SystemColor(INACTIVE_CAPTION_BORDER);
+
+ /** The window background color. */
+ public static final SystemColor window
+ = new SystemColor(WINDOW);
+
+ /** The window border color. */
+ public static final SystemColor windowBorder
+ = new SystemColor(WINDOW_BORDER);
+
+ /** The window text color. */
+ public static final SystemColor windowText
+ = new SystemColor(WINDOW_TEXT);
+
+ /** The menu background color. */
+ public static final SystemColor menu
+ = new SystemColor(MENU);
+
+ /** The menu text color. */
+ public static final SystemColor menuText
+ = new SystemColor(MENU_TEXT);
+
+ /** The text background color. */
+ public static final SystemColor text
+ = new SystemColor(TEXT);
+
+ /** The text foreground color. */
+ public static final SystemColor textText
+ = new SystemColor(TEXT_TEXT);
+
+ /** The highlighted text background color. */
+ public static final SystemColor textHighlight
+ = new SystemColor(TEXT_HIGHLIGHT);
+
+ /** The highlighted text foreground color. */
+ public static final SystemColor textHighlightText
+ = new SystemColor(TEXT_HIGHLIGHT_TEXT);
+
+ /** The inactive text color. */
+ public static final SystemColor textInactiveText
+ = new SystemColor(TEXT_INACTIVE_TEXT);
+
+ /** The control background color. */
+ public static final SystemColor control
+ = new SystemColor(CONTROL);
+
+ /** The control text color. */
+ public static final SystemColor controlText
+ = new SystemColor(CONTROL_TEXT);
+
+ /** The control highlight color. */
+ public static final SystemColor controlHighlight
+ = new SystemColor(CONTROL_HIGHLIGHT);
+
+ /** The control light highlight color. */
+ public static final SystemColor controlLtHighlight
+ = new SystemColor(CONTROL_LT_HIGHLIGHT);
+
+ /** The control shadow color. */
+ public static final SystemColor controlShadow
+ = new SystemColor(CONTROL_SHADOW);
+
+ /** The control dark shadow color. */
+ public static final SystemColor controlDkShadow
+ = new SystemColor(CONTROL_DK_SHADOW);
+
+ /** The scrollbar color. */
+ public static final SystemColor scrollbar
+ = new SystemColor(SCROLLBAR);
+
+ /** The info text background color. */
+ public static final SystemColor info
+ = new SystemColor(INFO);
+
+ /** The info text foreground color. */
+ public static final SystemColor infoText
+ = new SystemColor(INFO_TEXT);
+
+ /**
+ * Construct a system color which is dynamically updated.
+ *
+ * @param id the color id
+ */
+ private SystemColor(int id)
+ {
+ // Note: See Color#Color(int, boolean) to explain why we use this
+ // particular constructor.
+ super(id, true);
+ }
+
+ /**
+ * Returns the RGB value for this color, in the sRGB color space. The blue
+ * value will be in bits 0-7, green in 8-15, red in 6-23, and the alpha
+ * value (bits 24-31) is 0xff. This is dynamically updated, so it may not
+ * match the results of <code>getRed()</code>, <code>getGreen()</code>, or
+ * <code>getBlue()</code>.
+ *
+ * @return the current RGB value
+ */
+ public int getRGB()
+ {
+ Toolkit.getDefaultToolkit().loadSystemColors(colors);
+ return colors[value] | ALPHA_MASK;
+ }
+
+ /**
+ * Returns a paint context, used for filling areas of a raster scan with
+ * the current value of this system color. Since the system colors may be
+ * dynamically updated, the returned value may not always be the same; but
+ * as the system color is solid, the context does not need any of the
+ * passed parameters to do its job.
+ *
+ * @param cm the requested color model
+ * @param deviceBounds the bounding box in device coordinates, ignored
+ * @param userBounds the bounding box in user coordinates, ignored
+ * @param xform the bounds transformation, ignored
+ * @param hints any rendering hints, ignored
+ * @return a context for painting this solid color
+ */
+ public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+ Rectangle2D userBounds,
+ AffineTransform xform,
+ RenderingHints hints)
+ {
+ Toolkit.getDefaultToolkit().loadSystemColors(colors);
+ int color = colors[value] | ALPHA_MASK;
+ if (context == null || color != context.color || !context.getColorModel().equals(cm))
+ context = new ColorPaintContext(cm,color);
+ return context;
+ }
+
+ /**
+ * Returns a string describing this color. This is in the format
+ * "java.awt.SystemColor[i=" + index + ']', where index is one of the
+ * integer constants of this class. Unfortunately, this description
+ * does not describe the current value of the color; for that you should
+ * use <code>new Color(syscolor.getRGB()).toString()</code>.
+ *
+ * @return a string describing this color
+ */
+ public String toString()
+ {
+ return "java.awt.SystemColor[i=" + value + ']';
+ }
+} // class SystemColor
diff --git a/libjava/classpath/java/awt/TextArea.java b/libjava/classpath/java/awt/TextArea.java
new file mode 100644
index 0000000..d422d33
--- /dev/null
+++ b/libjava/classpath/java/awt/TextArea.java
@@ -0,0 +1,629 @@
+/* TextArea.java -- A multi-line text entry component
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.KeyEvent;
+import java.awt.peer.ComponentPeer;
+import java.awt.peer.TextAreaPeer;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleStateSet;
+
+
+/**
+ * A TextArea is a text component capable of displaying multiple lines
+ * of user-editable text. A TextArea handles its own scrolling and
+ * can display vertical and horizontal scrollbars as navigation aids.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class TextArea extends TextComponent implements java.io.Serializable
+{
+ /**
+ * Display both horiztonal and vertical scroll bars.
+ */
+ public static final int SCROLLBARS_BOTH = 0;
+
+ /**
+ * Display vertical scroll bar only.
+ */
+ public static final int SCROLLBARS_VERTICAL_ONLY = 1;
+
+ /**
+ * Display horizatonal scroll bar only.
+ */
+ public static final int SCROLLBARS_HORIZONTAL_ONLY = 2;
+
+ /**
+ * Do not display scrollbars.
+ */
+ public static final int SCROLLBARS_NONE = 3;
+
+ /**
+ * Serialization constant.
+ */
+ private static final long serialVersionUID = 3692302836626095722L;
+
+ /**
+ * @serial The number of columns used in this text area's preferred
+ * and minimum size calculations.
+ */
+ private int columns;
+
+ /**
+ * @serial The number of rows used in this text area's preferred and
+ * minimum size calculations.
+ */
+ private int rows;
+
+ /**
+ * @serial The scrollbar display policy. One of SCROLLBARS_BOTH,
+ * SCROLLBARS_VERTICAL_ONLY, SCROLLBARS_HORIZONTAL_ONLY,
+ * SCROLLBARS_NONE.
+ */
+ private int scrollbarVisibility;
+
+ /*
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_text_number;
+
+ /**
+ * Initialize a new instance of <code>TextArea</code> that is empty.
+ * Conceptually the <code>TextArea</code> has 0 rows and 0 columns
+ * but its initial bounds are defined by its peer or by the
+ * container in which it is packed. Both horizontal and vertical
+ * scrollbars will be displayed.
+ *
+ * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+ */
+ public TextArea ()
+ {
+ this ("", 0, 0, SCROLLBARS_BOTH);
+ }
+
+ /**
+ * Initialize a new instance of <code>TextArea</code> that contains
+ * the specified text. Conceptually the <code>TextArea</code> has 0
+ * rows and 0 columns but its initial bounds are defined by its peer
+ * or by the container in which it is packed. Both horizontal and
+ * veritcal scrollbars will be displayed.
+ *
+ * @param text The text to display in this text area.
+ *
+ * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+ */
+ public TextArea (String text)
+ {
+ this (text, 0, 0, SCROLLBARS_BOTH);
+ }
+
+ /**
+ * Initialize a new instance of <code>TextArea</code> that is empty
+ * and can display the specified number of rows and columns of text,
+ * without the need to scroll. Both horizontal and vertical
+ * scrollbars will be displayed.
+ *
+ * @param rows The number of rows in this text area.
+ * @param columns The number of columns in this text area.
+ *
+ * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+ */
+ public TextArea (int rows, int columns)
+ {
+ this ("", rows, columns, SCROLLBARS_BOTH);
+ }
+
+ /**
+ * Initialize a new instance of <code>TextArea</code> that can
+ * display the specified number of rows and columns of text, without
+ * the need to scroll. The TextArea initially contains the
+ * specified text.
+ *
+ * @param text The text to display in this text area.
+ * @param rows The number of rows in this text area.
+ * @param columns The number of columns in this text area.
+ *
+ * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+ */
+ public TextArea (String text, int rows, int columns)
+ {
+ this (text, rows, columns, SCROLLBARS_BOTH);
+ }
+
+ /**
+ * Initialize a new instance of <code>TextArea</code> that initially
+ * contains the specified text. The TextArea can display the
+ * specified number of rows and columns of text, without the need to
+ * scroll. This constructor allows specification of the scroll bar
+ * display policy.
+ *
+ * @param text The text to display in this text area.
+ * @param rows The number of rows in this text area.
+ * @param columns The number of columns in this text area.
+ * @param scrollbarVisibility The scroll bar display policy. One of
+ * SCROLLBARS_BOTH, SCROLLBARS_VERTICAL_ONLY,
+ * SCROLLBARS_HORIZONTAL_ONLY, SCROLLBARS_NONE.
+ *
+ * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+ */
+ public TextArea (String text, int rows, int columns, int scrollbarVisibility)
+ {
+ super (text);
+
+ if (GraphicsEnvironment.isHeadless ())
+ throw new HeadlessException ();
+
+ if (rows < 0 || columns < 0)
+ throw new IllegalArgumentException ("Bad row or column value");
+
+ if (scrollbarVisibility != SCROLLBARS_BOTH
+ && scrollbarVisibility != SCROLLBARS_VERTICAL_ONLY
+ && scrollbarVisibility != SCROLLBARS_HORIZONTAL_ONLY
+ && scrollbarVisibility != SCROLLBARS_NONE)
+ throw new IllegalArgumentException ("Bad scrollbar visibility value");
+
+ this.rows = rows;
+ this.columns = columns;
+ this.scrollbarVisibility = scrollbarVisibility;
+
+ // TextAreas need to receive tab key events so we override the
+ // default forward and backward traversal key sets.
+ Set s = new HashSet ();
+ s.add (AWTKeyStroke.getAWTKeyStroke (KeyEvent.VK_TAB,
+ KeyEvent.CTRL_DOWN_MASK));
+ setFocusTraversalKeys (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, s);
+ s = new HashSet ();
+ s.add (AWTKeyStroke.getAWTKeyStroke (KeyEvent.VK_TAB,
+ KeyEvent.SHIFT_DOWN_MASK
+ | KeyEvent.CTRL_DOWN_MASK));
+ setFocusTraversalKeys (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, s);
+ }
+
+ /**
+ * Retrieve the number of columns that this text area would prefer
+ * to display. This value may or may not correspond to the number
+ * of columns that are actually displayed.
+ *
+ * @return The preferred number of columns.
+ */
+ public int getColumns ()
+ {
+ return columns;
+ }
+
+ /**
+ * Set the preferred number of columns for this text area. This
+ * method does not cause the number of columns displayed by the text
+ * area to be updated, if the text area is currently visible.
+ *
+ * @param columns The preferred number of columns.
+ *
+ * @exception IllegalArgumentException If columns is less than zero.
+ */
+ public synchronized void setColumns (int columns)
+ {
+ if (columns < 0)
+ throw new IllegalArgumentException ("Value is less than zero: "
+ + columns);
+
+ this.columns = columns;
+ }
+
+ /**
+ * Retrieve the number of rows that this text area would prefer to
+ * display. This value may or may not correspond to the number of
+ * rows that are actually displayed.
+ *
+ * @return The preferred number of rows.
+ */
+ public int getRows ()
+ {
+ return rows;
+ }
+
+ /**
+ * Set the preferred number of rows for this text area. This method
+ * does not cause the number of columns displayed by the text area
+ * to be updated, if the text area is currently visible.
+ *
+ * @param rows The preferred number of rows.
+ *
+ * @exception IllegalArgumentException If rows is less than zero.
+ */
+ public synchronized void setRows (int rows)
+ {
+ if (rows < 1)
+ throw new IllegalArgumentException ("Value is less than one: " + rows);
+
+ this.rows = rows;
+ }
+
+ /**
+ * Retrieve the minimum size for this text area, considering the
+ * text area's current row and column values. A text area's minimum
+ * size depends on the number of rows and columns of text it would
+ * prefer to display, and on the size of the font in which the text
+ * would be displayed.
+ *
+ * @return The minimum size for this text field.
+ */
+ public Dimension getMinimumSize ()
+ {
+ return getMinimumSize (getRows (), getColumns ());
+ }
+
+ /**
+ * Retrieve the minimum size that this text area would have if its
+ * row and column values were equal to those specified. A text
+ * area's minimum size depends on the number of rows and columns of
+ * text it would prefer to display, and on the size of the font in
+ * which the text would be displayed.
+ *
+ * @param rows The number of rows to use in the minimum size
+ * calculation.
+ * @param columns The number of columns to use in the minimum size
+ * calculation.
+ *
+ * @return The minimum size for this text area.
+ */
+ public Dimension getMinimumSize (int rows, int columns)
+ {
+ return minimumSize (rows, columns);
+ }
+
+ /**
+ * Retrieve the minimum size for this text area, considering the
+ * text area's current row and column values. A text area's minimum
+ * size depends on the number of rows and columns of text it would
+ * prefer to display, and on the size of the font in which the text
+ * would be displayed.
+ *
+ * @return The minimum size for this text area.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMinimumSize ()</code>.
+ */
+ public Dimension minimumSize ()
+ {
+ return minimumSize (getRows (), getColumns ());
+ }
+
+ /**
+ * Retrieve the minimum size that this text area would have if its
+ * row and column values were equal to those specified. A text
+ * area's minimum size depends on the number of rows and columns of
+ * text it would prefer to display, and on the size of the font in
+ * which the text would be displayed.
+ *
+ * @param rows The number of rows to use in the minimum size
+ * calculation.
+ * @param columns The number of columns to use in the minimum size
+ * calculation.
+ *
+ * @return The minimum size for this text area.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMinimumSize (int, int)</code>.
+ */
+ public Dimension minimumSize (int rows, int columns)
+ {
+ TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+ // Sun returns Dimension (0,0) in this case.
+ if (peer == null)
+ return new Dimension (0, 0);
+
+ return peer.getMinimumSize (rows, columns);
+ }
+
+ /**
+ * Retrieve the preferred size for this text area, considering the
+ * text area's current row and column values. A text area's preferred
+ * size depends on the number of rows and columns of text it would
+ * prefer to display, and on the size of the font in which the text
+ * would be displayed.
+ *
+ * @return The preferred size for this text field.
+ */
+ public Dimension getPreferredSize ()
+ {
+ return getPreferredSize (getRows (), getColumns ());
+ }
+
+ /**
+ * Retrieve the preferred size that this text area would have if its
+ * row and column values were equal to those specified. A text
+ * area's preferred size depends on the number of rows and columns
+ * of text it would prefer to display, and on the size of the font
+ * in which the text would be displayed.
+ *
+ * @param rows The number of rows to use in the preferred size
+ * calculation.
+ * @param columns The number of columns to use in the preferred size
+ * calculation.
+ *
+ * @return The preferred size for this text area.
+ */
+ public Dimension getPreferredSize (int rows, int columns)
+ {
+ return preferredSize (rows, columns);
+ }
+
+ /**
+ * Retrieve the preferred size for this text area, considering the
+ * text area's current row and column values. A text area's preferred
+ * size depends on the number of rows and columns of text it would
+ * prefer to display, and on the size of the font in which the text
+ * would be displayed.
+ *
+ * @return The preferred size for this text field.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getPreferredSize ()</code>.
+ */
+ public Dimension preferredSize ()
+ {
+ return preferredSize (getRows (), getColumns ());
+ }
+
+ /**
+ * Retrieve the preferred size that this text area would have if its
+ * row and column values were equal to those specified. A text
+ * area's preferred size depends on the number of rows and columns
+ * of text it would prefer to display, and on the size of the font
+ * in which the text would be displayed.
+ *
+ * @param rows The number of rows to use in the preferred size
+ * calculation.
+ * @param columns The number of columns to use in the preferred size
+ * calculation.
+ *
+ * @return The preferred size for this text area.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getPreferredSize (int, int)</code>.
+ */
+ public Dimension preferredSize (int rows, int columns)
+ {
+ TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+ // Sun returns Dimension (0,0) in this case.
+ if (peer == null)
+ return new Dimension (0, 0);
+
+ return peer.getPreferredSize (rows, columns);
+ }
+
+ /**
+ * Retrieve the scroll bar display policy -- one of SCROLLBARS_BOTH,
+ * SCROLLBARS_VERTICAL_ONLY, SCROLLBARS_HORIZONTAL_ONLY,
+ * SCROLLBARS_NONE.
+ *
+ * @return The current scroll bar display policy.
+ */
+ public int getScrollbarVisibility ()
+ {
+ return scrollbarVisibility;
+ }
+
+ /**
+ * Notify this object that it should create its native peer.
+ */
+ public void addNotify ()
+ {
+ if (getPeer () == null)
+ setPeer ((ComponentPeer) getToolkit().createTextArea (this));
+ }
+
+ /**
+ * Append the specified text to the end of the current text.
+ *
+ * @param str The text to append.
+ */
+ public void append (String str)
+ {
+ appendText (str);
+ }
+
+ /**
+ * Append the specified text to the end of the current text.
+ *
+ * @param str The text to append.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>append ()</code>.
+ */
+ public void appendText (String str)
+ {
+ TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+ if (peer != null)
+ peer.insert (str, peer.getText().length ());
+ }
+
+ /**
+ * Insert the specified text at the specified position. The first
+ * character in the text area is at position zero.
+ *
+ * @param str The text to insert.
+ * @param pos The position at which to insert text.
+ */
+ public void insert (String str, int pos)
+ {
+ insertText (str, pos);
+ }
+
+ /**
+ * Insert the specified text at the specified position. The first
+ * character in the text area is at position zero.
+ *
+ * @param str The text to insert.
+ * @param pos The position at which to insert text.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>insert ()</code>.
+ */
+ public void insertText (String str, int pos)
+ {
+ TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+ if (peer != null)
+ peer.insert (str, pos);
+ }
+
+ /**
+ * Replace a range of characters with the specified text. The
+ * character at the start position will be replaced, unless start ==
+ * end. The character at the end posistion will not be replaced.
+ * The first character in the text area is at position zero. The
+ * length of the replacement text may differ from the length of the
+ * text that is replaced.
+ *
+ * @param str The new text for the range.
+ * @param start The start position of the replacement range.
+ * @param end The end position of the replacement range.
+ */
+ public void replaceRange (String str, int start, int end)
+ {
+ replaceText (str, start, end);
+ }
+
+ /**
+ * Replace a range of characters with the specified text. The
+ * character at the start position will be replaced, unless start ==
+ * end. The character at the end posistion will not be replaced.
+ * The first character in the text area is at position zero. The
+ * length of the replacement text may differ from the length of the
+ * text that is replaced.
+ *
+ * @param str The new text for the range.
+ * @param start The start position of the replacement range.
+ * @param end The end position of the replacement range.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>replaceRange ()</code>.
+ */
+ public void replaceText (String str, int start, int end)
+ {
+ TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+ if (peer != null)
+ peer.replaceRange (str, start, end);
+ }
+
+ /**
+ * Retrieve a debugging string for this text area.
+ *
+ * @return A debugging string for this text area.
+ */
+ protected String paramString ()
+ {
+ String sbVisibility = "";
+
+ switch (scrollbarVisibility)
+ {
+ case SCROLLBARS_BOTH:
+ sbVisibility = "both";
+ break;
+ case SCROLLBARS_VERTICAL_ONLY:
+ sbVisibility = "vertical-only";
+ break;
+ case SCROLLBARS_HORIZONTAL_ONLY:
+ sbVisibility = "horizontal-only";
+ break;
+ case SCROLLBARS_NONE:
+ sbVisibility = "none";
+ break;
+ }
+
+ String editable = "";
+ if (isEditable ())
+ editable = "editable,";
+
+ return getName () + "," + getX () + "," + getY () + "," + getWidth ()
+ + "x" + getHeight () + "," + "text=" + getText () + "," + editable
+ + "selection=" + getSelectionStart () + "-" + getSelectionEnd ()
+ + ",rows=" + rows + ",columns=" + columns + ",scrollbarVisibility="
+ + sbVisibility;
+ }
+
+ /**
+ * Generate a unique name for this text area.
+ *
+ * @return A unique name for this text area.
+ */
+ String generateName ()
+ {
+ return "text" + getUniqueLong ();
+ }
+
+ private static synchronized long getUniqueLong ()
+ {
+ return next_text_number++;
+ }
+
+ protected class AccessibleAWTTextArea extends AccessibleAWTTextComponent
+ {
+ protected AccessibleAWTTextArea()
+ {
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ return super.getAccessibleStateSet();
+ }
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>TextArea</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTTextArea();
+ return accessibleContext;
+ }
+}
diff --git a/libjava/classpath/java/awt/TextComponent.java b/libjava/classpath/java/awt/TextComponent.java
new file mode 100644
index 0000000..9edbd88
--- /dev/null
+++ b/libjava/classpath/java/awt/TextComponent.java
@@ -0,0 +1,739 @@
+/* TextComponent.java -- Widgets for entering text
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.TextEvent;
+import java.awt.event.TextListener;
+import java.awt.peer.TextComponentPeer;
+import java.io.Serializable;
+import java.text.BreakIterator;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleText;
+import javax.swing.text.AttributeSet;
+
+/**
+ * This class provides common functionality for widgets than
+ * contain text.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class TextComponent extends Component
+ implements Serializable, Accessible
+{
+
+/*
+ * Static Variables
+ */
+
+// Constant for serialization
+private static final long serialVersionUID = -2214773872412987419L;
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial Indicates whether or not this component is editable.
+ * This is package-private to avoid an accessor method.
+ */
+boolean editable;
+
+/**
+ * @serial The starting position of the selected text region.
+ * This is package-private to avoid an accessor method.
+ */
+int selectionStart;
+
+/**
+ * @serial The ending position of the selected text region.
+ * This is package-private to avoid an accessor method.
+ */
+int selectionEnd;
+
+/**
+ * @serial The text in the component
+ * This is package-private to avoid an accessor method.
+ */
+String text;
+
+/**
+ * A list of listeners that will receive events from this object.
+ */
+protected transient TextListener textListener;
+
+ protected class AccessibleAWTTextComponent
+ extends AccessibleAWTComponent
+ implements AccessibleText, TextListener
+ {
+ // Constructor
+ // Adds a listener for tracking caret changes
+ public AccessibleAWTTextComponent()
+ {
+ TextComponent.this.addTextListener(this);
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.TEXT;
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ // TODO: Docs say PropertyChangeEvent will fire if this state changes.
+ // That means that the event has to fire when editable changes.
+ AccessibleStateSet ss = super.getAccessibleStateSet();
+ if (editable)
+ ss.add(AccessibleState.EDITABLE);
+ return ss;
+ }
+
+ public AccessibleText getAccessibleText()
+ {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getIndexAtPoint(java.awt.Point)
+ */
+ public int getIndexAtPoint(Point point)
+ {
+ return TextComponent.this.getIndexAtPoint(point);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getCharacterBounds(int)
+ */
+ public Rectangle getCharacterBounds(int index)
+ {
+ return TextComponent.this.getCharacterBounds(index);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getCharCount()
+ */
+ public int getCharCount()
+ {
+ return text.length();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getCaretPosition()
+ */
+ public int getCaretPosition()
+ {
+ return TextComponent.this.getCaretPosition();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getAtIndex(int, int)
+ */
+ public String getAtIndex(int part, int index)
+ {
+ if (index < 0 || index >= text.length())
+ return null;
+ BreakIterator it = null;
+ switch (part)
+ {
+ case CHARACTER:
+ return text.substring(index, index + 1);
+ case WORD:
+ it = BreakIterator.getWordInstance();
+ break;
+ case SENTENCE:
+ it = BreakIterator.getSentenceInstance();
+ break;
+ default:
+ return null;
+ }
+ it.setText(text);
+ int start = index;
+ if (!it.isBoundary(index))
+ start = it.preceding(index);
+ int end = it.following(index);
+ if (end == -1)
+ return text.substring(index);
+ else
+ return text.substring(index, end);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getAfterIndex(int, int)
+ */
+ public String getAfterIndex(int part, int index) {
+ if (index < 0 || index >= text.length())
+ return null;
+ BreakIterator it = null;
+ switch (part)
+ {
+ case CHARACTER:
+ return text.substring(index, index + 1);
+ case WORD:
+ it = BreakIterator.getWordInstance();
+ break;
+ case SENTENCE:
+ it = BreakIterator.getSentenceInstance();
+ break;
+ default:
+ return null;
+ }
+ it.setText(text);
+ int start = index;
+ if (!it.isBoundary(index))
+ start = it.following(index);
+ // Make sure there was a complete unit. I.e. if index is in the middle
+ // of a word, return null if there is no word after the that one.
+ if (start == -1)
+ return null;
+ int end = it.following(start);
+ if (end == -1)
+ return text.substring(index);
+ else
+ return text.substring(index, end);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getBeforeIndex(int, int)
+ */
+ public String getBeforeIndex(int part, int index)
+ {
+ if (index < 1 || index >= text.length())
+ return null;
+ BreakIterator it = null;
+ switch (part)
+ {
+ case CHARACTER:
+ return text.substring(index - 1, index);
+ case WORD:
+ it = BreakIterator.getWordInstance();
+ break;
+ case SENTENCE:
+ it = BreakIterator.getSentenceInstance();
+ break;
+ default:
+ return null;
+ }
+ it.setText(text);
+ int end = index;
+ if (!it.isBoundary(index))
+ end = it.preceding(index);
+ // Make sure there was a complete unit. I.e. if index is in the middle
+ // of a word, return null if there is no word before that one.
+ if (end == -1)
+ return null;
+ int start = it.preceding(end);
+ if (start == -1)
+ return text.substring(0, end);
+ else
+ return text.substring(start, end);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getCharacterAttribute(int)
+ */
+ public AttributeSet getCharacterAttribute(int index)
+ {
+ // FIXME: I suspect this really gets filled in by subclasses.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getSelectionStart()
+ */
+ public int getSelectionStart() {
+ // TODO Auto-generated method stub
+ return selectionStart;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getSelectionEnd()
+ */
+ public int getSelectionEnd()
+ {
+ return selectionEnd;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getSelectedText()
+ */
+ public String getSelectedText()
+ {
+ if (selectionEnd - selectionStart > 0)
+ return text.substring(selectionStart, selectionEnd);
+ else
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.TextListener#textValueChanged(java.awt.event.TextEvent)
+ */
+ public void textValueChanged(TextEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+TextComponent(String text)
+{
+ this.text = text;
+ this.editable = true;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the text in this component
+ *
+ * @return The text in this component.
+ */
+public synchronized String
+getText()
+{
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ text = tcp.getText();
+
+ return(text);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the text in this component to the specified string.
+ *
+ * @param text The new text for this component.
+ */
+public synchronized void
+setText(String text)
+{
+ if (text == null)
+ text = "";
+
+ this.text = text;
+
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ tcp.setText(text);
+ setCaretPosition(0);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a string that contains the text that is currently selected.
+ *
+ * @return The currently selected text region.
+ */
+public synchronized String
+getSelectedText()
+{
+ String alltext = getText();
+ int start = getSelectionStart();
+ int end = getSelectionEnd();
+
+ return(alltext.substring(start, end));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the starting position of the selected text region.
+ * If the text is not selected then caret position is returned.
+ *
+ * @return The starting position of the selected text region.
+ */
+public synchronized int
+getSelectionStart()
+{
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ selectionStart = tcp.getSelectionStart();
+
+ return(selectionStart);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the starting position of the selected region to the
+ * specified value. If the specified value is out of range, then it
+ * will be silently changed to the nearest legal value.
+ *
+ * @param selectionStart The new start position for selected text.
+ */
+public synchronized void
+setSelectionStart(int selectionStart)
+{
+ select(selectionStart, getSelectionEnd());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the ending position of the selected text region.
+ * If the text is not selected, then caret position is returned
+ *
+ * @return The ending position of the selected text region.
+ */
+public synchronized int
+getSelectionEnd()
+{
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ selectionEnd = tcp.getSelectionEnd();
+
+ return(selectionEnd);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the ending position of the selected region to the
+ * specified value. If the specified value is out of range, then it
+ * will be silently changed to the nearest legal value.
+ *
+ * @param selectionEnd The new start position for selected text.
+ */
+public synchronized void
+setSelectionEnd(int selectionEnd)
+{
+ select(getSelectionStart(), selectionEnd);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the selected text range to the text between the
+ * specified start and end positions. Illegal values for these
+ * positions are silently fixed.
+ *
+ * @param selectionStart The new start position for the selected text.
+ * @param selectionEnd The new end position for the selected text.
+ */
+public synchronized void
+select(int selectionStart, int selectionEnd)
+{
+ if (selectionStart < 0)
+ selectionStart = 0;
+
+ if (selectionStart > getText().length())
+ selectionStart = text.length();
+
+ if (selectionEnd > text.length())
+ selectionEnd = text.length();
+
+ if (selectionStart > getSelectionEnd())
+ selectionStart = selectionEnd;
+
+ this.selectionStart = selectionStart;
+ this.selectionEnd = selectionEnd;
+
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ tcp.select(selectionStart, selectionEnd);
+}
+
+/*************************************************************************/
+
+/**
+ * Selects all of the text in the component.
+ */
+public synchronized void
+selectAll()
+{
+ select(0, getText().length());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the current caret position in the text.
+ *
+ * @return The caret position in the text.
+ */
+public synchronized int
+getCaretPosition()
+{
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ return(tcp.getCaretPosition());
+ else
+ return(0);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the caret position to the specified value.
+ *
+ * @param caretPosition The new caret position.
+ *
+ * @exception IllegalArgumentException If the value supplied for position
+ * is less than zero.
+ *
+ * @since 1.1
+ */
+public synchronized void
+setCaretPosition(int caretPosition)
+{
+ if (caretPosition < 0)
+ throw new IllegalArgumentException ();
+
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ tcp.setCaretPosition(caretPosition);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this component's text can be edited.
+ *
+ * @return <code>true</code> if the text can be edited, <code>false</code>
+ * otherwise.
+ */
+public boolean
+isEditable()
+{
+ return(editable);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets whether or not this component's text can be edited.
+ *
+ * @param editable <code>true</code> to enable editing of the text,
+ * <code>false</code> to disable it.
+ */
+public synchronized void
+setEditable(boolean editable)
+{
+ this.editable = editable;
+
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ tcp.setEditable(editable);
+}
+
+/*************************************************************************/
+
+/**
+ * Notifies the component that it should destroy its native peer.
+ */
+public void
+removeNotify()
+{
+ super.removeNotify();
+}
+
+/*************************************************************************/
+
+/**
+ * Adds a new listener to the list of text listeners for this
+ * component.
+ *
+ * @param listener The listener to be added.
+ */
+public synchronized void
+addTextListener(TextListener listener)
+{
+ textListener = AWTEventMulticaster.add(textListener, listener);
+
+ enableEvents(AWTEvent.TEXT_EVENT_MASK);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified listener from the list of listeners
+ * for this component.
+ *
+ * @param listener The listener to remove.
+ */
+public synchronized void
+removeTextListener(TextListener listener)
+{
+ textListener = AWTEventMulticaster.remove(textListener, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes the specified event for this component. Text events are
+ * processed by calling the <code>processTextEvent()</code> method.
+ * All other events are passed to the superclass method.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ if (event instanceof TextEvent)
+ processTextEvent((TextEvent)event);
+ else
+ super.processEvent(event);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes the specified text event by dispatching it to any listeners
+ * that are registered. Note that this method will only be called
+ * if text event's are enabled. This will be true if there are any
+ * registered listeners, or if the event has been specifically
+ * enabled using <code>enableEvents()</code>.
+ *
+ * @param event The text event to process.
+ */
+protected void
+processTextEvent(TextEvent event)
+{
+ if (textListener != null)
+ textListener.textValueChanged(event);
+}
+
+void
+dispatchEventImpl(AWTEvent e)
+{
+ if (e.id <= TextEvent.TEXT_LAST
+ && e.id >= TextEvent.TEXT_FIRST
+ && (textListener != null
+ || (eventMask & AWTEvent.TEXT_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debugging string.
+ *
+ * @return A debugging string.
+ */
+protected String
+paramString()
+{
+ return(getClass().getName() + "(text=" + getText() + ")");
+}
+
+ /**
+ * Returns an array of all the objects currently registered as FooListeners
+ * upon this <code>TextComponent</code>. FooListeners are registered using
+ * the addFooListener method.
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements java.util.EventListener.
+ */
+ public EventListener[] getListeners (Class listenerType)
+ {
+ if (listenerType == TextListener.class)
+ return AWTEventMulticaster.getListeners (textListener, listenerType);
+
+ return super.getListeners (listenerType);
+ }
+
+ /**
+ * Returns all text listeners registered to this object.
+ */
+ public TextListener[] getTextListeners ()
+ {
+ return (TextListener[]) getListeners (TextListener.class);
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>TextComponent</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTTextComponent();
+ return accessibleContext;
+ }
+
+
+ /*******************************/
+ // Provide AccessibleAWTTextComponent access to several peer functions that
+ // aren't publicly exposed. This is package-private to avoid an accessor
+ // method.
+ synchronized int
+ getIndexAtPoint(Point p)
+ {
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ return tcp.getIndexAtPoint(p.x, p.y);
+ return -1;
+ }
+
+ synchronized Rectangle
+ getCharacterBounds(int i)
+ {
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ return tcp.getCharacterBounds(i);
+ return null;
+ }
+
+
+
+
+} // class TextComponent
+
diff --git a/libjava/classpath/java/awt/TextField.java b/libjava/classpath/java/awt/TextField.java
new file mode 100644
index 0000000..4d62d02
--- /dev/null
+++ b/libjava/classpath/java/awt/TextField.java
@@ -0,0 +1,541 @@
+/* TextField.java -- A one line text entry field
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.peer.ComponentPeer;
+import java.awt.peer.TextFieldPeer;
+import java.util.EventListener;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleStateSet;
+
+/**
+ * This class implements a single line text entry field widget
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class TextField extends TextComponent
+{
+
+/*
+ * Static Variables
+ */
+
+// Serialization constant
+private static final long serialVersionUID = -2966288784432217853L;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * @serial The number of columns in the text entry field.
+ */
+private int columns;
+
+/**
+ * @serial The character that is echoed when doing protected input
+ */
+private char echoChar;
+
+// List of registered ActionListener's for this object.
+private ActionListener action_listeners;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Initializes a new instance of <code>TextField</code> that is empty
+ * and has one column.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+public
+TextField()
+{
+ this("", 1);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>TextField</code> containing
+ * the specified text. The number of columns will be equal to the
+ * length of the text string.
+ *
+ * @param text The text to display in the field.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+public
+TextField(String text)
+{
+ this(text, text.length());
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>TextField</code> that is empty
+ * and has the specified number of columns.
+ *
+ * @param columns The number of columns in the text field.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+public
+TextField(int columns)
+{
+ this("", columns);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>TextField</code> with the
+ * specified text and number of columns.
+ *
+ * @param text The text to display in the field.
+ * @param columns The number of columns in the field.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+public
+TextField(String text, int columns)
+{
+ super(text);
+ this.columns = columns;
+
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the number of columns in the field.
+ *
+ * @return The number of columns in the field.
+ */
+public int
+getColumns()
+{
+ return(columns);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the number of columns in this field to the specified value.
+ *
+ * @param columns The new number of columns in the field.
+ *
+ * @exception IllegalArgumentException If columns is less than zero.
+ */
+public synchronized void
+setColumns(int columns)
+{
+ if (columns < 0)
+ throw new IllegalArgumentException("Value is less than zero: " +
+ columns);
+
+ this.columns = columns;
+ // FIXME: How to we communicate this to our peer?
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the character that is echoed to the screen when a text
+ * field is protected (such as when a password is being entered).
+ *
+ * @return The echo character for this text field.
+ */
+public char
+getEchoChar()
+{
+ return(echoChar);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the character that is echoed when protected input such as
+ * a password is displayed.
+ *
+ * @param echoChar The new echo character.
+ */
+public void
+setEchoChar(char echoChar)
+{
+ setEchoCharacter (echoChar);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the character that is echoed when protected input such as
+ * a password is displayed.
+ *
+ * @param echoChar The new echo character.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>setEchoChar()</code>
+ */
+public void
+setEchoCharacter(char echoChar)
+{
+ this.echoChar = echoChar;
+
+ TextFieldPeer peer = (TextFieldPeer) getPeer ();
+ if (peer != null)
+ peer.setEchoChar (echoChar);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this text field has an echo character set
+ * so that characters the user type are not echoed to the screen.
+ *
+ * @return <code>true</code> if an echo character is set,
+ * <code>false</code> otherwise.
+ */
+public boolean
+echoCharIsSet()
+{
+ if (echoChar == '\u0000')
+ return(false);
+ else
+ return(true);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size for this text field.
+ *
+ * @return The minimum size for this text field.
+ */
+public Dimension
+getMinimumSize()
+{
+ return getMinimumSize (getColumns ());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size of a text field with the specified number
+ * of columns.
+ *
+ * @param columns The number of columns to get the minimum size for.
+ */
+public Dimension
+getMinimumSize(int columns)
+{
+ return minimumSize (columns);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size for this text field.
+ *
+ * @return The minimum size for this text field.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMinimumSize()</code>.
+ */
+public Dimension
+minimumSize()
+{
+ return minimumSize (getColumns ());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the minimum size of a text field with the specified number
+ * of columns.
+ *
+ * @param columns The number of columns to get the minimum size for.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMinimumSize(int)</code>.
+ */
+public Dimension
+minimumSize(int columns)
+{
+ TextFieldPeer peer = (TextFieldPeer) getPeer ();
+ if (peer == null)
+ return null; // FIXME: What do we do if there is no peer?
+
+ return peer.getMinimumSize (columns);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size for this text field.
+ *
+ * @return The preferred size for this text field.
+ */
+public Dimension
+getPreferredSize()
+{
+ return getPreferredSize (getColumns ());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size of a text field with the specified number
+ * of columns.
+ *
+ * @param columns The number of columns to get the preferred size for.
+ */
+public Dimension
+getPreferredSize(int columns)
+{
+ return preferredSize (columns);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size for this text field.
+ *
+ * @return The preferred size for this text field.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getPreferredSize()</code>.
+ */
+public Dimension
+preferredSize()
+{
+ return preferredSize (getColumns ());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the preferred size of a text field with the specified number
+ * of columns.
+ *
+ * @param columns The number of columns to get the preferred size for.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getPreferredSize(int)</code>.
+ */
+public Dimension
+preferredSize(int columns)
+{
+ TextFieldPeer peer = (TextFieldPeer) getPeer ();
+ if (peer == null)
+ return new Dimension (0, 0);
+
+ return peer.getPreferredSize (columns);
+}
+
+/*************************************************************************/
+
+/**
+ * Notifies this object that it should create its native peer.
+ */
+public void
+addNotify()
+{
+ if (getPeer() != null)
+ return;
+
+ setPeer((ComponentPeer)getToolkit().createTextField(this));
+}
+
+/*************************************************************************/
+
+/**
+ * Addes a new listener to the list of action listeners for this
+ * object.
+ *
+ * @param listener The listener to add to the list.
+ */
+public synchronized void
+addActionListener(ActionListener listener)
+{
+ action_listeners = AWTEventMulticaster.add(action_listeners, listener);
+
+ enableEvents(AWTEvent.ACTION_EVENT_MASK);
+}
+
+/*************************************************************************/
+
+/**
+ * Removes the specified listener from the list of action listeners
+ * for this object.
+ *
+ * @param listener The listener to remove from the list.
+ */
+public synchronized void
+removeActionListener(ActionListener listener)
+{
+ action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes the specified event. If the event is an instance of
+ * <code>ActionEvent</code> then <code>processActionEvent()</code> is
+ * called to process it, otherwise the event is sent to the
+ * superclass.
+ *
+ * @param event The event to process.
+ */
+protected void
+processEvent(AWTEvent event)
+{
+ if (event instanceof ActionEvent)
+ processActionEvent((ActionEvent)event);
+ else
+ super.processEvent(event);
+}
+
+/*************************************************************************/
+
+/**
+ * Processes an action event by calling any registered listeners.
+ * Note to subclasses: This method is not called unless action events
+ * are enabled on this object. This will be true if any listeners
+ * are registered, or if action events were specifically enabled
+ * using <code>enableEvents()</code>.
+ *
+ * @param event The event to process.
+ */
+protected void
+processActionEvent(ActionEvent event)
+{
+ if (action_listeners != null)
+ action_listeners.actionPerformed(event);
+}
+
+void
+dispatchEventImpl(AWTEvent e)
+{
+ if (e.id <= ActionEvent.ACTION_LAST
+ && e.id >= ActionEvent.ACTION_FIRST
+ && (action_listeners != null
+ || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a debug string for this object.
+ *
+ * @return A debug string for this object.
+ */
+protected String
+paramString()
+{
+ return(getClass().getName() + "(columns=" + getColumns() + ",echoChar=" +
+ getEchoChar());
+}
+
+ /**
+ * Returns an array of all the objects currently registered as FooListeners
+ * upon this <code>TextField</code>. FooListeners are registered using the
+ * addFooListener method.
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements java.util.EventListener.
+ *
+ * @since 1.3
+ */
+ public EventListener[] getListeners (Class listenerType)
+ {
+ if (listenerType == ActionListener.class)
+ return AWTEventMulticaster.getListeners (action_listeners, listenerType);
+
+ return super.getListeners (listenerType);
+ }
+
+ /**
+ * Return all ActionListeners register to this <code>TextField</code> object
+ * as an array.
+ *
+ * @since 1.4
+ */
+ public ActionListener[] getActionListeners ()
+ {
+ return (ActionListener[]) getListeners (ActionListener.class);
+ }
+
+ protected class AccessibleAWTTextField extends AccessibleAWTTextComponent
+ {
+ protected AccessibleAWTTextField()
+ {
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ return super.getAccessibleStateSet();
+ }
+ }
+
+ public AccessibleContext getAccessibleContext()
+ {
+ return new AccessibleAWTTextField();
+ }
+
+} // class TextField
diff --git a/libjava/classpath/java/awt/TexturePaint.java b/libjava/classpath/java/awt/TexturePaint.java
new file mode 100644
index 0000000..a12e384
--- /dev/null
+++ b/libjava/classpath/java/awt/TexturePaint.java
@@ -0,0 +1,75 @@
+/* TexturePaint.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+
+/** STUB CLASS ONLY */
+public class TexturePaint implements Paint
+{
+ private final BufferedImage texture;
+ private final Rectangle2D anchor;
+ public TexturePaint(BufferedImage texture, Rectangle2D anchor)
+ {
+ this.texture = texture;
+ this.anchor = anchor;
+ }
+ public BufferedImage getImage()
+ {
+ return texture;
+ }
+ public Rectangle2D getAnchorRect()
+ {
+ return anchor;
+ }
+ public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+ Rectangle2D userBounds,
+ AffineTransform xform,
+ RenderingHints hints)
+ {
+ throw new Error("not implemented");
+ }
+ public int getTransparency()
+ {
+ throw new Error("not implemented");
+ }
+} // class TexturePaint
diff --git a/libjava/classpath/java/awt/Toolkit.java b/libjava/classpath/java/awt/Toolkit.java
new file mode 100644
index 0000000..c7c6f9f
--- /dev/null
+++ b/libjava/classpath/java/awt/Toolkit.java
@@ -0,0 +1,995 @@
+/* Toolkit.java -- AWT Toolkit superclass
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.datatransfer.Clipboard;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.event.AWTEventListener;
+import java.awt.event.KeyEvent;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.ButtonPeer;
+import java.awt.peer.CanvasPeer;
+import java.awt.peer.CheckboxMenuItemPeer;
+import java.awt.peer.CheckboxPeer;
+import java.awt.peer.ChoicePeer;
+import java.awt.peer.DialogPeer;
+import java.awt.peer.FileDialogPeer;
+import java.awt.peer.FontPeer;
+import java.awt.peer.FramePeer;
+import java.awt.peer.LabelPeer;
+import java.awt.peer.LightweightPeer;
+import java.awt.peer.ListPeer;
+import java.awt.peer.MenuBarPeer;
+import java.awt.peer.MenuItemPeer;
+import java.awt.peer.MenuPeer;
+import java.awt.peer.PanelPeer;
+import java.awt.peer.PopupMenuPeer;
+import java.awt.peer.ScrollPanePeer;
+import java.awt.peer.ScrollbarPeer;
+import java.awt.peer.TextAreaPeer;
+import java.awt.peer.TextFieldPeer;
+import java.awt.peer.WindowPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.net.URL;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * The AWT system uses a set of native peer objects to implement its
+ * widgets. These peers are provided by a peer toolkit, that is accessed
+ * via a subclass of this superclass. The system toolkit is retrieved
+ * by the static methods <code>getDefaultToolkit</code>. This method
+ * determines the system toolkit by examining the system property
+ * <code>awt.toolkit</code>. That property is set to the name of the
+ * <code>Toolkit</code> subclass for the specified peer set. If the
+ * <code>awt.toolkit</code> property is not set, then the default
+ * toolkit <code>gnu.java.awt.peer.gtk.GtkToolkit</code> is used. This
+ * toolkit creates its peers using the GTK+ toolkit.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract class Toolkit
+{
+ /** The default toolkit name. */
+ private static String default_toolkit_name
+ = gnu.classpath.Configuration.default_awt_peer_toolkit;
+
+ /**
+ * The toolkit in use. Once we load it, we don't ever change it
+ * if the awt.toolkit property is set.
+ */
+ private static Toolkit toolkit;
+
+ /** The toolkit properties. */
+ private static Properties props = new Properties();
+
+ protected final Map desktopProperties = new Properties();
+
+ protected final PropertyChangeSupport desktopPropsSupport
+ = new PropertyChangeSupport(this);
+
+ /**
+ * Default constructor for subclasses.
+ */
+ public Toolkit()
+ {
+ }
+
+ /**
+ * Creates a peer object for the specified <code>Button</code>.
+ *
+ * @param target The <code>Button</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Button</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract ButtonPeer createButton(Button target);
+
+ /**
+ * Creates a peer object for the specified <code>TextField</code>.
+ *
+ * @param target The <code>TextField</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>TextField</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract TextFieldPeer createTextField(TextField target);
+
+ /**
+ * Creates a peer object for the specified <code>Label</code>.
+ *
+ * @param target The <code>Label</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Label</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract LabelPeer createLabel(Label target);
+
+ /**
+ * Creates a peer object for the specified <code>List</code>.
+ *
+ * @param target The <code>List</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>List</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract ListPeer createList(List target);
+
+ /**
+ * Creates a peer object for the specified <code>Checkbox</code>.
+ *
+ * @param target The <code>Checkbox</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Checkbox</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract CheckboxPeer createCheckbox(Checkbox target);
+
+ /**
+ * Creates a peer object for the specified <code>Scrollbar</code>.
+ *
+ * @param target The <code>Scrollbar</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Scrollbar</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract ScrollbarPeer createScrollbar(Scrollbar target);
+
+ /**
+ * Creates a peer object for the specified <code>ScrollPane</code>.
+ *
+ * @param target The <code>ScrollPane</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>ScrollPane</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract ScrollPanePeer createScrollPane(ScrollPane target);
+
+ /**
+ * Creates a peer object for the specified <code>TextArea</code>.
+ *
+ * @param target The <code>TextArea</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>TextArea</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract TextAreaPeer createTextArea(TextArea target);
+
+ /**
+ * Creates a peer object for the specified <code>Choice</code>.
+ *
+ * @param target The <code>Choice</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Choice</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract ChoicePeer createChoice(Choice target);
+
+ /**
+ * Creates a peer object for the specified <code>Frame</code>.
+ *
+ * @param target The <code>Frame</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Frame</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract FramePeer createFrame(Frame target);
+
+ /**
+ * Creates a peer object for the specified <code>Canvas</code>.
+ *
+ * @param target The <code>Canvas</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Canvas</code> object.
+ */
+ protected abstract CanvasPeer createCanvas(Canvas target);
+
+ /**
+ * Creates a peer object for the specified <code>Panel</code>.
+ *
+ * @param target The <code>Panel</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Panel</code> object.
+ */
+ protected abstract PanelPeer createPanel(Panel target);
+
+ /**
+ * Creates a peer object for the specified <code>Window</code>.
+ *
+ * @param target The <code>Window</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Window</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract WindowPeer createWindow(Window target);
+
+ /**
+ * Creates a peer object for the specified <code>Dialog</code>.
+ *
+ * @param target The dialog to create the peer for
+ *
+ * @return The peer for the specified font name.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract DialogPeer createDialog(Dialog target);
+
+ /**
+ * Creates a peer object for the specified <code>MenuBar</code>.
+ *
+ * @param target The <code>MenuBar</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>MenuBar</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract MenuBarPeer createMenuBar(MenuBar target);
+
+ /**
+ * Creates a peer object for the specified <code>Menu</code>.
+ *
+ * @param target The <code>Menu</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Menu</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract MenuPeer createMenu(Menu target);
+
+ /**
+ * Creates a peer object for the specified <code>PopupMenu</code>.
+ *
+ * @param target The <code>PopupMenu</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>PopupMenu</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract PopupMenuPeer createPopupMenu(PopupMenu target);
+
+ /**
+ * Creates a peer object for the specified <code>MenuItem</code>.
+ *
+ * @param target The <code>MenuItem</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>MenuItem</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract MenuItemPeer createMenuItem(MenuItem target);
+
+ /**
+ * Creates a peer object for the specified <code>FileDialog</code>.
+ *
+ * @param target The <code>FileDialog</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>FileDialog</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract FileDialogPeer createFileDialog(FileDialog target);
+
+ /**
+ * Creates a peer object for the specified <code>CheckboxMenuItem</code>.
+ *
+ * @param target The <code>CheckboxMenuItem</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>CheckboxMenuItem</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected abstract CheckboxMenuItemPeer
+ createCheckboxMenuItem(CheckboxMenuItem target);
+
+ /**
+ * Creates a peer object for the specified <code>Component</code>. The
+ * peer returned by this method is not a native windowing system peer
+ * with its own native window. Instead, this method allows the component
+ * to draw on its parent window as a "lightweight" widget.
+ *
+ * @param target The <code>Component</code> to create the peer for.
+ *
+ * @return The peer for the specified <code>Component</code> object.
+ */
+ protected LightweightPeer createComponent(Component target)
+ {
+ return new gnu.java.awt.peer.GLightweightPeer (target);
+ }
+
+ /**
+ * Creates a peer object for the specified font name.
+ *
+ * @param name The font to create the peer for.
+ * @param style The font style to create the peer for.
+ *
+ * @return The peer for the specified font name.
+ *
+ * @deprecated
+ */
+ protected abstract FontPeer getFontPeer(String name, int style);
+
+ /**
+ * Copies the current system colors into the specified array. This is
+ * the interface used by the <code>SystemColor</code> class. Although
+ * this method fills in the array with some default colors a real Toolkit
+ * should override this method and provide real system colors for the
+ * native GUI platform.
+ *
+ * @param systemColors The array to copy the system colors into.
+ * It must be at least 26 elements.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ *
+ * @see java.awt.SystemColor
+ */
+ protected void loadSystemColors(int systemColors[])
+ {
+ systemColors[SystemColor.DESKTOP] = 0xFF005C5C;
+ systemColors[SystemColor.ACTIVE_CAPTION] = 0xFF000080;
+ systemColors[SystemColor.ACTIVE_CAPTION_TEXT] = 0xFFFFFFFF;
+ systemColors[SystemColor.ACTIVE_CAPTION_BORDER] = 0xFFC0C0C0;
+ systemColors[SystemColor.INACTIVE_CAPTION] = 0xFF808080;
+ systemColors[SystemColor.INACTIVE_CAPTION_TEXT] = 0xFFC0C0C0;
+ systemColors[SystemColor.INACTIVE_CAPTION_BORDER] = 0xFFC0C0C0;
+ systemColors[SystemColor.WINDOW] = 0xFFFFFFFF;
+ systemColors[SystemColor.WINDOW_BORDER] = 0xFF000000;
+ systemColors[SystemColor.WINDOW_TEXT] = 0xFF000000;
+ systemColors[SystemColor.MENU] = 0xFFC0C0C0;
+ systemColors[SystemColor.MENU_TEXT] = 0xFF000000;
+ systemColors[SystemColor.TEXT] = 0xFFC0C0C0;
+ systemColors[SystemColor.TEXT_TEXT] = 0xFF000000;
+ systemColors[SystemColor.TEXT_HIGHLIGHT] = 0xFF000090;
+ systemColors[SystemColor.TEXT_HIGHLIGHT_TEXT] = 0xFFFFFFFF;
+ systemColors[SystemColor.TEXT_INACTIVE_TEXT] = 0xFF808080;
+ systemColors[SystemColor.CONTROL] = 0xFFC0C0C0;
+ systemColors[SystemColor.CONTROL_TEXT] = 0xFF000000;
+ systemColors[SystemColor.CONTROL_HIGHLIGHT] = 0xFFFFFFFF;
+ systemColors[SystemColor.CONTROL_LT_HIGHLIGHT] = 0xFFE0E0E0;
+ systemColors[SystemColor.CONTROL_SHADOW] = 0xFF808080;
+ systemColors[SystemColor.CONTROL_DK_SHADOW] = 0xFF000000;
+ systemColors[SystemColor.SCROLLBAR] = 0xFFE0E0E0;
+ systemColors[SystemColor.INFO] = 0xFFE0E000;
+ systemColors[SystemColor.INFO_TEXT] = 0xFF000000;
+ }
+
+ /**
+ * @since 1.4
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public void setDynamicLayout(boolean dynamic)
+ {
+ }
+
+ /**
+ * @since 1.4
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ protected boolean isDynamicLayoutSet()
+ {
+ return false;
+ }
+
+ /**
+ * @since 1.4
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public boolean isDynamicLayoutActive()
+ {
+ return false;
+ }
+
+ /**
+ * Returns the dimensions of the screen in pixels.
+ *
+ * @return The dimensions of the screen in pixels.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public abstract Dimension getScreenSize();
+
+ /**
+ * Returns the screen resolution in dots per square inch.
+ *
+ * @return The screen resolution in dots per square inch.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public abstract int getScreenResolution();
+
+ /**
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ *
+ * @since 1.4
+ */
+ public Insets getScreenInsets(GraphicsConfiguration gc)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the color model of the screen.
+ *
+ * @return The color model of the screen.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public abstract ColorModel getColorModel();
+
+ /**
+ * Returns the names of the available fonts.
+ *
+ * @return The names of the available fonts.
+ *
+ * @deprecated
+ */
+ public abstract String[] getFontList();
+
+ /**
+ * Return the font metrics for the specified font
+ *
+ * @param name The name of the font to return metrics for.
+ *
+ * @return The requested font metrics.
+ *
+ * @deprecated
+ */
+ public abstract FontMetrics getFontMetrics(Font name);
+
+ /**
+ * Flushes any buffered data to the screen so that it is in sync with
+ * what the AWT system has drawn to it.
+ */
+ public abstract void sync();
+
+ /**
+ * Returns an instance of the default toolkit. The default toolkit is
+ * the subclass of <code>Toolkit</code> specified in the system property
+ * <code>awt.toolkit</code>, or <code>gnu.java.awt.peer.gtk.GtkToolkit</code>
+ * if the property is not set.
+ *
+ * @return An instance of the system default toolkit.
+ *
+ * @throws AWTError If the toolkit cannot be loaded.
+ */
+ public static Toolkit getDefaultToolkit()
+ {
+ if (toolkit != null)
+ return toolkit;
+ String toolkit_name = System.getProperty("awt.toolkit",
+ default_toolkit_name);
+ try
+ {
+ Class cls = Class.forName(toolkit_name);
+ Object obj = cls.newInstance();
+ if (!(obj instanceof Toolkit))
+ throw new AWTError(toolkit_name + " is not a subclass of " +
+ "java.awt.Toolkit");
+ toolkit = (Toolkit) obj;
+ return toolkit;
+ }
+ catch (ThreadDeath death)
+ {
+ throw death;
+ }
+ catch (Throwable t)
+ {
+ AWTError e = new AWTError("Cannot load AWT toolkit: " + toolkit_name);
+ throw (AWTError) e.initCause(t);
+ }
+ }
+
+ /**
+ * Returns an image from the specified file, which must be in a
+ * recognized format. Supported formats vary from toolkit to toolkit.
+ *
+ * @return name The name of the file to read the image from.
+ */
+ public abstract Image getImage(String name);
+
+ /**
+ * Returns an image from the specified URL, which must be in a
+ * recognized format. Supported formats vary from toolkit to toolkit.
+ *
+ * @return url The URl to read the image from.
+ */
+ public abstract Image getImage(URL url);
+
+ public abstract Image createImage(String filename);
+
+ public abstract Image createImage(URL url);
+
+ /**
+ * Readies an image to be rendered on the screen. The width and height
+ * values can be set to the default sizes for the image by passing -1
+ * in those parameters.
+ *
+ * @param image The image to prepare for rendering.
+ * @param width The width of the image.
+ * @param height The height of the image.
+ * @param observer The observer to receive events about the preparation
+ * process.
+ *
+ * @return <code>true</code> if the image is already prepared for rendering,
+ * <code>false</code> otherwise.
+ */
+ public abstract boolean prepareImage(Image image, int width, int height,
+ ImageObserver observer);
+
+ /**
+ * Checks the status of specified image as it is being readied for
+ * rendering.
+ *
+ * @param image The image to prepare for rendering.
+ * @param width The width of the image.
+ * @param height The height of the image.
+ * @param observer The observer to receive events about the preparation
+ * process.
+ *
+ * @return A union of the bitmasks from
+ * <code>java.awt.image.ImageObserver</code> that indicates the current
+ * state of the imaging readying process.
+ */
+ public abstract int checkImage(Image image, int width, int height,
+ ImageObserver observer);
+
+ /**
+ * Creates an image using the specified <code>ImageProducer</code>
+ *
+ * @param producer The <code>ImageProducer</code> to create the image from.
+ *
+ * @return The created image.
+ */
+ public abstract Image createImage(ImageProducer producer);
+
+ /**
+ * Creates an image from the specified byte array. The array must be in
+ * a recognized format. Supported formats vary from toolkit to toolkit.
+ *
+ * @param data The raw image data.
+ *
+ * @return The created image.
+ */
+ public Image createImage(byte[] data)
+ {
+ return createImage(data, 0, data.length);
+ }
+
+ /**
+ * Creates an image from the specified portion of the byte array passed.
+ * The array must be in a recognized format. Supported formats vary from
+ * toolkit to toolkit.
+ *
+ * @param data The raw image data.
+ * @param offset The offset into the data where the image data starts.
+ * @param len The length of the image data.
+ *
+ * @return The created image.
+ */
+ public abstract Image createImage(byte[] data, int offset, int len);
+
+ /**
+ * Returns a instance of <code>PrintJob</code> for the specified
+ * arguments.
+ *
+ * @param frame The window initiating the print job.
+ * @param title The print job title.
+ * @param props The print job properties.
+ *
+ * @return The requested print job, or <code>null</code> if the job
+ * was cancelled.
+ *
+ * @exception NullPointerException If frame is null,
+ * or GraphicsEnvironment.isHeadless() returns true.
+ * @exception SecurityException If this thread is not allowed to initiate
+ * a print job request.
+ */
+ public abstract PrintJob getPrintJob(Frame frame, String title,
+ Properties props);
+
+ /**
+ * Returns a instance of <code>PrintJob</code> for the specified
+ * arguments.
+ *
+ * @param frame The window initiating the print job.
+ * @param title The print job title.
+ * @param jobAttr A set of job attributes which will control the print job.
+ * @param pageAttr A set of page attributes which will control the print job.
+ *
+ * @exception NullPointerException If frame is null, and either jobAttr is null
+ * or jobAttr.getDialog() returns JobAttributes.DialogType.NATIVE.
+ * @exception IllegalArgumentException If pageAttrspecifies differing cross
+ * feed and feed resolutions, or when GraphicsEnvironment.isHeadless() returns
+ * true.
+ * @exception SecurityException If this thread is not allowed to initiate
+ * a print job request.
+ *
+ * @since 1.3
+ */
+ public PrintJob getPrintJob(Frame frame, String title,
+ JobAttributes jobAttr, PageAttributes pageAttr)
+ {
+ return null;
+ }
+
+ /**
+ * Causes a "beep" tone to be generated.
+ */
+ public abstract void beep();
+
+ /**
+ * Returns the system clipboard.
+ *
+ * @return THe system clipboard.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public abstract Clipboard getSystemClipboard();
+
+ /**
+ * Gets the singleton instance of the system selection as a Clipboard object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ *
+ * @since 1.4
+ */
+ public Clipboard getSystemSelection()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the accelerator key mask for menu shortcuts. The default is
+ * <code>Event.CTRL_MASK</code>. A toolkit must override this method
+ * to change the default.
+ *
+ * @return The key mask for the menu accelerator key.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public int getMenuShortcutKeyMask()
+ {
+ return Event.CTRL_MASK;
+ }
+
+ /**
+ * Returns whether the given locking key on the keyboard is currently in its
+ * "on" state.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ * @exception IllegalArgumentException If keyCode is not one of the valid keys.
+ * @exception UnsupportedOperationException If the host system doesn't allow
+ * getting the state of this key programmatically, or if the keyboard doesn't
+ * have this key.
+ */
+ public boolean getLockingKeyState(int keyCode)
+ {
+ if (keyCode != KeyEvent.VK_CAPS_LOCK
+ && keyCode != KeyEvent.VK_NUM_LOCK
+ && keyCode != KeyEvent.VK_SCROLL_LOCK)
+ throw new IllegalArgumentException();
+
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sets the state of the given locking key on the keyboard.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ * @exception IllegalArgumentException If keyCode is not one of the valid keys.
+ * @exception UnsupportedOperationException If the host system doesn't allow
+ * getting the state of this key programmatically, or if the keyboard doesn't
+ * have this key.
+ */
+ public void setLockingKeyState(int keyCode, boolean on)
+ {
+ if (keyCode != KeyEvent.VK_CAPS_LOCK
+ && keyCode != KeyEvent.VK_NUM_LOCK
+ && keyCode != KeyEvent.VK_SCROLL_LOCK)
+ throw new IllegalArgumentException();
+
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the native container object of the specified component. This
+ * method is necessary because the parent component might be a lightweight
+ * component.
+ *
+ * @param component The component to fetch the native container for.
+ *
+ * @return The native container object for this component.
+ */
+ protected static Container getNativeContainer(Component component)
+ {
+ component = component.getParent();
+ while (true)
+ {
+ if (component == null)
+ return null;
+ if (! (component instanceof Container))
+ {
+ component = component.getParent();
+ continue;
+ }
+ if (component.getPeer() instanceof LightweightPeer)
+ {
+ component = component.getParent();
+ continue;
+ }
+ return (Container) component;
+ }
+ }
+
+ /**
+ * Creates a new custom cursor object.
+ *
+ * @exception IndexOutOfBoundsException If the hotSpot values are outside
+ * the bounds of the cursor.
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
+ {
+ // Presumably the only reason this isn't abstract is for backwards
+ // compatibility? FIXME?
+ return null;
+ }
+
+ /**
+ * Returns the supported cursor dimension which is closest to the
+ * desired sizes.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public Dimension getBestCursorSize(int preferredWidth, int preferredHeight)
+ {
+ return new Dimension (0,0);
+ }
+
+ /**
+ * Returns the maximum number of colors the Toolkit supports in a custom
+ * cursor palette.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public int getMaximumCursorColors()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns whether Toolkit supports this state for Frames.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ *
+ * @since 1.4
+ */
+ public boolean isFrameStateSupported(int state)
+ {
+ return false;
+ }
+
+ /**
+ * Returns the value of the property with the specified name, or the
+ * default value if the property does not exist.
+ *
+ * @param key The name of the property to retrieve.
+ * @param def The default value of the property.
+ */
+ public static String getProperty(String key, String def)
+ {
+ return props.getProperty(key, def);
+ }
+
+
+ /**
+ * Returns the event queue that is suitable for the calling context.
+ *
+ * <p>Despite the word &#x201c;System&#x201d; in the name of this
+ * method, a toolkit may provide different event queues for each
+ * applet. There is no guarantee that the same queue is shared
+ * system-wide.
+ *
+ * <p>The implementation first checks whether a
+ * SecurityManager has been installed. If so, its {@link
+ * java.lang.SecurityManager#checkAwtEventQueueAccess()} method gets
+ * called. The security manager will throw a SecurityException if it
+ * does not grant the permission to access the event queue.
+ *
+ * <p>Next, the call is delegated to {@link
+ * #getSystemEventQueueImpl()}.
+ *
+ * @return The event queue for this applet (or application).
+ *
+ * @throws SecurityException if a security manager has been
+ * installed, and it does not grant the permission to access the
+ * event queue.
+ */
+ public final EventQueue getSystemEventQueue()
+ {
+ SecurityManager sm;
+
+ sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkAwtEventQueueAccess();
+
+ return getSystemEventQueueImpl();
+ }
+
+
+ /**
+ * Returns the event queue that is suitable for the calling context.
+ *
+ * <p>Despite the word &#x201c;System&#x201d; in the name of this
+ * method, a toolkit may provide different event queues for each
+ * applet. There is no guarantee that the same queue is shared
+ * system-wide.
+ *
+ * <p>No security checks are performed, which is why this method
+ * may only be called by Toolkits.
+ *
+ * @see #getSystemEventQueue()
+ */
+ protected abstract EventQueue getSystemEventQueueImpl();
+
+
+ /**
+ * @since 1.3
+ */
+ public abstract DragSourceContextPeer
+ createDragSourceContextPeer(DragGestureEvent e);
+
+ /**
+ * @since 1.3
+ */
+ public DragGestureRecognizer
+ createDragGestureRecognizer(Class recognizer, DragSource ds,
+ Component comp, int actions,
+ DragGestureListener l)
+ {
+ return null;
+ }
+
+ public final Object getDesktopProperty(String propertyName)
+ {
+ return desktopProperties.get(propertyName);
+ }
+
+ protected final void setDesktopProperty(String name, Object newValue)
+ {
+ Object oldValue = getDesktopProperty(name);
+ desktopProperties.put(name, newValue);
+ desktopPropsSupport.firePropertyChange(name, oldValue, newValue);
+ }
+
+ protected Object lazilyLoadDesktopProperty(String name)
+ {
+ // FIXME - what is this??
+ return null;
+ }
+
+ protected void initializeDesktopProperties()
+ {
+ // Overridden by toolkit implementation?
+ }
+
+ public void addPropertyChangeListener(String name,
+ PropertyChangeListener pcl)
+ {
+ desktopPropsSupport.addPropertyChangeListener(name, pcl);
+ }
+
+ public void removePropertyChangeListener(String name,
+ PropertyChangeListener pcl)
+ {
+ desktopPropsSupport.removePropertyChangeListener(name, pcl);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners()
+ {
+ return desktopPropsSupport.getPropertyChangeListeners();
+ }
+
+ /**
+ * @since 1.4
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners(String name)
+ {
+ return desktopPropsSupport.getPropertyChangeListeners(name);
+ }
+
+ public void addAWTEventListener(AWTEventListener listener, long eventMask)
+ {
+ // SecurityManager s = System.getSecurityManager();
+ // if (s != null)
+ // s.checkPermission(AWTPermission("listenToAllAWTEvents"));
+ // FIXME
+ }
+
+ public void removeAWTEventListener(AWTEventListener listener)
+ {
+ // FIXME
+ }
+
+ /**
+ * @since 1.4
+ */
+ public AWTEventListener[] getAWTEventListeners()
+ {
+ return null;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public AWTEventListener[] getAWTEventListeners(long mask)
+ {
+ return null;
+ }
+
+ /**
+ * @since 1.3
+ */
+ public abstract Map mapInputMethodHighlight(InputMethodHighlight highlight);
+} // class Toolkit
diff --git a/libjava/classpath/java/awt/Transparency.java b/libjava/classpath/java/awt/Transparency.java
new file mode 100644
index 0000000..8885871
--- /dev/null
+++ b/libjava/classpath/java/awt/Transparency.java
@@ -0,0 +1,67 @@
+/* Transparency.java -- common transparency modes in graphics
+ Copyright (C) 2000, 2002, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt;
+
+/**
+ * A common transparency mode for layering graphics.
+ *
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface Transparency
+{
+ /** Image data which is completely opaque, for an alpha value of 1.0. */
+ int OPAQUE = 1;
+
+ /**
+ * Image data which is either completely opaque or transparent, for an
+ * exact integer alpha value.
+ */
+ int BITMASK = 2;
+
+ /** Image data which is translucent, for a non-integer alpha value. */
+ int TRANSLUCENT = 3;
+
+ /**
+ * Return the transparency type.
+ *
+ * @return One of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}.
+ */
+ int getTransparency();
+} // interface Transparency
diff --git a/libjava/classpath/java/awt/Window.java b/libjava/classpath/java/awt/Window.java
new file mode 100644
index 0000000..e26c4e3
--- /dev/null
+++ b/libjava/classpath/java/awt/Window.java
@@ -0,0 +1,1125 @@
+/* Window.java --
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt;
+
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowFocusListener;
+import java.awt.event.WindowListener;
+import java.awt.event.WindowStateListener;
+import java.awt.image.BufferStrategy;
+import java.awt.peer.WindowPeer;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.EventListener;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+
+/**
+ * This class represents a top-level window with no decorations.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ */
+public class Window extends Container implements Accessible
+{
+ private static final long serialVersionUID = 4497834738069338734L;
+
+ // Serialized fields, from Sun's serialization spec.
+ private String warningString = null;
+ private int windowSerializedDataVersion = 0; // FIXME
+ /** @since 1.2 */
+ // private FocusManager focusMgr; // FIXME: what is this?
+ /** @since 1.2 */
+ private int state = 0;
+ /** @since 1.4 */
+ private boolean focusableWindowState = true;
+
+ // A list of other top-level windows owned by this window.
+ private transient Vector ownedWindows = new Vector();
+
+ private transient WindowListener windowListener;
+ private transient WindowFocusListener windowFocusListener;
+ private transient WindowStateListener windowStateListener;
+ private transient GraphicsConfiguration graphicsConfiguration;
+
+ private transient boolean shown;
+
+ // This is package-private to avoid an accessor method.
+ transient Component windowFocusOwner;
+
+ /*
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_window_number;
+
+ protected class AccessibleAWTWindow extends AccessibleAWTContainer
+ {
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.WINDOW;
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleStateSet states = super.getAccessibleStateSet();
+ if (isActive())
+ states.add(AccessibleState.ACTIVE);
+ return states;
+ }
+ }
+
+ /**
+ * This (package access) constructor is used by subclasses that want
+ * to build windows that do not have parents. Eg. toplevel
+ * application frames. Subclasses cannot call super(null), since
+ * null is an illegal argument.
+ */
+ Window()
+ {
+ visible = false;
+ // Windows are the only Containers that default to being focus
+ // cycle roots.
+ focusCycleRoot = true;
+ setLayout(new BorderLayout());
+
+ addWindowFocusListener (new WindowAdapter ()
+ {
+ public void windowGainedFocus (WindowEvent event)
+ {
+ if (windowFocusOwner != null)
+ {
+ // FIXME: move this section and the other similar
+ // sections in Component into a separate method.
+ EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+ synchronized (eq)
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+ Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+ if (currentFocusOwner != null)
+ {
+ eq.postEvent (new FocusEvent (currentFocusOwner, FocusEvent.FOCUS_LOST,
+ false, windowFocusOwner));
+ eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED,
+ false, currentFocusOwner));
+ }
+ else
+ eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED, false));
+ }
+ }
+ }
+ });
+ }
+
+ Window(GraphicsConfiguration gc)
+ {
+ this();
+ graphicsConfiguration = gc;
+ }
+
+ /**
+ * Initializes a new instance of <code>Window</code> with the specified
+ * parent. The window will initially be invisible.
+ *
+ * @param owner The owning <code>Frame</code> of this window.
+ *
+ * @exception IllegalArgumentException If the owner's GraphicsConfiguration
+ * is not from a screen device, or if owner is null; this exception is always
+ * thrown when GraphicsEnvironment.isHeadless returns true.
+ */
+ public Window(Frame owner)
+ {
+ this (owner, owner.getGraphicsConfiguration ());
+ }
+
+ /**
+ * Initializes a new instance of <code>Window</code> with the specified
+ * parent. The window will initially be invisible.
+ *
+ * @exception IllegalArgumentException If the owner's GraphicsConfiguration
+ * is not from a screen device, or if owner is null; this exception is always
+ * thrown when GraphicsEnvironment.isHeadless returns true.
+ *
+ * @since 1.2
+ */
+ public Window(Window owner)
+ {
+ this (owner, owner.getGraphicsConfiguration ());
+ }
+
+ /**
+ * Initializes a new instance of <code>Window</code> with the specified
+ * parent. The window will initially be invisible.
+ *
+ * @exception IllegalArgumentException If owner is null or if gc is not from a
+ * screen device; this exception is always thrown when
+ * GraphicsEnvironment.isHeadless returns true.
+ *
+ * @since 1.3
+ */
+ public Window(Window owner, GraphicsConfiguration gc)
+ {
+ this ();
+
+ synchronized (getTreeLock())
+ {
+ if (owner == null)
+ throw new IllegalArgumentException ("owner must not be null");
+
+ parent = owner;
+ owner.ownedWindows.add(new WeakReference(this));
+ }
+
+ // FIXME: make this text visible in the window.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null && ! s.checkTopLevelWindow(this))
+ warningString = System.getProperty("awt.appletWarning");
+
+ if (gc != null
+ && gc.getDevice().getType() != GraphicsDevice.TYPE_RASTER_SCREEN)
+ throw new IllegalArgumentException ("gc must be from a screen device");
+
+ if (gc == null)
+ graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice()
+ .getDefaultConfiguration();
+ else
+ graphicsConfiguration = gc;
+ }
+
+ GraphicsConfiguration getGraphicsConfigurationImpl()
+ {
+ if (graphicsConfiguration != null)
+ return graphicsConfiguration;
+
+ return super.getGraphicsConfigurationImpl();
+ }
+
+ /**
+ * Creates the native peer for this window.
+ */
+ public void addNotify()
+ {
+ if (peer == null)
+ peer = getToolkit().createWindow(this);
+ super.addNotify();
+ }
+
+ /**
+ * Relays out this window's child components at their preferred size.
+ *
+ * @specnote pack() doesn't appear to be called internally by show(), so
+ * we duplicate some of the functionality.
+ */
+ public void pack()
+ {
+ if (parent != null && !parent.isDisplayable())
+ parent.addNotify();
+ if (peer == null)
+ addNotify();
+
+ setSize(getPreferredSize());
+
+ validate();
+ }
+
+ /**
+ * Shows on-screen this window and any of its owned windows for whom
+ * isVisible returns true.
+ */
+ public void show()
+ {
+ if (parent != null && !parent.isDisplayable())
+ parent.addNotify();
+ if (peer == null)
+ addNotify();
+
+ // Show visible owned windows.
+ synchronized (getTreeLock())
+ {
+ Iterator e = ownedWindows.iterator();
+ while(e.hasNext())
+ {
+ Window w = (Window)(((Reference) e.next()).get());
+ if (w != null)
+ {
+ if (w.isVisible())
+ w.getPeer().setVisible(true);
+ }
+ else
+ // Remove null weak reference from ownedWindows.
+ // Unfortunately this can't be done in the Window's
+ // finalize method because there is no way to guarantee
+ // synchronous access to ownedWindows there.
+ e.remove();
+ }
+ }
+ validate();
+ super.show();
+ toFront();
+
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+ manager.setGlobalFocusedWindow (this);
+
+ if (!shown)
+ {
+ FocusTraversalPolicy policy = getFocusTraversalPolicy ();
+ Component initialFocusOwner = null;
+
+ if (policy != null)
+ initialFocusOwner = policy.getInitialComponent (this);
+
+ if (initialFocusOwner != null)
+ initialFocusOwner.requestFocusInWindow ();
+
+ shown = true;
+ }
+ }
+
+ public void hide()
+ {
+ // Hide visible owned windows.
+ synchronized (getTreeLock ())
+ {
+ Iterator e = ownedWindows.iterator();
+ while(e.hasNext())
+ {
+ Window w = (Window)(((Reference) e.next()).get());
+ if (w != null)
+ {
+ if (w.isVisible() && w.getPeer() != null)
+ w.getPeer().setVisible(false);
+ }
+ else
+ e.remove();
+ }
+ }
+ super.hide();
+ }
+
+ public boolean isDisplayable()
+ {
+ if (super.isDisplayable())
+ return true;
+ return peer != null;
+ }
+
+ /**
+ * Destroys any resources associated with this window. This includes
+ * all components in the window and all owned top-level windows.
+ */
+ public void dispose()
+ {
+ hide();
+
+ synchronized (getTreeLock ())
+ {
+ Iterator e = ownedWindows.iterator();
+ while(e.hasNext())
+ {
+ Window w = (Window)(((Reference) e.next()).get());
+ if (w != null)
+ w.dispose();
+ else
+ // Remove null weak reference from ownedWindows.
+ e.remove();
+ }
+
+ for (int i = 0; i < ncomponents; ++i)
+ component[i].removeNotify();
+ this.removeNotify();
+
+ // Post a WINDOW_CLOSED event.
+ WindowEvent we = new WindowEvent(this, WindowEvent.WINDOW_CLOSED);
+ getToolkit().getSystemEventQueue().postEvent(we);
+ }
+ }
+
+ /**
+ * Sends this window to the back so that all other windows display in
+ * front of it.
+ */
+ public void toBack()
+ {
+ if (peer != null)
+ {
+ WindowPeer wp = (WindowPeer) peer;
+ wp.toBack();
+ }
+ }
+
+ /**
+ * Brings this window to the front so that it displays in front of
+ * any other windows.
+ */
+ public void toFront()
+ {
+ if (peer != null)
+ {
+ WindowPeer wp = (WindowPeer) peer;
+ wp.toFront();
+ }
+ }
+
+ /**
+ * Returns the toolkit used to create this window.
+ *
+ * @return The toolkit used to create this window.
+ *
+ * @specnote Unlike Component.getToolkit, this implementation always
+ * returns the value of Toolkit.getDefaultToolkit().
+ */
+ public Toolkit getToolkit()
+ {
+ return Toolkit.getDefaultToolkit();
+ }
+
+ /**
+ * Returns the warning string that will be displayed if this window is
+ * popped up by an unsecure applet or application.
+ *
+ * @return The unsecure window warning message.
+ */
+ public final String getWarningString()
+ {
+ return warningString;
+ }
+
+ /**
+ * Returns the locale that this window is configured for.
+ *
+ * @return The locale this window is configured for.
+ */
+ public Locale getLocale()
+ {
+ return locale == null ? Locale.getDefault() : locale;
+ }
+
+ /*
+ /** @since 1.2
+ public InputContext getInputContext()
+ {
+ // FIXME
+ }
+ */
+
+ /**
+ * Sets the cursor for this window to the specifiec cursor.
+ *
+ * @param cursor The new cursor for this window.
+ */
+ public void setCursor(Cursor cursor)
+ {
+ super.setCursor(cursor);
+ }
+
+ public Window getOwner()
+ {
+ return (Window) parent;
+ }
+
+ /** @since 1.2 */
+ public Window[] getOwnedWindows()
+ {
+ Window [] trimmedList;
+ synchronized (getTreeLock ())
+ {
+ // Windows with non-null weak references in ownedWindows.
+ Window [] validList = new Window [ownedWindows.size()];
+
+ Iterator e = ownedWindows.iterator();
+ int numValid = 0;
+ while (e.hasNext())
+ {
+ Window w = (Window)(((Reference) e.next()).get());
+ if (w != null)
+ validList[numValid++] = w;
+ else
+ // Remove null weak reference from ownedWindows.
+ e.remove();
+ }
+
+ if (numValid != validList.length)
+ {
+ trimmedList = new Window [numValid];
+ System.arraycopy (validList, 0, trimmedList, 0, numValid);
+ }
+ else
+ trimmedList = validList;
+ }
+ return trimmedList;
+ }
+
+ /**
+ * Adds the specified listener to the list of <code>WindowListeners</code>
+ * that will receive events for this window.
+ *
+ * @param listener The <code>WindowListener</code> to add.
+ */
+ public synchronized void addWindowListener(WindowListener listener)
+ {
+ windowListener = AWTEventMulticaster.add(windowListener, listener);
+ }
+
+ /**
+ * Removes the specified listener from the list of
+ * <code>WindowListeners</code> that will receive events for this window.
+ *
+ * @param listener The <code>WindowListener</code> to remove.
+ */
+ public synchronized void removeWindowListener(WindowListener listener)
+ {
+ windowListener = AWTEventMulticaster.remove(windowListener, listener);
+ }
+
+ /**
+ * Returns an array of all the window listeners registered on this window.
+ *
+ * @since 1.4
+ */
+ public synchronized WindowListener[] getWindowListeners()
+ {
+ return (WindowListener[])
+ AWTEventMulticaster.getListeners(windowListener,
+ WindowListener.class);
+ }
+
+ /**
+ * Returns an array of all the window focus listeners registered on this
+ * window.
+ *
+ * @since 1.4
+ */
+ public synchronized WindowFocusListener[] getWindowFocusListeners()
+ {
+ return (WindowFocusListener[])
+ AWTEventMulticaster.getListeners(windowFocusListener,
+ WindowFocusListener.class);
+ }
+
+ /**
+ * Returns an array of all the window state listeners registered on this
+ * window.
+ *
+ * @since 1.4
+ */
+ public synchronized WindowStateListener[] getWindowStateListeners()
+ {
+ return (WindowStateListener[])
+ AWTEventMulticaster.getListeners(windowStateListener,
+ WindowStateListener.class);
+ }
+
+ /**
+ * Adds the specified listener to this window.
+ */
+ public void addWindowFocusListener (WindowFocusListener wfl)
+ {
+ windowFocusListener = AWTEventMulticaster.add (windowFocusListener, wfl);
+ }
+
+ /**
+ * Adds the specified listener to this window.
+ *
+ * @since 1.4
+ */
+ public void addWindowStateListener (WindowStateListener wsl)
+ {
+ windowStateListener = AWTEventMulticaster.add (windowStateListener, wsl);
+ }
+
+ /**
+ * Removes the specified listener from this window.
+ */
+ public void removeWindowFocusListener (WindowFocusListener wfl)
+ {
+ windowFocusListener = AWTEventMulticaster.remove (windowFocusListener, wfl);
+ }
+
+ /**
+ * Removes the specified listener from this window.
+ *
+ * @since 1.4
+ */
+ public void removeWindowStateListener (WindowStateListener wsl)
+ {
+ windowStateListener = AWTEventMulticaster.remove (windowStateListener, wsl);
+ }
+
+ /**
+ * Returns an array of all the objects currently registered as FooListeners
+ * upon this Window. FooListeners are registered using the addFooListener
+ * method.
+ *
+ * @exception ClassCastException If listenerType doesn't specify a class or
+ * interface that implements java.util.EventListener.
+ *
+ * @since 1.3
+ */
+ public EventListener[] getListeners(Class listenerType)
+ {
+ if (listenerType == WindowListener.class)
+ return getWindowListeners();
+ return super.getListeners(listenerType);
+ }
+
+ void dispatchEventImpl(AWTEvent e)
+ {
+ // Make use of event id's in order to avoid multiple instanceof tests.
+ if (e.id <= WindowEvent.WINDOW_LAST
+ && e.id >= WindowEvent.WINDOW_FIRST
+ && (windowListener != null
+ || windowFocusListener != null
+ || windowStateListener != null
+ || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+ }
+
+ /**
+ * Processes the specified event for this window. If the event is an
+ * instance of <code>WindowEvent</code>, then
+ * <code>processWindowEvent()</code> is called to process the event,
+ * otherwise the superclass version of this method is invoked.
+ *
+ * @param evt The event to process.
+ */
+ protected void processEvent(AWTEvent evt)
+ {
+ if (evt instanceof WindowEvent)
+ processWindowEvent((WindowEvent) evt);
+ else
+ super.processEvent(evt);
+ }
+
+ /**
+ * Dispatches this event to any listeners that are listening for
+ * <code>WindowEvents</code> on this window. This method only gets
+ * invoked if it is enabled via <code>enableEvents()</code> or if
+ * a listener has been added.
+ *
+ * @param evt The event to process.
+ */
+ protected void processWindowEvent(WindowEvent evt)
+ {
+ int id = evt.getID();
+
+ if (id == WindowEvent.WINDOW_GAINED_FOCUS
+ || id == WindowEvent.WINDOW_LOST_FOCUS)
+ processWindowFocusEvent (evt);
+ else if (id == WindowEvent.WINDOW_STATE_CHANGED)
+ processWindowStateEvent (evt);
+ else
+ {
+ if (windowListener != null)
+ {
+ switch (evt.getID())
+ {
+ case WindowEvent.WINDOW_ACTIVATED:
+ windowListener.windowActivated(evt);
+ break;
+
+ case WindowEvent.WINDOW_CLOSED:
+ windowListener.windowClosed(evt);
+ break;
+
+ case WindowEvent.WINDOW_CLOSING:
+ windowListener.windowClosing(evt);
+ break;
+
+ case WindowEvent.WINDOW_DEACTIVATED:
+ windowListener.windowDeactivated(evt);
+ break;
+
+ case WindowEvent.WINDOW_DEICONIFIED:
+ windowListener.windowDeiconified(evt);
+ break;
+
+ case WindowEvent.WINDOW_ICONIFIED:
+ windowListener.windowIconified(evt);
+ break;
+
+ case WindowEvent.WINDOW_OPENED:
+ windowListener.windowOpened(evt);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Identifies if this window is active. The active window is a Frame or
+ * Dialog that has focus or owns the active window.
+ *
+ * @return true if active, else false.
+ * @since 1.4
+ */
+ public boolean isActive()
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+ return manager.getActiveWindow() == this;
+ }
+
+ /**
+ * Identifies if this window is focused. A window is focused if it is the
+ * focus owner or it contains the focus owner.
+ *
+ * @return true if focused, else false.
+ * @since 1.4
+ */
+ public boolean isFocused()
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+ return manager.getFocusedWindow() == this;
+ }
+
+ /**
+ * Returns the child window that has focus if this window is active.
+ * This method returns <code>null</code> if this window is not active
+ * or no children have focus.
+ *
+ * @return The component that has focus, or <code>null</code> if no
+ * component has focus.
+ */
+ public Component getFocusOwner ()
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ Window activeWindow = manager.getActiveWindow ();
+
+ // The currently-focused Component belongs to the active Window.
+ if (activeWindow == this)
+ return manager.getFocusOwner ();
+ else
+ return windowFocusOwner;
+ }
+
+ /**
+ * Set the focus owner for this window. This method is used to
+ * remember which component was focused when this window lost
+ * top-level focus, so that when it regains top-level focus the same
+ * child component can be refocused.
+ *
+ * @param windowFocusOwner the component in this window that owns
+ * the focus.
+ */
+ void setFocusOwner (Component windowFocusOwner)
+ {
+ this.windowFocusOwner = windowFocusOwner;
+ }
+
+ /**
+ * Post a Java 1.0 event to the event queue.
+ *
+ * @param e The event to post.
+ *
+ * @deprecated
+ */
+ public boolean postEvent(Event e)
+ {
+ return handleEvent (e);
+ }
+
+ /**
+ * Tests whether or not this window is visible on the screen.
+ *
+ * In contrast to the normal behaviour of Container, which is that
+ * a container is showing if its parent is visible and showing, a Window
+ * is even showing, if its parent (i.e. an invisible Frame) is not showing.
+ *
+ * @return <code>true</code> if this window is visible, <code>false</code>
+ * otherwise.
+ */
+ public boolean isShowing()
+ {
+ return isVisible();
+ }
+
+ public void setLocationRelativeTo (Component c)
+ {
+ if (c == null || !c.isShowing ())
+ {
+ int x = 0;
+ int y = 0;
+
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment ();
+ Point center = ge.getCenterPoint ();
+ x = center.x - (width / 2);
+ y = center.y - (height / 2);
+ setLocation (x, y);
+ }
+ // FIXME: handle case where component is non-null.
+ }
+
+ /**
+ * A BltBufferStrategy for windows.
+ */
+ private class WindowBltBufferStrategy extends BltBufferStrategy
+ {
+ /**
+ * Creates a block transfer strategy for this window.
+ *
+ * @param numBuffers the number of buffers in this strategy
+ * @param accelerated true if the buffer should be accelerated,
+ * false otherwise
+ */
+ WindowBltBufferStrategy(int numBuffers, boolean accelerated)
+ {
+ super(numBuffers,
+ new BufferCapabilities(new ImageCapabilities(accelerated),
+ new ImageCapabilities(accelerated),
+ BufferCapabilities.FlipContents.COPIED));
+ }
+ }
+
+ /**
+ * A FlipBufferStrategy for windows.
+ */
+ private class WindowFlipBufferStrategy extends FlipBufferStrategy
+ {
+ /**
+ * Creates a flip buffer strategy for this window.
+ *
+ * @param numBuffers the number of buffers in this strategy
+ *
+ * @throws AWTException if the requested number of buffers is not
+ * supported
+ */
+ WindowFlipBufferStrategy(int numBuffers)
+ throws AWTException
+ {
+ super(numBuffers,
+ new BufferCapabilities(new ImageCapabilities(true),
+ new ImageCapabilities(true),
+ BufferCapabilities.FlipContents.COPIED));
+ }
+ }
+
+ /**
+ * Creates a buffering strategy that manages how this window is
+ * repainted. This method attempts to create the optimum strategy
+ * based on the desired number of buffers. Hardware or software
+ * acceleration may be used.
+ *
+ * createBufferStrategy attempts different levels of optimization,
+ * but guarantees that some strategy with the requested number of
+ * buffers will be created even if it is not optimal. First it
+ * attempts to create a page flipping strategy, then an accelerated
+ * blitting strategy, then an unaccelerated blitting strategy.
+ *
+ * Calling this method causes any existing buffer strategy to be
+ * destroyed.
+ *
+ * @param numBuffers the number of buffers in this strategy
+ *
+ * @throws IllegalArgumentException if requested number of buffers
+ * is less than one
+ * @throws IllegalStateException if this window is not displayable
+ *
+ * @since 1.4
+ */
+ public void createBufferStrategy(int numBuffers)
+ {
+ if (numBuffers < 1)
+ throw new IllegalArgumentException("Window.createBufferStrategy: number"
+ + " of buffers is less than one");
+
+ if (!isDisplayable())
+ throw new IllegalStateException("Window.createBufferStrategy: window is"
+ + " not displayable");
+
+ BufferStrategy newStrategy = null;
+
+ // try a flipping strategy
+ try
+ {
+ newStrategy = new WindowFlipBufferStrategy(numBuffers);
+ }
+ catch (AWTException e)
+ {
+ }
+
+ // fall back to an accelerated blitting strategy
+ if (newStrategy == null)
+ newStrategy = new WindowBltBufferStrategy(numBuffers, true);
+
+ bufferStrategy = newStrategy;
+ }
+
+ /**
+ * Creates a buffering strategy that manages how this window is
+ * repainted. This method attempts to create a strategy based on
+ * the specified capabilities and throws an exception if the
+ * requested strategy is not supported.
+ *
+ * Calling this method causes any existing buffer strategy to be
+ * destroyed.
+ *
+ * @param numBuffers the number of buffers in this strategy
+ * @param caps the requested buffering capabilities
+ *
+ * @throws AWTException if the requested capabilities are not
+ * supported
+ * @throws IllegalArgumentException if requested number of buffers
+ * is less than one or if caps is null
+ *
+ * @since 1.4
+ */
+ public void createBufferStrategy(int numBuffers,
+ BufferCapabilities caps)
+ {
+ if (numBuffers < 1)
+ throw new IllegalArgumentException("Window.createBufferStrategy: number"
+ + " of buffers is less than one");
+
+ if (caps == null)
+ throw new IllegalArgumentException("Window.createBufferStrategy:"
+ + " capabilities object is null");
+
+ // a flipping strategy was requested
+ if (caps.isPageFlipping())
+ {
+ try
+ {
+ bufferStrategy = new WindowFlipBufferStrategy(numBuffers);
+ }
+ catch (AWTException e)
+ {
+ }
+ }
+ else
+ bufferStrategy = new WindowBltBufferStrategy(numBuffers, true);
+ }
+
+ /**
+ * Returns the buffer strategy used by the window.
+ *
+ * @return the buffer strategy.
+ * @since 1.4
+ */
+ public BufferStrategy getBufferStrategy()
+ {
+ return bufferStrategy;
+ }
+
+ /**
+ * @since 1.2
+ *
+ * @deprecated
+ */
+ public void applyResourceBundle(ResourceBundle rb)
+ {
+ throw new Error ("Not implemented");
+ }
+
+ /**
+ * @since 1.2
+ *
+ * @deprecated
+ */
+ public void applyResourceBundle(String rbName)
+ {
+ ResourceBundle rb = ResourceBundle.getBundle(rbName, Locale.getDefault(),
+ ClassLoader.getSystemClassLoader());
+ if (rb != null)
+ applyResourceBundle(rb);
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>Window</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTWindow();
+ return accessibleContext;
+ }
+
+ /**
+ * Get graphics configuration. The implementation for Window will
+ * not ask any parent containers, since Window is a toplevel
+ * window and not actually embedded in the parent component.
+ */
+ public GraphicsConfiguration getGraphicsConfiguration()
+ {
+ if (graphicsConfiguration != null) return graphicsConfiguration;
+ if (peer != null) return peer.getGraphicsConfiguration();
+ return null;
+ }
+
+ protected void processWindowFocusEvent(WindowEvent event)
+ {
+ if (windowFocusListener != null)
+ {
+ switch (event.getID ())
+ {
+ case WindowEvent.WINDOW_GAINED_FOCUS:
+ windowFocusListener.windowGainedFocus (event);
+ break;
+
+ case WindowEvent.WINDOW_LOST_FOCUS:
+ windowFocusListener.windowLostFocus (event);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * @since 1.4
+ */
+ protected void processWindowStateEvent(WindowEvent event)
+ {
+ if (windowStateListener != null
+ && event.getID () == WindowEvent.WINDOW_STATE_CHANGED)
+ windowStateListener.windowStateChanged (event);
+ }
+
+ /**
+ * Returns whether this <code>Window</code> can get the focus or not.
+ *
+ * @since 1.4
+ */
+ public final boolean isFocusableWindow ()
+ {
+ if (getFocusableWindowState () == false)
+ return false;
+
+ if (this instanceof Dialog
+ || this instanceof Frame)
+ return true;
+
+ // FIXME: Implement more possible cases for returning true.
+
+ return false;
+ }
+
+ /**
+ * Returns the value of the focusableWindowState property.
+ *
+ * @since 1.4
+ */
+ public boolean getFocusableWindowState ()
+ {
+ return focusableWindowState;
+ }
+
+ /**
+ * Sets the value of the focusableWindowState property.
+ *
+ * @since 1.4
+ */
+ public void setFocusableWindowState (boolean focusableWindowState)
+ {
+ this.focusableWindowState = focusableWindowState;
+ }
+
+ // setBoundsCallback is needed so that when a user moves a window,
+ // the Window's location can be updated without calling the peer's
+ // setBounds method. When a user moves a window the peer window's
+ // location is updated automatically and the windowing system sends
+ // a message back to the application informing it of its updated
+ // dimensions. We must update the AWT Window class with these new
+ // dimensions. But we don't want to call the peer's setBounds
+ // method, because the peer's dimensions have already been updated.
+ // (Under X, having this method prevents Configure event loops when
+ // moving windows: Component.setBounds -> peer.setBounds ->
+ // postConfigureEvent -> Component.setBounds -> ... In some cases
+ // Configure event loops cause windows to jitter back and forth
+ // continuously).
+ void setBoundsCallback (int x, int y, int w, int h)
+ {
+ if (this.x == x && this.y == y && width == w && height == h)
+ return;
+ invalidate();
+ boolean resized = width != w || height != h;
+ boolean moved = this.x != x || this.y != y;
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ if (resized && isShowing ())
+ {
+ ComponentEvent ce =
+ new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ if (moved && isShowing ())
+ {
+ ComponentEvent ce =
+ new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
+ /**
+ * Generate a unique name for this window.
+ *
+ * @return A unique name for this window.
+ */
+ String generateName()
+ {
+ return "win" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_window_number++;
+ }
+}
diff --git a/libjava/classpath/java/awt/color/CMMException.java b/libjava/classpath/java/awt/color/CMMException.java
new file mode 100644
index 0000000..ab328ec
--- /dev/null
+++ b/libjava/classpath/java/awt/color/CMMException.java
@@ -0,0 +1,63 @@
+/* CMMException.java -- error in the native CMM
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.color;
+
+/**
+ * Thrown when there is an error in the native CMM.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @status updated to 1.4
+ */
+public class CMMException extends RuntimeException
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 5775558044142994965L;
+
+ /**
+ * Create a new instance with a specified detailed error message.
+ *
+ * @param message the message
+ */
+ public CMMException(String message)
+ {
+ super(message);
+ }
+} // class CMMException
diff --git a/libjava/classpath/java/awt/color/ColorSpace.java b/libjava/classpath/java/awt/color/ColorSpace.java
new file mode 100644
index 0000000..79369da
--- /dev/null
+++ b/libjava/classpath/java/awt/color/ColorSpace.java
@@ -0,0 +1,183 @@
+/* ColorSpace.java -- transforms between color spaces
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.color;
+
+import java.io.Serializable;
+
+/**
+ * NEEDS DOCUMENTATION
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @since 1.2
+ */
+public abstract class ColorSpace implements Serializable
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = -409452704308689724L;
+
+ public static final int TYPE_XYZ = 0;
+ public static final int TYPE_Lab = 1;
+ public static final int TYPE_Luv = 2;
+ public static final int TYPE_YCbCr = 3;
+ public static final int TYPE_Yxy = 4;
+ public static final int TYPE_RGB = 5;
+ public static final int TYPE_GRAY = 6;
+ public static final int TYPE_HSV = 7;
+ public static final int TYPE_HLS = 8;
+ public static final int TYPE_CMYK = 9;
+ // mysterious gap in the enumeration sequenece
+ public static final int TYPE_CMY = 11;
+ public static final int TYPE_2CLR = 12;
+ public static final int TYPE_3CLR = 13;
+ public static final int TYPE_4CLR = 14;
+ public static final int TYPE_5CLR = 15;
+ public static final int TYPE_6CLR = 16;
+ public static final int TYPE_7CLR = 17;
+ public static final int TYPE_8CLR = 18;
+ public static final int TYPE_9CLR = 19;
+ public static final int TYPE_ACLR = 20;
+ public static final int TYPE_BCLR = 21;
+ public static final int TYPE_CCLR = 22;
+ public static final int TYPE_DCLR = 23;
+ public static final int TYPE_ECLR = 24;
+ public static final int TYPE_FCLR = 25;
+
+ public static final int CS_sRGB = 1000;
+ public static final int CS_LINEAR_RGB = 1004;
+ public static final int CS_CIEXYZ = 1001;
+ public static final int CS_PYCC = 1002;
+ public static final int CS_GRAY = 1003;
+
+ private static final int CS_BASE = CS_sRGB;
+ private static final int CS_END = CS_LINEAR_RGB + 1;
+ private static final int CS_COUNT = CS_END - CS_BASE;
+
+ // Instances are lazily instantiated
+ private static final ColorSpace[] INSTANCES = new ColorSpace[CS_COUNT];
+
+ /**
+ * @serial
+ */
+ // Visible in subclass.
+ final int type;
+
+ /**
+ * @serial
+ */
+ // Visible in subclass.
+ final int numComponents;
+
+ protected ColorSpace(int type, int numcomponents)
+ {
+ this.type = type;
+ numComponents = numcomponents;
+ }
+
+ public static ColorSpace getInstance(int colorspace)
+ {
+ if ((colorspace >= CS_BASE) && (colorspace < CS_END))
+ {
+ int instanceIndex = colorspace - CS_BASE;
+ if (INSTANCES[instanceIndex] == null)
+ {
+ ICC_Profile profile = new ICC_Profile(colorspace);
+ INSTANCES[instanceIndex] = new ICC_ColorSpace(profile);
+ }
+ return INSTANCES[instanceIndex];
+ }
+ throw new IllegalArgumentException("unknown/unsupported colorspace");
+ }
+
+ public boolean isCS_sRGB()
+ {
+ return type == CS_sRGB;
+ }
+
+ /**
+ * Transforms a color value assumed to be in this ColorSpace into a value in
+ * the default CS_sRGB color space.
+ *
+ * @exception ArrayIndexOutOfBoundsException If array length is not at least
+ * the number of components in this ColorSpace.
+ */
+ public abstract float[] toRGB(float[] colorvalue);
+
+ public abstract float[] fromRGB(float[] rgbvalue);
+
+ public abstract float[] toCIEXYZ(float[] colorvalue);
+
+ public abstract float[] fromCIEXYZ(float[] colorvalue);
+
+ public int getType()
+ {
+ return type;
+ }
+
+ public int getNumComponents()
+ {
+ return numComponents;
+ }
+
+ public String getName(int idx)
+ {
+ return "type " + type;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public float getMinValue(int idx)
+ {
+ if (idx < 0 || idx >= numComponents)
+ throw new IllegalArgumentException();
+ return 0;
+ }
+
+ /**
+ * @since 1.4
+ */
+ public float getMaxValue(int idx)
+ {
+ if (idx < 0 || idx >= numComponents)
+ throw new IllegalArgumentException();
+ return 1;
+ }
+} // class ColorSpace
diff --git a/libjava/classpath/java/awt/color/ICC_ColorSpace.java b/libjava/classpath/java/awt/color/ICC_ColorSpace.java
new file mode 100644
index 0000000..b50048c
--- /dev/null
+++ b/libjava/classpath/java/awt/color/ICC_ColorSpace.java
@@ -0,0 +1,314 @@
+/* ICC_ColorSpace.java -- the canonical color space implementation
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.color;
+
+import gnu.java.awt.color.CieXyzConverter;
+import gnu.java.awt.color.ClutProfileConverter;
+import gnu.java.awt.color.ColorSpaceConverter;
+import gnu.java.awt.color.GrayProfileConverter;
+import gnu.java.awt.color.GrayScaleConverter;
+import gnu.java.awt.color.LinearRGBConverter;
+import gnu.java.awt.color.PyccConverter;
+import gnu.java.awt.color.RgbProfileConverter;
+import gnu.java.awt.color.SrgbConverter;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * ICC_ColorSpace - an implementation of ColorSpace
+ *
+ * While an ICC_Profile class abstracts the data in an ICC profile file
+ * an ICC_ColorSpace performs the color space conversions defined by
+ * an ICC_Profile instance.
+ *
+ * Typically, an ICC_Profile will either be created using getInstance,
+ * either from the built-in colorspaces, or from an ICC profile file.
+ * Then a ICC_Colorspace will be used to perform transforms from the
+ * device colorspace to and from the profile color space.
+ *
+ * The PCS used by ColorSpace is CIE XYZ relative a D50 white point.
+ * (Profiles using a CIE Lab PCS will have their input and output converted
+ * to D50 CIE XYZ accordingly.
+ *
+ * Note that a valid profile may not contain transforms in both directions,
+ * in which case the output may be undefined.
+ * All built-in colorspaces have bidirectional transforms, but developers
+ * using an ICC profile file may want to check the profile class using
+ * the ICC_Profile.getProfileClass() method. Input class profiles are
+ * guaranteed to have transforms to the PCS, output class profiles are
+ * guaranteed to have transforms from the PCS to device space.
+ *
+ * @author Sven de Marothy
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @since 1.2
+ */
+public class ICC_ColorSpace extends ColorSpace
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 3455889114070431483L;
+
+ /**
+ * @serial
+ */
+ private ICC_Profile thisProfile;
+
+ /**
+ * @serial
+ */
+ private float[] minVal;
+
+ /**
+ * @serial
+ */
+ private float[] maxVal;
+
+ /**
+ * @serial
+ */
+ private float[] diffMinMax;
+
+ /**
+ * @serial
+ */
+ private float[] invDiffMinMax;
+
+ /**
+ * @serial
+ */
+ private boolean needScaleInit;
+
+ /**
+ * Tells us if the PCS is CIE LAB (must be CIEXYZ otherwise)
+ */
+ private transient int type;
+ private transient int nComponents;
+ private transient ColorSpaceConverter converter;
+
+ /**
+ * Constructs a new ICC_ColorSpace from an ICC_Profile object.
+ *
+ * @exception IllegalArgumentException If profile is inappropriate for
+ * representing a ColorSpace.
+ */
+ public ICC_ColorSpace(ICC_Profile profile)
+ {
+ super(profile.getColorSpaceType(), profile.getNumComponents());
+
+ converter = getConverter(profile);
+ thisProfile = profile;
+ nComponents = profile.getNumComponents();
+ type = profile.getColorSpaceType();
+ makeArrays();
+ }
+
+ /**
+ * Return the profile
+ */
+ public ICC_Profile getProfile()
+ {
+ return thisProfile;
+ }
+
+ /**
+ * Transforms a color value assumed to be in this ColorSpace into a value in
+ * the default CS_sRGB color space.
+ *
+ * @exception ArrayIndexOutOfBoundsException If array length is not at least
+ * the number of components in this ColorSpace.
+ */
+ public float[] toRGB(float[] colorvalue)
+ {
+ return converter.toRGB(colorvalue);
+ }
+
+ /**
+ * Transforms a color value assumed to be in the default CS_sRGB color space
+ * into this ColorSpace.
+ *
+ * @exception ArrayIndexOutOfBoundsException If array length is not at
+ * least 3.
+ */
+ public float[] fromRGB(float[] rgbvalue)
+ {
+ return converter.fromRGB(rgbvalue);
+ }
+
+ /**
+ * Transforms a color value assumed to be in this ColorSpace into the
+ * CS_CIEXYZ conversion color space.
+ *
+ * @exception ArrayIndexOutOfBoundsException If array length is not at
+ * least the number of components in this ColorSpace.
+ */
+ public float[] toCIEXYZ(float[] colorvalue)
+ {
+ return converter.toCIEXYZ(colorvalue);
+ }
+
+ /**
+ * Transforms a color value assumed to be in the CS_CIEXYZ conversion color
+ * space into this ColorSpace.
+ *
+ * @exception ArrayIndexOutOfBoundsException If array length is not at
+ * least 3.
+ */
+ public float[] fromCIEXYZ(float[] colorvalue)
+ {
+ return converter.fromCIEXYZ(colorvalue);
+ }
+
+ public boolean isCS_sRGB()
+ {
+ return converter instanceof SrgbConverter;
+ }
+
+ /**
+ * Returns the minimum normalized color component value for the specified
+ * component.
+ *
+ * @exception IllegalArgumentException If component is less than 0 or greater
+ * than numComponents - 1.
+ *
+ * @since 1.4
+ */
+ public float getMinValue(int idx)
+ {
+ // FIXME: Not 100% certain of this.
+ if (type == ColorSpace.TYPE_Lab && (idx == 1 || idx == 2))
+ return -128f;
+
+ if (idx < 0 || idx >= nComponents)
+ throw new IllegalArgumentException();
+ return 0;
+ }
+
+ /**
+ * Returns the maximum normalized color component value for the specified
+ * component.
+ *
+ * @exception IllegalArgumentException If component is less than 0 or greater
+ * than numComponents - 1.
+ *
+ * @since 1.4
+ */
+ public float getMaxValue(int idx)
+ {
+ if (type == ColorSpace.TYPE_XYZ && idx >= 0 && idx <= 2)
+ return 1 + 32767 / 32768f;
+ else if (type == ColorSpace.TYPE_Lab)
+ {
+ if (idx == 0)
+ return 100;
+ if (idx == 1 || idx == 2)
+ return 127;
+ }
+ if (idx < 0 || idx >= nComponents)
+ throw new IllegalArgumentException();
+ return 1;
+ }
+
+ /**
+ * Returns a colorspace converter suitable for a given profile
+ */
+ private ColorSpaceConverter getConverter(ICC_Profile profile)
+ {
+ ColorSpaceConverter converter;
+ switch (profile.isPredefined())
+ {
+ case CS_sRGB:
+ converter = new SrgbConverter();
+ break;
+ case CS_CIEXYZ:
+ converter = new CieXyzConverter();
+ break;
+ case CS_GRAY:
+ converter = new GrayScaleConverter();
+ break;
+ case CS_LINEAR_RGB:
+ converter = new LinearRGBConverter();
+ break;
+ case CS_PYCC:
+ converter = new PyccConverter();
+ break;
+ default:
+ if (profile instanceof ICC_ProfileRGB)
+ converter = new RgbProfileConverter((ICC_ProfileRGB) profile);
+ else if (profile instanceof ICC_ProfileGray)
+ converter = new GrayProfileConverter((ICC_ProfileGray) profile);
+ else
+ converter = new ClutProfileConverter(profile);
+ break;
+ }
+ return converter;
+ }
+
+ /**
+ * Serialization compatibility requires these variable to be set,
+ * although we don't use them. Perhaps we should?
+ */
+ private void makeArrays()
+ {
+ minVal = new float[nComponents];
+ maxVal = new float[nComponents];
+
+ invDiffMinMax = diffMinMax = null;
+ for (int i = 0; i < nComponents; i++)
+ {
+ minVal[i] = getMinValue(i);
+ maxVal[i] = getMaxValue(i);
+ }
+ needScaleInit = true;
+ }
+
+ /**
+ * Deserializes the object
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ // set up objects
+ converter = getConverter(thisProfile);
+ nComponents = thisProfile.getNumComponents();
+ type = thisProfile.getColorSpaceType();
+ }
+} // class ICC_ColorSpace
diff --git a/libjava/classpath/java/awt/color/ICC_Profile.java b/libjava/classpath/java/awt/color/ICC_Profile.java
new file mode 100644
index 0000000..75f55a1
--- /dev/null
+++ b/libjava/classpath/java/awt/color/ICC_Profile.java
@@ -0,0 +1,1244 @@
+/* ICC_Profile.java -- color space profiling
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.color;
+
+import gnu.java.awt.color.ProfileHeader;
+import gnu.java.awt.color.TagEntry;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * ICC Profile - represents an ICC Color profile.
+ * The ICC profile format is a standard file format which maps the transform
+ * from a device color space to a standard Profile Color Space (PCS), which
+ * can either be CIE L*a*b or CIE XYZ.
+ * (With the exception of device link profiles which map from one device space
+ * to another)
+ *
+ * ICC profiles calibrated to specific input/output devices are used when color
+ * fidelity is of importance.
+ *
+ * An instance of ICC_Profile can be created using the getInstance() methods,
+ * either using one of the predefined color spaces enumerated in ColorSpace,
+ * or from an ICC profile file, or from an input stream.
+ *
+ * An ICC_ColorSpace object can then be created to transform color values
+ * through the profile.
+ *
+ * The ICC_Profile class implements the version 2 format specified by
+ * International Color Consortium Specification ICC.1:1998-09,
+ * and its addendum ICC.1A:1999-04, April 1999
+ * (available at www.color.org)
+ *
+ * @author Sven de Marothy
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @since 1.2
+ */
+public class ICC_Profile implements Serializable
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = -3938515861990936766L;
+
+ /**
+ * ICC Profile classes
+ */
+ public static final int CLASS_INPUT = 0;
+ public static final int CLASS_DISPLAY = 1;
+ public static final int CLASS_OUTPUT = 2;
+ public static final int CLASS_DEVICELINK = 3;
+ public static final int CLASS_COLORSPACECONVERSION = 4;
+ public static final int CLASS_ABSTRACT = 5;
+ public static final int CLASS_NAMEDCOLOR = 6;
+
+ /**
+ * ICC Profile class signatures
+ */
+ public static final int icSigInputClass = 0x73636e72; // 'scnr'
+ public static final int icSigDisplayClass = 0x6d6e7472; // 'mntr'
+ public static final int icSigOutputClass = 0x70727472; // 'prtr'
+ public static final int icSigLinkClass = 0x6c696e6b; // 'link'
+ public static final int icSigColorSpaceClass = 0x73706163; // 'spac'
+ public static final int icSigAbstractClass = 0x61627374; // 'abst'
+ public static final int icSigNamedColorClass = 0x6e6d636c; // 'nmcl'
+
+ /**
+ * Color space signatures
+ */
+ public static final int icSigXYZData = 0x58595A20; // 'XYZ '
+ public static final int icSigLabData = 0x4C616220; // 'Lab '
+ public static final int icSigLuvData = 0x4C757620; // 'Luv '
+ public static final int icSigYCbCrData = 0x59436272; // 'YCbr'
+ public static final int icSigYxyData = 0x59787920; // 'Yxy '
+ public static final int icSigRgbData = 0x52474220; // 'RGB '
+ public static final int icSigGrayData = 0x47524159; // 'GRAY'
+ public static final int icSigHsvData = 0x48535620; // 'HSV '
+ public static final int icSigHlsData = 0x484C5320; // 'HLS '
+ public static final int icSigCmykData = 0x434D594B; // 'CMYK'
+ public static final int icSigCmyData = 0x434D5920; // 'CMY '
+ public static final int icSigSpace2CLR = 0x32434C52; // '2CLR'
+ public static final int icSigSpace3CLR = 0x33434C52; // '3CLR'
+ public static final int icSigSpace4CLR = 0x34434C52; // '4CLR'
+ public static final int icSigSpace5CLR = 0x35434C52; // '5CLR'
+ public static final int icSigSpace6CLR = 0x36434C52; // '6CLR'
+ public static final int icSigSpace7CLR = 0x37434C52; // '7CLR'
+ public static final int icSigSpace8CLR = 0x38434C52; // '8CLR'
+ public static final int icSigSpace9CLR = 0x39434C52; // '9CLR'
+ public static final int icSigSpaceACLR = 0x41434C52; // 'ACLR'
+ public static final int icSigSpaceBCLR = 0x42434C52; // 'BCLR'
+ public static final int icSigSpaceCCLR = 0x43434C52; // 'CCLR'
+ public static final int icSigSpaceDCLR = 0x44434C52; // 'DCLR'
+ public static final int icSigSpaceECLR = 0x45434C52; // 'ECLR'
+ public static final int icSigSpaceFCLR = 0x46434C52; // 'FCLR'
+
+ /**
+ * Rendering intents
+ */
+ public static final int icPerceptual = 0;
+ public static final int icRelativeColorimetric = 1;
+ public static final int icSaturation = 2;
+ public static final int icAbsoluteColorimetric = 3;
+
+ /**
+ * Tag signatures
+ */
+ public static final int icSigAToB0Tag = 0x41324230; // 'A2B0'
+ public static final int icSigAToB1Tag = 0x41324231; // 'A2B1'
+ public static final int icSigAToB2Tag = 0x41324232; // 'A2B2'
+ public static final int icSigBlueColorantTag = 0x6258595A; // 'bXYZ'
+ public static final int icSigBlueTRCTag = 0x62545243; // 'bTRC'
+ public static final int icSigBToA0Tag = 0x42324130; // 'B2A0'
+ public static final int icSigBToA1Tag = 0x42324131; // 'B2A1'
+ public static final int icSigBToA2Tag = 0x42324132; // 'B2A2'
+ public static final int icSigCalibrationDateTimeTag = 0x63616C74; // 'calt'
+ public static final int icSigCharTargetTag = 0x74617267; // 'targ'
+ public static final int icSigCopyrightTag = 0x63707274; // 'cprt'
+ public static final int icSigCrdInfoTag = 0x63726469; // 'crdi'
+ public static final int icSigDeviceMfgDescTag = 0x646D6E64; // 'dmnd'
+ public static final int icSigDeviceModelDescTag = 0x646D6464; // 'dmdd'
+ public static final int icSigDeviceSettingsTag = 0x64657673; // 'devs'
+ public static final int icSigGamutTag = 0x67616D74; // 'gamt'
+ public static final int icSigGrayTRCTag = 0x6b545243; // 'kTRC'
+ public static final int icSigGreenColorantTag = 0x6758595A; // 'gXYZ'
+ public static final int icSigGreenTRCTag = 0x67545243; // 'gTRC'
+ public static final int icSigLuminanceTag = 0x6C756d69; // 'lumi'
+ public static final int icSigMeasurementTag = 0x6D656173; // 'meas'
+ public static final int icSigMediaBlackPointTag = 0x626B7074; // 'bkpt'
+ public static final int icSigMediaWhitePointTag = 0x77747074; // 'wtpt'
+ public static final int icSigNamedColor2Tag = 0x6E636C32; // 'ncl2'
+ public static final int icSigOutputResponseTag = 0x72657370; // 'resp'
+ public static final int icSigPreview0Tag = 0x70726530; // 'pre0'
+ public static final int icSigPreview1Tag = 0x70726531; // 'pre1'
+ public static final int icSigPreview2Tag = 0x70726532; // 'pre2'
+ public static final int icSigProfileDescriptionTag = 0x64657363; // 'desc'
+ public static final int icSigProfileSequenceDescTag = 0x70736571; // 'pseq'
+ public static final int icSigPs2CRD0Tag = 0x70736430; // 'psd0'
+ public static final int icSigPs2CRD1Tag = 0x70736431; // 'psd1'
+ public static final int icSigPs2CRD2Tag = 0x70736432; // 'psd2'
+ public static final int icSigPs2CRD3Tag = 0x70736433; // 'psd3'
+ public static final int icSigPs2CSATag = 0x70733273; // 'ps2s'
+ public static final int icSigPs2RenderingIntentTag = 0x70733269; // 'ps2i'
+ public static final int icSigRedColorantTag = 0x7258595A; // 'rXYZ'
+ public static final int icSigRedTRCTag = 0x72545243; // 'rTRC'
+ public static final int icSigScreeningDescTag = 0x73637264; // 'scrd'
+ public static final int icSigScreeningTag = 0x7363726E; // 'scrn'
+ public static final int icSigTechnologyTag = 0x74656368; // 'tech'
+ public static final int icSigUcrBgTag = 0x62666420; // 'bfd '
+ public static final int icSigViewingCondDescTag = 0x76756564; // 'vued'
+ public static final int icSigViewingConditionsTag = 0x76696577; // 'view'
+ public static final int icSigChromaticityTag = 0x6368726D; // 'chrm'
+
+ /**
+ * Non-ICC tag 'head' for use in retrieving the header with getData()
+ */
+ public static final int icSigHead = 0x68656164;
+
+ /**
+ * Header offsets
+ */
+ public static final int icHdrSize = 0;
+ public static final int icHdrCmmId = 4;
+ public static final int icHdrVersion = 8;
+ public static final int icHdrDeviceClass = 12;
+ public static final int icHdrColorSpace = 16;
+ public static final int icHdrPcs = 20;
+ public static final int icHdrDate = 24;
+ public static final int icHdrMagic = 36;
+ public static final int icHdrPlatform = 40;
+ public static final int icHdrFlags = 44;
+ public static final int icHdrManufacturer = 48;
+ public static final int icHdrModel = 52;
+ public static final int icHdrAttributes = 56;
+ public static final int icHdrRenderingIntent = 64;
+ public static final int icHdrIlluminant = 68;
+ public static final int icHdrCreator = 80;
+
+ /**
+ *
+ */
+ public static final int icTagType = 0;
+ public static final int icTagReserved = 4;
+ public static final int icCurveCount = 8;
+ public static final int icCurveData = 12;
+ public static final int icXYZNumberX = 8;
+
+ /**
+ * offset of the Tag table
+ */
+ private static final int tagTableOffset = 128;
+
+ /**
+ * @serial
+ */
+ private static final int iccProfileSerializedDataVersion = 1;
+
+ /**
+ * Constants related to generating profiles for
+ * built-in colorspace profiles
+ */
+ /**
+ * Copyright notice to stick into built-in-profile files.
+ */
+ private static final String copyrightNotice = "Generated by GNU Classpath.";
+
+ /**
+ * Resolution of the TRC to use for predefined profiles.
+ * 1024 should suffice.
+ */
+ private static final int TRC_POINTS = 1024;
+
+ /**
+ * CIE 1931 D50 white point (in Lab coordinates)
+ */
+ private static final float[] D50 = { 0.96422f, 1.00f, 0.82521f };
+
+ /**
+ * Color space profile ID
+ * Set to the predefined profile class (e.g. CS_sRGB) if a predefined
+ * color space is used, set to -1 otherwise.
+ * (or if the profile has been modified)
+ */
+ private transient int profileID;
+
+ /**
+ * The profile header data
+ */
+ private transient ProfileHeader header;
+
+ /**
+ * A hashtable containing the profile tags as TagEntry objects
+ */
+ private transient Hashtable tagTable;
+
+ /**
+ * Contructor for predefined colorspaces
+ */
+ ICC_Profile(int profileID)
+ {
+ header = null;
+ tagTable = null;
+ createProfile(profileID);
+ }
+
+ /**
+ * Constructs an ICC_Profile from a header and a table of loaded tags.
+ */
+ ICC_Profile(ProfileHeader h, Hashtable tags) throws IllegalArgumentException
+ {
+ header = h;
+ tagTable = tags;
+ profileID = -1; // Not a predefined color space
+ }
+
+ /**
+ * Constructs an ICC_Profile from a byte array of data.
+ */
+ ICC_Profile(byte[] data) throws IllegalArgumentException
+ {
+ // get header and verify it
+ header = new ProfileHeader(data);
+ header.verifyHeader(data.length);
+ tagTable = createTagTable(data);
+ profileID = -1; // Not a predefined color space
+ }
+
+ /**
+ * Free up the used memory.
+ */
+ protected void finalize()
+ {
+ }
+
+ /**
+ * Returns an ICC_Profile instance from a byte array of profile data.
+ *
+ * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
+ * may be returned if appropriate.
+ *
+ * @throws IllegalArgumentException if the profile data is an invalid
+ * v2 profile.
+ *
+ * @param data - the profile data
+ * @return An ICC_Profile object
+ */
+ public static ICC_Profile getInstance(byte[] data)
+ {
+ ProfileHeader header = new ProfileHeader(data);
+
+ // verify it as a correct ICC header, including size
+ header.verifyHeader(data.length);
+
+ Hashtable tags = createTagTable(data);
+
+ if (isRGBProfile(header, tags))
+ return new ICC_ProfileRGB(data);
+ if (isGrayProfile(header, tags))
+ return new ICC_ProfileGray(data);
+
+ return new ICC_Profile(header, tags);
+ }
+
+ /**
+ * Returns an predefined ICC_Profile instance.
+ *
+ * This will construct an ICC_Profile instance from one of the predefined
+ * color spaces in the ColorSpace class. (e.g. CS_sRGB, CS_GRAY, etc)
+ *
+ * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
+ * may be returned if appropriate.
+ *
+ * @return An ICC_Profile object
+ */
+ public static ICC_Profile getInstance(int cspace)
+ {
+ if (cspace == ColorSpace.CS_sRGB || cspace == ColorSpace.CS_LINEAR_RGB)
+ return new ICC_ProfileRGB(cspace);
+ if (cspace == ColorSpace.CS_GRAY)
+ return new ICC_ProfileGray(cspace);
+ return new ICC_Profile(cspace);
+ }
+
+ /**
+ * Returns an ICC_Profile instance from an ICC Profile file.
+ *
+ * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
+ * may be returned if appropriate.
+ *
+ * @throws IllegalArgumentException if the profile data is an invalid
+ * v2 profile.
+ * @throws IOException if the file could not be read.
+ *
+ * @param filename - the file name of the profile file.
+ * @return An ICC_Profile object
+ */
+ public static ICC_Profile getInstance(String filename)
+ throws IOException
+ {
+ return getInstance(new FileInputStream(filename));
+ }
+
+ /**
+ * Returns an ICC_Profile instance from an InputStream.
+ *
+ * This method can be used for reading ICC profiles embedded in files
+ * which support this. (JPEG and SVG for instance).
+ *
+ * The stream is treated in the following way: The profile header
+ * (128 bytes) is read first, and the header is validated. If the profile
+ * header is valid, it will then attempt to read the rest of the profile
+ * from the stream. The stream is not closed after reading.
+ *
+ * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
+ * may be returned if appropriate.
+ *
+ * @throws IllegalArgumentException if the profile data is an invalid
+ * v2 profile.
+ * @throws IOException if the stream could not be read.
+ *
+ * @param in - the input stream to read the profile from.
+ * @return An ICC_Profile object
+ */
+ public static ICC_Profile getInstance(InputStream in)
+ throws IOException
+ {
+ // read the header
+ byte[] headerData = new byte[ProfileHeader.HEADERSIZE];
+ if (in.read(headerData) != ProfileHeader.HEADERSIZE)
+ throw new IllegalArgumentException("Invalid profile header");
+
+ ProfileHeader header = new ProfileHeader(headerData);
+
+ // verify it as a correct ICC header, but do not verify the
+ // size as we are reading from a stream.
+ header.verifyHeader(-1);
+
+ // get the size
+ byte[] data = new byte[header.getSize()];
+ System.arraycopy(headerData, 0, data, 0, ProfileHeader.HEADERSIZE);
+
+ // read the rest
+ if (in.read(data, ProfileHeader.HEADERSIZE,
+ header.getSize() - ProfileHeader.HEADERSIZE) != header.getSize()
+ - ProfileHeader.HEADERSIZE)
+ throw new IOException("Incorrect profile size");
+
+ return getInstance(data);
+ }
+
+ /**
+ * Returns the major version number
+ */
+ public int getMajorVersion()
+ {
+ return header.getMajorVersion();
+ }
+
+ /**
+ * Returns the minor version number.
+ *
+ * Only the least-significant byte contains data, in BCD form:
+ * the least-significant nibble is the BCD bug fix revision,
+ * the most-significant nibble is the BCD minor revision number.
+ *
+ * (E.g. For a v2.1.0 profile this will return <code>0x10</code>)
+ */
+ public int getMinorVersion()
+ {
+ return header.getMinorVersion();
+ }
+
+ /**
+ * Returns the device class of this profile,
+ *
+ * (E.g. CLASS_INPUT for a scanner profile,
+ * CLASS_OUTPUT for a printer)
+ */
+ public int getProfileClass()
+ {
+ return header.getProfileClass();
+ }
+
+ /**
+ * Returns the color space of this profile, in terms
+ * of the color space constants defined in ColorSpace.
+ * (For example, it may be a ColorSpace.TYPE_RGB)
+ */
+ public int getColorSpaceType()
+ {
+ return header.getColorSpace();
+ }
+
+ /**
+ * Returns the color space of this profile's Profile Connection Space (OCS)
+ *
+ * In terms of the color space constants defined in ColorSpace.
+ * This may be TYPE_XYZ or TYPE_Lab
+ */
+ public int getPCSType()
+ {
+ return header.getProfileColorSpace();
+ }
+
+ /**
+ * Writes the profile data to an ICC profile file.
+ * @param filename - The name of the file to write
+ * @throws IOException if the write failed.
+ */
+ public void write(String filename) throws IOException
+ {
+ FileOutputStream out = new FileOutputStream(filename);
+ write(out);
+ out.flush();
+ out.close();
+ }
+
+ /**
+ * Writes the profile data in ICC profile file-format to a stream.
+ * This is useful for embedding ICC profiles in file formats which
+ * support this (such as JPEG and SVG).
+ *
+ * The stream is not closed after writing.
+ * @param out - The outputstream to which the profile data should be written
+ * @throws IOException if the write failed.
+ */
+ public void write(OutputStream out) throws IOException
+ {
+ out.write(getData());
+ }
+
+ /**
+ * Returns the data corresponding to this ICC_Profile as a byte array.
+ *
+ * @return The data in a byte array,
+ * where the first element corresponds to first byte of the profile file.
+ */
+ public byte[] getData()
+ {
+ int size = getSize();
+ byte[] data = new byte[size];
+
+ // Header
+ System.arraycopy(header.getData(size), 0, data, 0, ProfileHeader.HEADERSIZE);
+ // # of tags
+ byte[] tt = getTagTable();
+ System.arraycopy(tt, 0, data, ProfileHeader.HEADERSIZE, tt.length);
+
+ Enumeration e = tagTable.elements();
+ while (e.hasMoreElements())
+ {
+ TagEntry tag = (TagEntry) e.nextElement();
+ System.arraycopy(tag.getData(), 0,
+ data, tag.getOffset(), tag.getSize());
+ }
+ return data;
+ }
+
+ /**
+ * Returns the ICC profile tag data
+ * The non ICC-tag icSigHead is also permitted to request the header data.
+ *
+ * @param tagSignature The ICC signature of the requested tag
+ * @return A byte array containing the tag data
+ */
+ public byte[] getData(int tagSignature)
+ {
+ if (tagSignature == icSigHead)
+ return header.getData(getSize());
+
+ TagEntry t = (TagEntry) tagTable.get(TagEntry.tagHashKey(tagSignature));
+ if (t == null)
+ return null;
+ return t.getData();
+ }
+
+ /**
+ * Sets the ICC profile tag data.
+ *
+ * Note that an ICC profile can only contain one tag of each type, if
+ * a tag already exists with the given signature, it is replaced.
+ *
+ * @param tagSignature - The signature of the tag to set
+ * @param data - A byte array containing the tag data
+ */
+ public void setData(int tagSignature, byte[] data)
+ {
+ profileID = -1; // Not a predefined color space if modified.
+
+ if (tagSignature == icSigHead)
+ header = new ProfileHeader(data);
+ else
+ {
+ TagEntry t = new TagEntry(tagSignature, data);
+ tagTable.put(t.hashKey(), t);
+ }
+ }
+
+ /**
+ * Get the number of components in the profile's device color space.
+ */
+ public int getNumComponents()
+ {
+ int[] lookup =
+ {
+ ColorSpace.TYPE_RGB, 3, ColorSpace.TYPE_CMY, 3,
+ ColorSpace.TYPE_CMYK, 4, ColorSpace.TYPE_GRAY, 1,
+ ColorSpace.TYPE_YCbCr, 3, ColorSpace.TYPE_XYZ, 3,
+ ColorSpace.TYPE_Lab, 3, ColorSpace.TYPE_HSV, 3,
+ ColorSpace.TYPE_2CLR, 2, ColorSpace.TYPE_Luv, 3,
+ ColorSpace.TYPE_Yxy, 3, ColorSpace.TYPE_HLS, 3,
+ ColorSpace.TYPE_3CLR, 3, ColorSpace.TYPE_4CLR, 4,
+ ColorSpace.TYPE_5CLR, 5, ColorSpace.TYPE_6CLR, 6,
+ ColorSpace.TYPE_7CLR, 7, ColorSpace.TYPE_8CLR, 8,
+ ColorSpace.TYPE_9CLR, 9, ColorSpace.TYPE_ACLR, 10,
+ ColorSpace.TYPE_BCLR, 11, ColorSpace.TYPE_CCLR, 12,
+ ColorSpace.TYPE_DCLR, 13, ColorSpace.TYPE_ECLR, 14,
+ ColorSpace.TYPE_FCLR, 15
+ };
+ for (int i = 0; i < lookup.length; i += 2)
+ if (header.getColorSpace() == lookup[i])
+ return lookup[i + 1];
+ return 3; // should never happen.
+ }
+
+ /**
+ * After deserializing we must determine if the class we want
+ * is really one of the more specialized ICC_ProfileRGB or
+ * ICC_ProfileGray classes.
+ */
+ protected Object readResolve() throws ObjectStreamException
+ {
+ if (isRGBProfile(header, tagTable))
+ return new ICC_ProfileRGB(getData());
+ if (isGrayProfile(header, tagTable))
+ return new ICC_ProfileGray(getData());
+ return this;
+ }
+
+ /**
+ * Deserializes an instance
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ String predef = (String) s.readObject();
+ byte[] data = (byte[]) s.readObject();
+
+ if (data != null)
+ {
+ header = new ProfileHeader(data);
+ tagTable = createTagTable(data);
+ profileID = -1; // Not a predefined color space
+ }
+
+ if (predef != null)
+ {
+ predef = predef.intern();
+ if (predef.equals("CS_sRGB"))
+ createProfile(ColorSpace.CS_sRGB);
+ if (predef.equals("CS_LINEAR_RGB"))
+ createProfile(ColorSpace.CS_LINEAR_RGB);
+ if (predef.equals("CS_CIEXYZ"))
+ createProfile(ColorSpace.CS_CIEXYZ);
+ if (predef.equals("CS_GRAY"))
+ createProfile(ColorSpace.CS_GRAY);
+ if (predef.equals("CS_PYCC"))
+ createProfile(ColorSpace.CS_PYCC);
+ }
+ }
+
+ /**
+ * Serializes an instance
+ * The format is a String and a byte array,
+ * The string is non-null if the instance is one of the built-in profiles.
+ * Otherwise the byte array is non-null and represents the profile data.
+ */
+ private void writeObject(ObjectOutputStream s) throws IOException
+ {
+ s.defaultWriteObject();
+ if (profileID == ColorSpace.CS_sRGB)
+ s.writeObject("CS_sRGB");
+ else if (profileID == ColorSpace.CS_LINEAR_RGB)
+ s.writeObject("CS_LINEAR_RGB");
+ else if (profileID == ColorSpace.CS_CIEXYZ)
+ s.writeObject("CS_CIEXYZ");
+ else if (profileID == ColorSpace.CS_GRAY)
+ s.writeObject("CS_GRAY");
+ else if (profileID == ColorSpace.CS_PYCC)
+ s.writeObject("CS_PYCC");
+ else
+ {
+ s.writeObject(null); // null string
+ s.writeObject(getData()); // data
+ return;
+ }
+ s.writeObject(null); // null data
+ }
+
+ /**
+ * Sorts a ICC profile byte array into TagEntry objects stored in
+ * a hash table.
+ */
+ private static Hashtable createTagTable(byte[] data)
+ throws IllegalArgumentException
+ {
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ int nTags = buf.getInt(tagTableOffset);
+
+ Hashtable tagTable = new Hashtable();
+ for (int i = 0; i < nTags; i++)
+ {
+ TagEntry te = new TagEntry(buf.getInt(tagTableOffset
+ + i * TagEntry.entrySize + 4),
+ buf.getInt(tagTableOffset
+ + i * TagEntry.entrySize + 8),
+ buf.getInt(tagTableOffset
+ + i * TagEntry.entrySize + 12),
+ data);
+
+ if (tagTable.put(te.hashKey(), te) != null)
+ throw new IllegalArgumentException("Duplicate tag in profile:" + te);
+ }
+ return tagTable;
+ }
+
+ /**
+ * Returns the total size of the padded, stored data
+ * Note: Tags must be stored on 4-byte aligned offsets.
+ */
+ private int getSize()
+ {
+ int totalSize = ProfileHeader.HEADERSIZE; // size of header
+
+ int tagTableSize = 4 + tagTable.size() * TagEntry.entrySize; // size of tag table
+ if ((tagTableSize & 0x0003) != 0)
+ tagTableSize += 4 - (tagTableSize & 0x0003); // pad
+ totalSize += tagTableSize;
+
+ Enumeration e = tagTable.elements();
+ while (e.hasMoreElements())
+ { // tag data
+ int tagSize = ((TagEntry) e.nextElement()).getSize();
+ if ((tagSize & 0x0003) != 0)
+ tagSize += 4 - (tagSize & 0x0003); // pad
+ totalSize += tagSize;
+ }
+ return totalSize;
+ }
+
+ /**
+ * Generates the tag index table
+ */
+ private byte[] getTagTable()
+ {
+ int tagTableSize = 4 + tagTable.size() * TagEntry.entrySize;
+ if ((tagTableSize & 0x0003) != 0)
+ tagTableSize += 4 - (tagTableSize & 0x0003); // pad
+
+ int offset = 4;
+ int tagOffset = ProfileHeader.HEADERSIZE + tagTableSize;
+ ByteBuffer buf = ByteBuffer.allocate(tagTableSize);
+ buf.putInt(tagTable.size()); // number of tags
+
+ Enumeration e = tagTable.elements();
+ while (e.hasMoreElements())
+ {
+ TagEntry tag = (TagEntry) e.nextElement();
+ buf.putInt(offset, tag.getSignature());
+ buf.putInt(offset + 4, tagOffset);
+ buf.putInt(offset + 8, tag.getSize());
+ tag.setOffset(tagOffset);
+ int tagSize = tag.getSize();
+ if ((tagSize & 0x0003) != 0)
+ tagSize += 4 - (tagSize & 0x0003); // pad
+ tagOffset += tagSize;
+ offset += 12;
+ }
+ return buf.array();
+ }
+
+ /**
+ * Returns if the criteria for an ICC_ProfileRGB are met.
+ * This means:
+ * Color space is TYPE_RGB
+ * (r,g,b)ColorantTags included
+ * (r,g,b)TRCTags included
+ * mediaWhitePointTag included
+ */
+ private static boolean isRGBProfile(ProfileHeader header, Hashtable tags)
+ {
+ if (header.getColorSpace() != ColorSpace.TYPE_RGB)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigRedColorantTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigGreenColorantTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigBlueColorantTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigRedTRCTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigGreenTRCTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigBlueTRCTag)) == null)
+ return false;
+ return (tags.get(TagEntry.tagHashKey(icSigMediaWhitePointTag)) != null);
+ }
+
+ /**
+ * Returns if the criteria for an ICC_ProfileGray are met.
+ * This means:
+ * Colorspace is TYPE_GRAY
+ * grayTRCTag included
+ * mediaWhitePointTag included
+ */
+ private static boolean isGrayProfile(ProfileHeader header, Hashtable tags)
+ {
+ if (header.getColorSpace() != ColorSpace.TYPE_GRAY)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigGrayTRCTag)) == null)
+ return false;
+ return (tags.get(TagEntry.tagHashKey(icSigMediaWhitePointTag)) != null);
+ }
+
+ /**
+ * Returns curve data for a 'curv'-type tag
+ * If it's a gamma curve, a single entry will be returned with the
+ * gamma value (including 1.0 for linear response)
+ * Otherwise the TRC table is returned.
+ *
+ * (Package private - used by ICC_ProfileRGB and ICC_ProfileGray)
+ */
+ short[] getCurve(int signature)
+ {
+ byte[] data = getData(signature);
+ short[] curve;
+
+ // can't find tag?
+ if (data == null)
+ return null;
+
+ // not an curve type tag?
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ if (buf.getInt(0) != 0x63757276) // 'curv' type
+ return null;
+ int count = buf.getInt(8);
+ if (count == 0)
+ {
+ curve = new short[1];
+ curve[0] = 0x0100; // 1.00 in u8fixed8
+ return curve;
+ }
+ if (count == 1)
+ {
+ curve = new short[1];
+ curve[0] = buf.getShort(12); // other u8fixed8 gamma
+ return curve;
+ }
+ curve = new short[count];
+ for (int i = 0; i < count; i++)
+ curve[i] = buf.getShort(12 + i * 2);
+ return curve;
+ }
+
+ /**
+ * Returns XYZ tristimulus values for an 'XYZ ' type tag
+ * @return the XYZ values, or null if the tag was not an 'XYZ ' type tag.
+ *
+ * (Package private - used by ICC_ProfileXYZ and ICC_ProfileGray)
+ */
+ float[] getXYZData(int signature)
+ {
+ byte[] data = getData(signature);
+
+ // can't find tag?
+ if (data == null)
+ return null;
+
+ // not an XYZData type tag?
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ if (buf.getInt(0) != icSigXYZData) // 'XYZ ' type
+ return null;
+
+ float[] point = new float[3];
+
+ // get the X,Y,Z tristimulus values
+ point[0] = ((float) buf.getInt(8)) / 65536f;
+ point[1] = ((float) buf.getInt(12)) / 65536f;
+ point[2] = ((float) buf.getInt(16)) / 65536f;
+ return point;
+ }
+
+ /**
+ * Returns the profile ID if it's a predefined profile
+ * Or -1 for a profile loaded from an ICC profile
+ *
+ * (Package private - used by ICC_ColorSpace)
+ */
+ int isPredefined()
+ {
+ return profileID;
+ }
+
+ /**
+ * Creates a tag of XYZ-value type.
+ */
+ private byte[] makeXYZData(float[] values)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(20);
+ buf.putInt(0, icSigXYZData); // 'XYZ '
+ buf.putInt(4, 0);
+ buf.putInt(8, (int) (values[0] * 65536.0));
+ buf.putInt(12, (int) (values[1] * 65536.0));
+ buf.putInt(16, (int) (values[2] * 65536.0));
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of text type
+ */
+ private byte[] makeTextTag(String text)
+ {
+ int length = text.length();
+ ByteBuffer buf = ByteBuffer.allocate(8 + length + 1);
+ byte[] data;
+ try
+ {
+ data = text.getBytes("US-ASCII");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ data = new byte[length]; // shouldn't happen
+ }
+
+ buf.putInt(0, (int) 0x74657874); // 'text'
+ buf.putInt(4, 0);
+ for (int i = 0; i < length; i++)
+ buf.put(8 + i, data[i]);
+ buf.put(8 + length, (byte) 0); // null-terminate
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of textDescriptionType
+ */
+ private byte[] makeDescTag(String text)
+ {
+ int length = text.length();
+ ByteBuffer buf = ByteBuffer.allocate(90 + length + 1);
+ buf.putInt(0, (int) 0x64657363); // 'desc'
+ buf.putInt(4, 0); // reserved
+ buf.putInt(8, length + 1); // ASCII length, including null termination
+ byte[] data;
+
+ try
+ {
+ data = text.getBytes("US-ASCII");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ data = new byte[length]; // shouldn't happen
+ }
+
+ for (int i = 0; i < length; i++)
+ buf.put(12 + i, data[i]);
+ buf.put(12 + length, (byte) 0); // null-terminate
+
+ for (int i = 0; i < 39; i++)
+ buf.putShort(13 + length + (i * 2), (short) 0); // 78 bytes we can ignore
+
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of TRC type (linear curve)
+ */
+ private byte[] makeTRC()
+ {
+ ByteBuffer buf = ByteBuffer.allocate(12);
+ buf.putInt(0, 0x63757276); // 'curv' type
+ buf.putInt(4, 0); // reserved
+ buf.putInt(8, 0);
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of TRC type (single gamma value)
+ */
+ private byte[] makeTRC(float gamma)
+ {
+ short gammaValue = (short) (gamma * 256f);
+ ByteBuffer buf = ByteBuffer.allocate(14);
+ buf.putInt(0, 0x63757276); // 'curv' type
+ buf.putInt(4, 0); // reserved
+ buf.putInt(8, 1);
+ buf.putShort(12, gammaValue); // 1.00 in u8fixed8
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of TRC type (TRC curve points)
+ */
+ private byte[] makeTRC(float[] trc)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(12 + 2 * trc.length);
+ buf.putInt(0, 0x63757276); // 'curv' type
+ buf.putInt(4, 0); // reserved
+ buf.putInt(8, trc.length); // number of points
+
+ // put the curve values
+ for (int i = 0; i < trc.length; i++)
+ buf.putShort(12 + i * 2, (short) (trc[i] * 65535f));
+
+ return buf.array();
+ }
+
+ /**
+ * Creates an identity color lookup table.
+ */
+ private byte[] makeIdentityClut()
+ {
+ final int nIn = 3;
+ final int nOut = 3;
+ final int nInEntries = 256;
+ final int nOutEntries = 256;
+ final int gridpoints = 16;
+
+ // gridpoints**nIn
+ final int clutSize = 2 * nOut * gridpoints * gridpoints * gridpoints;
+ final int totalSize = clutSize + 2 * nInEntries * nIn
+ + 2 * nOutEntries * nOut + 52;
+
+ ByteBuffer buf = ByteBuffer.allocate(totalSize);
+ buf.putInt(0, 0x6D667432); // 'mft2'
+ buf.putInt(4, 0); // reserved
+ buf.put(8, (byte) nIn); // number input channels
+ buf.put(9, (byte) nOut); // number output channels
+ buf.put(10, (byte) gridpoints); // number gridpoints
+ buf.put(11, (byte) 0); // padding
+
+ // identity matrix
+ buf.putInt(12, 65536); // = 1 in s15.16 fixed point
+ buf.putInt(16, 0);
+ buf.putInt(20, 0);
+ buf.putInt(24, 0);
+ buf.putInt(28, 65536);
+ buf.putInt(32, 0);
+ buf.putInt(36, 0);
+ buf.putInt(40, 0);
+ buf.putInt(44, 65536);
+
+ buf.putShort(48, (short) nInEntries); // input table entries
+ buf.putShort(50, (short) nOutEntries); // output table entries
+
+ // write the linear input channels, unsigned 16.16 fixed point,
+ // from 0.0 to FF.FF
+ for (int channel = 0; channel < 3; channel++)
+ for (int i = 0; i < nInEntries; i++)
+ {
+ short n = (short) ((i << 8) | i); // assumes 256 entries
+ buf.putShort(52 + (channel * nInEntries + i) * 2, n);
+ }
+ int clutOffset = 52 + nInEntries * nIn * 2;
+
+ for (int x = 0; x < gridpoints; x++)
+ for (int y = 0; y < gridpoints; y++)
+ for (int z = 0; z < gridpoints; z++)
+ {
+ int offset = clutOffset + z * 2 * nOut + y * gridpoints * 2 * nOut
+ + x * gridpoints * gridpoints * 2 * nOut;
+ double xf = ((double) x) / ((double) gridpoints - 1.0);
+ double yf = ((double) y) / ((double) gridpoints - 1.0);
+ double zf = ((double) z) / ((double) gridpoints - 1.0);
+ buf.putShort(offset, (short) (xf * 65535.0));
+ buf.putShort(offset + 2, (short) (yf * 65535.0));
+ buf.putShort(offset + 4, (short) (zf * 65535.0));
+ }
+
+ for (int channel = 0; channel < 3; channel++)
+ for (int i = 0; i < nOutEntries; i++)
+ {
+ short n = (short) ((i << 8) | i); // assumes 256 entries
+ buf.putShort(clutOffset + clutSize + (channel * nOutEntries + i) * 2,
+ n);
+ }
+
+ return buf.array();
+ }
+
+ /**
+ * Creates profile data corresponding to the built-in colorspaces.
+ */
+ private void createProfile(int colorSpace) throws IllegalArgumentException
+ {
+ this.profileID = colorSpace;
+ header = new ProfileHeader();
+ tagTable = new Hashtable();
+
+ switch (colorSpace)
+ {
+ case ColorSpace.CS_sRGB:
+ createRGBProfile();
+ return;
+ case ColorSpace.CS_LINEAR_RGB:
+ createLinearRGBProfile();
+ return;
+ case ColorSpace.CS_CIEXYZ:
+ createCIEProfile();
+ return;
+ case ColorSpace.CS_GRAY:
+ createGrayProfile();
+ return;
+ case ColorSpace.CS_PYCC:
+ createPyccProfile();
+ return;
+ default:
+ throw new IllegalArgumentException("Not a predefined color space!");
+ }
+ }
+
+ /**
+ * Creates an ICC_Profile representing the sRGB color space
+ */
+ private void createRGBProfile()
+ {
+ header.setColorSpace( ColorSpace.TYPE_RGB );
+ header.setProfileColorSpace( ColorSpace.TYPE_XYZ );
+ ICC_ColorSpace cs = new ICC_ColorSpace(this);
+
+ float[] r = { 1f, 0f, 0f };
+ float[] g = { 0f, 1f, 0f };
+ float[] b = { 0f, 0f, 1f };
+ float[] black = { 0f, 0f, 0f };
+
+ // CIE 1931 D50 white point (in Lab coordinates)
+ float[] white = D50;
+
+ // Get tristimulus values (matrix elements)
+ r = cs.toCIEXYZ(r);
+ g = cs.toCIEXYZ(g);
+ b = cs.toCIEXYZ(b);
+
+ // Generate the sRGB TRC curve, this is the linear->nonlinear
+ // RGB transform.
+ cs = new ICC_ColorSpace(getInstance(ICC_ColorSpace.CS_LINEAR_RGB));
+ float[] points = new float[TRC_POINTS];
+ float[] in = new float[3];
+ for (int i = 0; i < TRC_POINTS; i++)
+ {
+ in[0] = in[1] = in[2] = ((float) i) / ((float) TRC_POINTS - 1);
+ in = cs.fromRGB(in);
+ // Note this value is the same for all components.
+ points[i] = in[0];
+ }
+
+ setData(icSigRedColorantTag, makeXYZData(r));
+ setData(icSigGreenColorantTag, makeXYZData(g));
+ setData(icSigBlueColorantTag, makeXYZData(b));
+ setData(icSigMediaWhitePointTag, makeXYZData(white));
+ setData(icSigMediaBlackPointTag, makeXYZData(black));
+ setData(icSigRedTRCTag, makeTRC(points));
+ setData(icSigGreenTRCTag, makeTRC(points));
+ setData(icSigBlueTRCTag, makeTRC(points));
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("Generic sRGB"));
+ this.profileID = ColorSpace.CS_sRGB;
+ }
+
+ /**
+ * Creates an linear sRGB profile
+ */
+ private void createLinearRGBProfile()
+ {
+ header.setColorSpace(ColorSpace.TYPE_RGB);
+ header.setProfileColorSpace(ColorSpace.TYPE_XYZ);
+ ICC_ColorSpace cs = new ICC_ColorSpace(this);
+
+ float[] r = { 1f, 0f, 0f };
+ float[] g = { 0f, 1f, 0f };
+ float[] b = { 0f, 0f, 1f };
+ float[] black = { 0f, 0f, 0f };
+
+ float[] white = D50;
+
+ // Get tristimulus values (matrix elements)
+ r = cs.toCIEXYZ(r);
+ g = cs.toCIEXYZ(g);
+ b = cs.toCIEXYZ(b);
+
+ setData(icSigRedColorantTag, makeXYZData(r));
+ setData(icSigGreenColorantTag, makeXYZData(g));
+ setData(icSigBlueColorantTag, makeXYZData(b));
+
+ setData(icSigMediaWhitePointTag, makeXYZData(white));
+ setData(icSigMediaBlackPointTag, makeXYZData(black));
+
+ setData(icSigRedTRCTag, makeTRC());
+ setData(icSigGreenTRCTag, makeTRC());
+ setData(icSigBlueTRCTag, makeTRC());
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("Linear RGB"));
+ this.profileID = ColorSpace.CS_LINEAR_RGB;
+ }
+
+ /**
+ * Creates an CIE XYZ identity profile
+ */
+ private void createCIEProfile()
+ {
+ header.setColorSpace( ColorSpace.TYPE_XYZ );
+ header.setProfileColorSpace( ColorSpace.TYPE_XYZ );
+ header.setProfileClass( CLASS_COLORSPACECONVERSION );
+ ICC_ColorSpace cs = new ICC_ColorSpace(this);
+
+ float[] white = D50;
+
+ setData(icSigMediaWhitePointTag, makeXYZData(white));
+ setData(icSigAToB0Tag, makeIdentityClut());
+ setData(icSigBToA0Tag, makeIdentityClut());
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("CIE XYZ identity profile"));
+ this.profileID = ColorSpace.CS_CIEXYZ;
+ }
+
+ /**
+ * Creates a linear gray ICC_Profile
+ */
+ private void createGrayProfile()
+ {
+ header.setColorSpace(ColorSpace.TYPE_GRAY);
+ header.setProfileColorSpace(ColorSpace.TYPE_XYZ);
+
+ // CIE 1931 D50 white point (in Lab coordinates)
+ float[] white = D50;
+
+ setData(icSigMediaWhitePointTag, makeXYZData(white));
+ setData(icSigGrayTRCTag, makeTRC(1.0f));
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("Linear grayscale"));
+ this.profileID = ColorSpace.CS_GRAY;
+ }
+
+ /**
+ * XXX Implement me
+ */
+ private void createPyccProfile()
+ {
+ header.setColorSpace(ColorSpace.TYPE_3CLR);
+ header.setProfileColorSpace(ColorSpace.TYPE_XYZ);
+
+ // Create CLUTs here. :-)
+
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("Photo YCC"));
+ this.profileID = ColorSpace.CS_PYCC;
+ }
+} // class ICC_Profile
diff --git a/libjava/classpath/java/awt/color/ICC_ProfileGray.java b/libjava/classpath/java/awt/color/ICC_ProfileGray.java
new file mode 100644
index 0000000..3b5948d
--- /dev/null
+++ b/libjava/classpath/java/awt/color/ICC_ProfileGray.java
@@ -0,0 +1,133 @@
+/* ICC_ProfileGray.java -- the ICC profile for a Gray colorspace
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.color;
+
+/**
+ * ICC_ProfileGray - a special case of ICC_Profiles.
+ *
+ * The ICC_Profile.getInstance() method will return an instance of the
+ * ICC_ProfileGray subclass when all the following conditions are met:
+ * The device color space of the profile is TYPE_GRAY.
+ * The profile contains a gray TRCTag.
+ * The profile contains a mediaWhitePointTag.
+ *
+ * As per the ICC specification, the color space conversion can then
+ * be done through the following method:
+ * linearGray = grayTRC[deviceGray]
+ *
+ * Note that if the profile contains a CLUT for the color space conversion,
+ * it should be used instead, and the TRC information ignored.
+ *
+ * @author Sven de Marothy
+ * @since 1.2
+ */
+public class ICC_ProfileGray extends ICC_Profile
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = -1124721290732002649L;
+ private transient float[] whitePoint;
+
+ /**
+ * Package-private constructor used by ICC_ColorSpace for creating an
+ * ICC_ProfileGray from a predefined ColorSpace (CS_GRAY)
+ */
+ ICC_ProfileGray(int cspace)
+ {
+ super(cspace);
+ whitePoint = getXYZData(icSigMediaWhitePointTag);
+ }
+
+ /**
+ * Package-private constructor used by ICC_ColorSpace for creating an
+ * ICC_ProfileGray from profile data.
+ */
+ ICC_ProfileGray(byte[] data)
+ {
+ super(data);
+ whitePoint = getXYZData(icSigMediaWhitePointTag);
+ }
+
+
+ /**
+ * Returns the media white point of the profile.
+ */
+ public float[] getMediaWhitePoint()
+ {
+ float[] wp = new float[3];
+ wp[0] = whitePoint[0];
+ wp[1] = whitePoint[1];
+ wp[2] = whitePoint[2];
+ return wp;
+ }
+
+ /**
+ * Returns the TRC gamma value.
+ * @throws ProfileDataException if the TRC is described by a lookup
+ * table and not a gamma value.
+ */
+ public float getGamma()
+ {
+ short[] data = getCurve(icSigGrayTRCTag);
+ if (data == null)
+ throw new IllegalArgumentException("Couldn't read Gray TRC data.");
+ if (data.length != 1)
+ throw new ProfileDataException("TRC is a table, not a gamma value.");
+
+ // convert the unsigned 7.8 fixed-point gamma to a float.
+ double gamma = (double) (data[0] & (0xFFFF)) / 256.0;
+ return (float) gamma;
+ }
+
+ /**
+ * Returns the TRC lookup table.
+ * @throws ProfileDataException if the TRC is described by a gamma value
+ * and not a lookup table.
+ */
+ public short[] getTRC()
+ {
+ short[] data = getCurve(icSigGrayTRCTag);
+ if (data == null)
+ throw new IllegalArgumentException("Couldn't read Gray TRC data.");
+ if (data.length <= 1)
+ throw new ProfileDataException("Gamma value, not a TRC table.");
+ return data;
+ }
+} // class ICC_ProfileGray
diff --git a/libjava/classpath/java/awt/color/ICC_ProfileRGB.java b/libjava/classpath/java/awt/color/ICC_ProfileRGB.java
new file mode 100644
index 0000000..0039332
--- /dev/null
+++ b/libjava/classpath/java/awt/color/ICC_ProfileRGB.java
@@ -0,0 +1,227 @@
+/* ICC_ProfileRGB.java -- the ICC profile for a RGB colorspace
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.color;
+
+/**
+ * ICC_ProfileRGB - a special case of ICC_Profiles.
+ *
+ * The ICC_Profile.getInstance() method will return an instance of the
+ * ICC_ProfileRGB subclass when all the following conditions are met:
+ * The device color space of the profile is TYPE_RGB.
+ * The profile contains red, green and blue ColorantTags.
+ * The profile contains red, green and blue TRCTags.
+ * The profile contains a mediaWhitePointTag included.
+ *
+ * As per the ICC specification, the color space conversion can then
+ * be done through the following method:
+ * linearR = redTRC[deviceR]
+ * linearG = greenTRC[deviceG]
+ * linearB = blueTRC[deviceB]
+ * TRC curves are either a single gamma value, or a 1-dimensional lookup table.
+ *
+ * Followed by the matrix transform:
+ * PCS = M*linear
+ *
+ * Where PCS is the vector of profile color space (must be XYZ) coordinates,
+ * linear is the vector of linear RGB coordinates, and the matrix M is
+ * constructed from the ColorantTags, where the columns are red, green and
+ * blue respectively, and the rows are X, Y and Z.
+ *
+ * Note that if the profile contains a CLUT for the color space conversion,
+ * it should be used instead, and the TRC information ignored.
+ *
+ * @author Sven de Marothy
+ * @since 1.2
+ */
+public class ICC_ProfileRGB extends ICC_Profile
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 8505067385152579334L;
+
+ public static final int REDCOMPONENT = 0;
+
+ public static final int GREENCOMPONENT = 1;
+
+ public static final int BLUECOMPONENT = 2;
+
+ private transient float[][] matrix;
+
+ private transient float[] gamma;
+
+ private transient float[] whitePoint;
+
+
+ /**
+ * Package-private constructor used by ICC_ColorSpace for creating an
+ * ICC_ProfileRGB from a predefined ColorSpace (CS_LINEAR_RGB and CS_sRGB)
+ */
+ ICC_ProfileRGB(int cspace)
+ {
+ super(cspace);
+ matrix = createMatrix();
+ whitePoint = getXYZData(icSigMediaWhitePointTag);
+ }
+
+ /**
+ * Package-private constructor used by ICC_ColorSpace for creating an
+ * ICC_ProfileRGB from profile data.
+ */
+ ICC_ProfileRGB(byte[] data)
+ {
+ super(data);
+ matrix = createMatrix();
+ whitePoint = getXYZData(icSigMediaWhitePointTag);
+ }
+
+ /**
+ * Returns the media white point of the profile.
+ */
+ public float[] getMediaWhitePoint()
+ {
+ float[] wp = new float[3];
+ wp[0] = whitePoint[0];
+ wp[1] = whitePoint[1];
+ wp[2] = whitePoint[2];
+ return wp;
+ }
+
+ /**
+ * Returns the colorant matrix of the conversion.
+ */
+ public float[][] getMatrix()
+ {
+ float[][] mat = new float[3][3];
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ mat[i][j] = matrix[i][j];
+ return mat;
+ }
+
+ /**
+ * Returns the gamma value of a component
+ * @throws ProfileDataException if the TRC is described by a lookup
+ * table and not a gamma value.
+ */
+ public float getGamma(int component)
+ {
+ short[] data;
+ switch (component)
+ {
+ case REDCOMPONENT:
+ data = getCurve(icSigRedTRCTag);
+ break;
+ case GREENCOMPONENT:
+ data = getCurve(icSigGreenTRCTag);
+ break;
+ case BLUECOMPONENT:
+ data = getCurve(icSigBlueTRCTag);
+ break;
+ default:
+ throw new IllegalArgumentException("Not a valid component");
+ }
+ if (data == null)
+ throw new IllegalArgumentException("Error reading TRC");
+
+ if (data.length != 1)
+ throw new ProfileDataException("Not a single-gamma TRC");
+
+ // convert the unsigned 7.8 fixed-point gamma to a float.
+ float gamma = (float) (((int) data[0] & 0xFF00) >> 8);
+ double fraction = ((int) data[0] & 0x00FF) / 256.0;
+ gamma += (float) fraction;
+ return gamma;
+ }
+
+ /**
+ * Returns the TRC lookup table for a component
+ * @throws ProfileDataException if the TRC is described by a gamma
+ * value and not a lookup table.
+ */
+ public short[] getTRC(int component)
+ {
+ short[] data;
+ switch (component)
+ {
+ case REDCOMPONENT:
+ data = getCurve(icSigRedTRCTag);
+ break;
+ case GREENCOMPONENT:
+ data = getCurve(icSigGreenTRCTag);
+ break;
+ case BLUECOMPONENT:
+ data = getCurve(icSigBlueTRCTag);
+ break;
+ default:
+ throw new IllegalArgumentException("Not a valid component");
+ }
+ if (data == null)
+ throw new IllegalArgumentException("Error reading TRC");
+
+ if (data.length <= 1)
+ throw new ProfileDataException("Gamma value, not a TRC table.");
+
+ return data;
+ }
+
+ /**
+ * Creates the colorspace conversion matrix from the RGB tristimulus
+ * values.
+ */
+ private float[][] createMatrix() throws IllegalArgumentException
+ {
+ float[][] mat = new float[3][3];
+ float[] r;
+ float[] g;
+ float[] b;
+ r = getXYZData(icSigRedColorantTag);
+ g = getXYZData(icSigGreenColorantTag);
+ b = getXYZData(icSigBlueColorantTag);
+ if (r == null || g == null || b == null)
+ throw new IllegalArgumentException("Error reading colorant tags!");
+ for (int i = 0; i < 3; i++)
+ {
+ mat[i][0] = r[i];
+ mat[i][1] = g[i];
+ mat[i][2] = b[i];
+ }
+ return mat;
+ }
+} // class ICC_ProfileRGB
diff --git a/libjava/classpath/java/awt/color/ProfileDataException.java b/libjava/classpath/java/awt/color/ProfileDataException.java
new file mode 100644
index 0000000..1af23b1
--- /dev/null
+++ b/libjava/classpath/java/awt/color/ProfileDataException.java
@@ -0,0 +1,64 @@
+/* ProfileDataException.java -- error in processing an ICC_Profile
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.color;
+
+/**
+ * Thrown when there is an error accessing or processing an
+ * <code>ICC_Profile</code>.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @status updated to 1.4
+ */
+public class ProfileDataException extends RuntimeException
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 7286140888240322498L;
+
+ /**
+ * Create a new instance with a specified detailed error message.
+ *
+ * @param message the message
+ */
+ public ProfileDataException(String message)
+ {
+ super(message);
+ }
+} // class ProfileDataException
diff --git a/libjava/classpath/java/awt/color/package.html b/libjava/classpath/java/awt/color/package.html
new file mode 100644
index 0000000..9a08577
--- /dev/null
+++ b/libjava/classpath/java/awt/color/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.color package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.color</title></head>
+
+<body>
+<p>Classes to represent color spaces and profiles.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/datatransfer/Clipboard.java b/libjava/classpath/java/awt/datatransfer/Clipboard.java
new file mode 100644
index 0000000..9953a72
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/Clipboard.java
@@ -0,0 +1,114 @@
+/* Clipboard.java -- Class for transferring data via cut and paste.
+ Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+/**
+ * This class allows data to be transferred using a cut and paste type
+ * mechanism.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class Clipboard
+{
+ /**
+ * The data being transferred.
+ */
+ protected Transferable contents;
+
+ /**
+ * The owner of this clipboard.
+ */
+ protected ClipboardOwner owner;
+
+ // The clipboard name
+ private String name;
+
+ /**
+ * Initializes a new instance of <code>Clipboard</code> with the
+ * specified name.
+ *
+ * @param name The clipboard name.
+ */
+ public Clipboard(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * Returns the name of the clipboard.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Returns the contents of the clipboard.
+ *
+ * @param requestor The object requesting the contents.
+ *
+ * @exception IllegalStateException If the clipboard is currently unavailable
+ */
+ public synchronized Transferable getContents(Object requestor)
+ {
+ return contents;
+ }
+
+ /**
+ * Sets the content and owner of this clipboard.
+ * If the given owner is different from the current owner
+ * then lostOwnership is called on the current owner.
+ * XXX - is this called with the old or new contents.
+ *
+ * @param contents The new clipboard contents.
+ * @param owner The new clipboard owner
+ *
+ * @exception IllegalStateException If the clipboard is currently unavailable
+ */
+ public synchronized void setContents(Transferable contents, ClipboardOwner owner)
+ {
+ if (this.owner != owner)
+ if (this.owner != null)
+ this.owner.lostOwnership(this, contents);
+
+ this.owner = owner;
+ this.contents = contents;
+ }
+}
+
diff --git a/libjava/classpath/java/awt/datatransfer/ClipboardOwner.java b/libjava/classpath/java/awt/datatransfer/ClipboardOwner.java
new file mode 100644
index 0000000..df75825
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/ClipboardOwner.java
@@ -0,0 +1,57 @@
+/* ClipboardOwner.java -- Interface for clipboard providers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+/**
+ * This interface is for classes that will own a clipboard object.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface ClipboardOwner
+{
+ /**
+ * This method is called to notify this object that it no longer
+ * has ownership of the specified <code>Clipboard</code>.
+ *
+ * @param clipboard The clipboard for which ownership was lost.
+ * @param contents The contents of the clipboard which are no longer owned.
+ */
+ void lostOwnership (Clipboard clipboard, Transferable contents);
+}
+
diff --git a/libjava/classpath/java/awt/datatransfer/DataFlavor.java b/libjava/classpath/java/awt/datatransfer/DataFlavor.java
new file mode 100644
index 0000000..e5fbd24
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/DataFlavor.java
@@ -0,0 +1,1034 @@
+/* DataFlavor.java -- A type of data to transfer via the clipboard.
+ Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+
+/**
+ * This class represents a particular data format used for transferring
+ * data via the clipboard.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class DataFlavor implements java.io.Externalizable, Cloneable
+{
+ static final long serialVersionUID = 8367026044764648243L;
+
+ // FIXME: Serialization: Need to write methods for.
+
+/**
+ * This is the data flavor used for tranferring plain text. The MIME
+ * type is "text/plain; charset=unicode". The representation class
+ * is <code>java.io.InputStream</code>.
+ *
+ * @deprecated The charset unicode is platform specific and InputStream
+ * deals with bytes not chars. Use <code>getRederForText()</code>.
+ */
+public static final DataFlavor plainTextFlavor;
+
+/**
+ * This is the data flavor used for transferring Java strings. The
+ * MIME type is "application/x-java-serialized-object" and the
+ * representation class is <code>java.lang.String</code>.
+ */
+public static final DataFlavor stringFlavor;
+
+/**
+ * This is a data flavor used for transferring lists of files. The
+ * representation type is a <code>java.util.List</code>, with each element of
+ * the list being a <code>java.io.File</code>.
+ */
+public static final DataFlavor javaFileListFlavor;
+
+/**
+ * This is an image flavor used for transferring images. The
+ * representation type is a <code>java.awt.Image</code>.
+ */
+public static final DataFlavor imageFlavor;
+
+/**
+ * This is the MIME type used for transferring a serialized object.
+ * The representation class is the type of object be deserialized.
+ */
+public static final String javaSerializedObjectMimeType =
+ "application/x-java-serialized-object";
+
+/**
+ * This is the MIME type used to transfer a Java object reference within
+ * the same JVM. The representation class is the class of the object
+ * being transferred.
+ */
+public static final String javaJVMLocalObjectMimeType =
+ "application/x-java-jvm-local-objectref";
+
+/**
+ * This is the MIME type used to transfer a link to a remote object.
+ * The representation class is the type of object being linked to.
+ */
+public static final String javaRemoteObjectMimeType =
+ "application/x-java-remote-object";
+
+static
+{
+ plainTextFlavor
+ = new DataFlavor(java.io.InputStream.class,
+ "text/plain; charset=unicode",
+ "plain unicode text");
+
+ stringFlavor
+ = new DataFlavor(java.lang.String.class,
+ "Java Unicode String");
+
+ javaFileListFlavor
+ = new DataFlavor(java.util.List.class,
+ "Java File List");
+
+ // javaFileListFlavor.mimeType = "application/x-java-file-list";
+
+ imageFlavor
+ = new DataFlavor(java.awt.Image.class,
+ "Java Image");
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+// The MIME type for this flavor
+private final String mimeType;
+
+// The representation class for this flavor
+private final Class representationClass;
+
+// The human readable name of this flavor
+private String humanPresentableName;
+
+/*************************************************************************/
+
+/*
+ * Static Methods
+ */
+
+/**
+ * This method attempts to load the named class. The following class
+ * loaders are searched in order: the bootstrap class loader, the
+ * system class loader, the context class loader (if it exists), and
+ * the specified fallback class loader.
+ *
+ * @param className The name of the class to load.
+ * @param classLoader The class loader to use if all others fail, which
+ * may be <code>null</code>.
+ *
+ * @exception ClassNotFoundException If the class cannot be loaded.
+ */
+protected static final Class
+tryToLoadClass(String className, ClassLoader classLoader)
+ throws ClassNotFoundException
+{
+ try
+ {
+ return(Class.forName(className));
+ }
+ catch(Exception e) { ; }
+ // Commented out for Java 1.1
+ /*
+ try
+ {
+ return(className.getClass().getClassLoader().findClass(className));
+ }
+ catch(Exception e) { ; }
+
+ try
+ {
+ return(ClassLoader.getSystemClassLoader().findClass(className));
+ }
+ catch(Exception e) { ; }
+ */
+
+ // FIXME: What is the context class loader?
+ /*
+ try
+ {
+ }
+ catch(Exception e) { ; }
+ */
+
+ if (classLoader != null)
+ return(classLoader.loadClass(className));
+ else
+ throw new ClassNotFoundException(className);
+}
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Empty public constructor needed for externalization.
+ * Should not be used for normal instantiation.
+ */
+public
+DataFlavor()
+{
+ mimeType = null;
+ representationClass = null;
+ humanPresentableName = null;
+}
+
+/*************************************************************************/
+
+/**
+ * Private constructor.
+ */
+private
+DataFlavor(Class representationClass,
+ String mimeType,
+ String humanPresentableName)
+{
+ this.representationClass = representationClass;
+ this.mimeType = mimeType;
+ if (humanPresentableName != null)
+ this.humanPresentableName = humanPresentableName;
+ else
+ this.humanPresentableName = mimeType;
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>DataFlavor</code>. The class
+ * and human readable name are specified, the MIME type will be
+ * "application/x-java-serialized-object". If the human readable name
+ * is not specified (<code>null</code>) then the human readable name
+ * will be the same as the MIME type.
+ *
+ * @param representationClass The representation class for this object.
+ * @param humanPresentableName The display name of the object.
+ */
+public
+DataFlavor(Class representationClass, String humanPresentableName)
+{
+ this(representationClass,
+ "application/x-java-serialized-object"
+ + "; class="
+ + representationClass.getName(),
+ humanPresentableName);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>DataFlavor</code> with the
+ * specified MIME type and description. If the MIME type has a
+ * "class=&lt;rep class&gt;" parameter then the representation class will
+ * be the class name specified. Otherwise the class defaults to
+ * <code>java.io.InputStream</code>. If the human readable name
+ * is not specified (<code>null</code>) then the human readable name
+ * will be the same as the MIME type.
+ *
+ * @param mimeType The MIME type for this flavor.
+ * @param humanPresentableName The display name of this flavor.
+ * @param classLoader The class loader for finding classes if the default
+ * class loaders do not work.
+ *
+ * @exception IllegalArgumentException If the representation class
+ * specified cannot be loaded.
+ * @exception ClassNotFoundException If the class is not loaded.
+ */
+public
+DataFlavor(String mimeType, String humanPresentableName,
+ ClassLoader classLoader) throws ClassNotFoundException
+{
+ this(getRepresentationClassFromMime(mimeType, classLoader),
+ mimeType, humanPresentableName);
+}
+
+private static Class
+getRepresentationClassFromMime(String mimeString, ClassLoader classLoader)
+{
+ String classname = getParameter("class", mimeString);
+ if (classname != null)
+ {
+ try
+ {
+ return tryToLoadClass(classname, classLoader);
+ }
+ catch(Exception e)
+ {
+ throw new IllegalArgumentException("classname: " + e.getMessage());
+ }
+ }
+ else
+ {
+ return java.io.InputStream.class;
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>DataFlavor</code> with the
+ * specified MIME type and description. If the MIME type has a
+ * "class=&lt;rep class&gt;" parameter then the representation class will
+ * be the class name specified. Otherwise the class defaults to
+ * <code>java.io.InputStream</code>. If the human readable name
+ * is not specified (<code>null</code>) then the human readable name
+ * will be the same as the MIME type. This is the same as calling
+ * <code>new DataFlavor(mimeType, humanPresentableName, null)</code>.
+ *
+ * @param mimeType The MIME type for this flavor.
+ * @param humanPresentableName The display name of this flavor.
+ *
+ * @exception IllegalArgumentException If the representation class
+ * specified cannot be loaded.
+ */
+public
+DataFlavor(String mimeType, String humanPresentableName)
+{
+ this (getRepresentationClassFromMime (mimeType, null), humanPresentableName);
+}
+
+/*************************************************************************/
+
+/**
+ * Initializes a new instance of <code>DataFlavor</code> with the specified
+ * MIME type. This type can have a "class=" parameter to specify the
+ * representation class, and then the class must exist or an exception will
+ * be thrown. If there is no "class=" parameter then the representation class
+ * will be <code>java.io.InputStream</code>. This is the same as calling
+ * <code>new DataFlavor(mimeType, null)</code>.
+ *
+ * @param mimeType The MIME type for this flavor.
+ *
+ * @exception IllegalArgumentException If a class is not specified in
+ * the MIME type.
+ * @exception ClassNotFoundException If the class cannot be loaded.
+ */
+public
+DataFlavor(String mimeType) throws ClassNotFoundException
+{
+ this(mimeType, null);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the MIME type of this flavor.
+ *
+ * @return The MIME type for this flavor.
+ */
+public String
+getMimeType()
+{
+ return(mimeType);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the representation class for this flavor.
+ *
+ * @return The representation class for this flavor.
+ */
+public Class
+getRepresentationClass()
+{
+ return(representationClass);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the human presentable name for this flavor.
+ *
+ * @return The human presentable name for this flavor.
+ */
+public String
+getHumanPresentableName()
+{
+ return(humanPresentableName);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the primary MIME type for this flavor.
+ *
+ * @return The primary MIME type for this flavor.
+ */
+public String
+getPrimaryType()
+{
+ int idx = mimeType.indexOf("/");
+ if (idx == -1)
+ return(mimeType);
+
+ return(mimeType.substring(0, idx));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the MIME subtype for this flavor.
+ *
+ * @return The MIME subtype for this flavor.
+ */
+public String
+getSubType()
+{
+ int idx = mimeType.indexOf("/");
+ if (idx == -1)
+ return("");
+
+ String subtype = mimeType.substring(idx + 1);
+
+ idx = subtype.indexOf(" ");
+ if (idx == -1)
+ return(subtype);
+ else
+ return(subtype.substring(0, idx));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the value of the named MIME type parameter, or <code>null</code>
+ * if the parameter does not exist. Given the parameter name and the mime
+ * string.
+ *
+ * @param paramName The name of the parameter.
+ * @param mimeString The mime string from where the name should be found.
+ *
+ * @return The value of the parameter or null.
+ */
+private static String
+getParameter(String paramName, String mimeString)
+{
+ int idx = mimeString.indexOf(paramName + "=");
+ if (idx == -1)
+ return(null);
+
+ String value = mimeString.substring(idx + paramName.length() + 1);
+
+ idx = value.indexOf(" ");
+ if (idx == -1)
+ return(value);
+ else
+ return(value.substring(0, idx));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the value of the named MIME type parameter, or <code>null</code>
+ * if the parameter does not exist.
+ *
+ * @param paramName The name of the paramter.
+ *
+ * @return The value of the parameter.
+ */
+public String
+getParameter(String paramName)
+{
+ return getParameter(paramName, mimeType);
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the human presentable name to the specified value.
+ *
+ * @param humanPresentableName The new display name.
+ */
+public void
+setHumanPresentableName(String humanPresentableName)
+{
+ this.humanPresentableName = humanPresentableName;
+}
+
+/*************************************************************************/
+
+/**
+ * Tests the MIME type of this object for equality against the specified
+ * MIME type.
+ *
+ * @param mimeType The MIME type to test against.
+ *
+ * @return <code>true</code> if the MIME type is equal to this object's
+ * MIME type, <code>false</code> otherwise.
+ *
+ * @exception NullPointerException If mimeType is null.
+ */
+public boolean
+isMimeTypeEqual(String mimeType)
+{
+ // FIXME: Need to handle default attributes and parameters
+
+ return(this.mimeType.equals(mimeType));
+}
+
+/*************************************************************************/
+
+/**
+ * Tests the MIME type of this object for equality against the specified
+ * data flavor's MIME type
+ *
+ * @param flavor The flavor to test against.
+ *
+ * @return <code>true</code> if the flavor's MIME type is equal to this
+ * object's MIME type, <code>false</code> otherwise.
+ */
+public final boolean
+isMimeTypeEqual(DataFlavor flavor)
+{
+ return(isMimeTypeEqual(flavor.getMimeType()));
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this flavor represents a serialized object.
+ *
+ * @return <code>true</code> if this flavor represents a serialized
+ * object, <code>false</code> otherwise.
+ */
+public boolean
+isMimeTypeSerializedObject()
+{
+ return(mimeType.startsWith(javaSerializedObjectMimeType));
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this flavor has a representation class of
+ * <code>java.io.InputStream</code>.
+ *
+ * @return <code>true</code> if the representation class of this flavor
+ * is <code>java.io.InputStream</code>, <code>false</code> otherwise.
+ */
+public boolean
+isRepresentationClassInputStream()
+{
+ return(representationClass.getName().equals("java.io.InputStream"));
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether the representation class for this flavor is
+ * serializable.
+ *
+ * @return <code>true</code> if the representation class is serializable,
+ * <code>false</code> otherwise.
+ */
+public boolean
+isRepresentationClassSerializable()
+{
+ Class[] interfaces = representationClass.getInterfaces();
+
+ int i = 0;
+ while (i < interfaces.length)
+ {
+ if (interfaces[i].getName().equals("java.io.Serializable"))
+ return(true);
+ ++i;
+ }
+
+ return(false);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether the representation class for his flavor is remote.
+ *
+ * @return <code>true</code> if the representation class is remote,
+ * <code>false</code> otherwise.
+ */
+public boolean
+isRepresentationClassRemote()
+{
+ // FIXME: Implement
+ throw new RuntimeException("Not implemented");
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this flavor represents a serialized object.
+ *
+ * @return <code>true</code> if this flavor represents a serialized
+ * object, <code>false</code> otherwise.
+ */
+public boolean
+isFlavorSerializedObjectType()
+{
+ // FIXME: What is the diff between this and isMimeTypeSerializedObject?
+ return(mimeType.startsWith(javaSerializedObjectMimeType));
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this flavor represents a remote object.
+ *
+ * @return <code>true</code> if this flavor represents a remote object,
+ * <code>false</code> otherwise.
+ */
+public boolean
+isFlavorRemoteObjectType()
+{
+ return(mimeType.startsWith(javaRemoteObjectMimeType));
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not this flavor represents a list of files.
+ *
+ * @return <code>true</code> if this flavor represents a list of files,
+ * <code>false</code> otherwise.
+ */
+public boolean
+isFlavorJavaFileListType()
+{
+ if (this.mimeType.equals(javaFileListFlavor.mimeType) &&
+ this.representationClass.equals(javaFileListFlavor.representationClass))
+ return(true);
+
+ return(false);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a copy of this object.
+ *
+ * @return A copy of this object.
+ *
+ * @exception CloneNotSupportedException If the object's class does not support
+ * the Cloneable interface. Subclasses that override the clone method can also
+ * throw this exception to indicate that an instance cannot be cloned.
+ */
+public Object clone () throws CloneNotSupportedException
+{
+ try
+ {
+ return(super.clone());
+ }
+ catch(Exception e)
+ {
+ return(null);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * This method test the specified <code>DataFlavor</code> for equality
+ * against this object. This will be true if the MIME type and
+ * representation type are the equal.
+ *
+ * @param flavor The <code>DataFlavor</code> to test against.
+ *
+ * @return <code>true</code> if the flavor is equal to this object,
+ * <code>false</code> otherwise.
+ */
+public boolean
+equals(DataFlavor flavor)
+{
+ if (flavor == null)
+ return(false);
+
+ if (!this.mimeType.toLowerCase().equals(flavor.mimeType.toLowerCase()))
+ return(false);
+
+ if (!this.representationClass.equals(flavor.representationClass))
+ return(false);
+
+ return(true);
+}
+
+/*************************************************************************/
+
+/**
+ * This method test the specified <code>Object</code> for equality
+ * against this object. This will be true if the following conditions
+ * are met:
+ * <p>
+ * <ul>
+ * <li>The object is not <code>null</code>.</li>
+ * <li>The object is an instance of <code>DataFlavor</code>.</li>
+ * <li>The object's MIME type and representation class are equal to
+ * this object's.</li>
+ * </ul>
+ *
+ * @param obj The <code>Object</code> to test against.
+ *
+ * @return <code>true</code> if the flavor is equal to this object,
+ * <code>false</code> otherwise.
+ */
+public boolean
+equals(Object obj)
+{
+ if (!(obj instanceof DataFlavor))
+ return(false);
+
+ return(equals((DataFlavor)obj));
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not the specified string is equal to the MIME type
+ * of this object.
+ *
+ * @param str The string to test against.
+ *
+ * @return <code>true</code> if the string is equal to this object's MIME
+ * type, <code>false</code> otherwise.
+ *
+ * @deprecated Not compatible with <code>hashCode()</code>.
+ * Use <code>isMimeTypeEqual()</code>
+ */
+public boolean
+equals(String str)
+{
+ return(isMimeTypeEqual(str));
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the hash code for this data flavor.
+ * The hash code is based on the (lower case) mime type and the
+ * representation class.
+ */
+public int
+hashCode()
+{
+ return(mimeType.toLowerCase().hashCode()^representationClass.hashCode());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns <code>true</code> when the given <code>DataFlavor</code>
+ * matches this one.
+ */
+public boolean
+match(DataFlavor dataFlavor)
+{
+ // XXX - How is this different from equals?
+ return(equals(dataFlavor));
+}
+
+/*************************************************************************/
+
+/**
+ * This method exists for backward compatibility. It simply returns
+ * the same name/value pair passed in.
+ *
+ * @param name The parameter name.
+ * @param value The parameter value.
+ *
+ * @return The name/value pair.
+ *
+ * @deprecated
+ */
+protected String
+normalizeMimeTypeParameter(String name, String value)
+{
+ return(name + "=" + value);
+}
+
+/*************************************************************************/
+
+/**
+ * This method exists for backward compatibility. It simply returns
+ * the MIME type string unchanged.
+ *
+ * @param type The MIME type.
+ *
+ * @return The MIME type.
+ *
+ * @deprecated
+ */
+protected String
+normalizeMimeType(String type)
+{
+ return(type);
+}
+
+/*************************************************************************/
+
+/**
+ * Serialize this class.
+ *
+ * @param stream The <code>ObjectOutput</code> stream to serialize to.
+ *
+ * @exception IOException If an error occurs.
+ */
+public void
+writeExternal(ObjectOutput stream) throws IOException
+{
+ // FIXME: Implement me
+}
+
+/*************************************************************************/
+
+/**
+ * De-serialize this class.
+ *
+ * @param stream The <code>ObjectInput</code> stream to deserialize from.
+ *
+ * @exception IOException If an error ocurs.
+ * @exception ClassNotFoundException If the class for an object being restored
+ * cannot be found.
+ */
+public void
+readExternal(ObjectInput stream) throws IOException, ClassNotFoundException
+{
+ // FIXME: Implement me
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a string representation of this DataFlavor. Including the
+ * representation class name, MIME type and human presentable name.
+ */
+public String
+toString()
+{
+ return("DataFlavor[representationClass="
+ + representationClass.getName()
+ + ",mimeType="
+ + mimeType
+ + "humanPresentableName="
+ + humanPresentableName);
+}
+
+/*************************************************************************/
+
+/**
+ * XXX - Currently returns <code>plainTextFlavor</code>.
+ */
+public static final DataFlavor
+getTextPlainUnicodeFlavor()
+{
+ return(plainTextFlavor);
+}
+
+/*************************************************************************/
+
+/**
+ * XXX - Currently returns <code>java.io.InputStream</code>.
+ *
+ * @since 1.3
+ */
+public final Class
+getDefaultRepresentationClass()
+{
+ return(java.io.InputStream.class);
+}
+/*************************************************************************/
+
+/**
+ * XXX - Currently returns <code>java.io.InputStream</code>.
+ */
+public final String
+getDefaultRepresentationClassAsString()
+{
+ return(getDefaultRepresentationClass().getName());
+}
+
+/*************************************************************************/
+
+/**
+ * Selects the best supported text flavor on this implementation.
+ * Returns <code>null</code> when none of the given flavors is liked.
+ *
+ * The <code>DataFlavor</code> returned the first data flavor in the
+ * array that has either a representation class which is (a subclass of)
+ * <code>Reader</code> or <code>String</code>, or has a representation
+ * class which is (a subclass of) <code>InputStream</code> and has a
+ * primary MIME type of "text" and has an supported encoding.
+ */
+public static final DataFlavor
+selectBestTextFlavor(DataFlavor[] availableFlavors)
+{
+ for(int i=0; i<availableFlavors.length; i++)
+ {
+ DataFlavor df = availableFlavors[i];
+ Class c = df.representationClass;
+
+ // A Reader or String is good.
+ if ((Reader.class.isAssignableFrom(c))
+ || (String.class.isAssignableFrom(c)))
+ {
+ return df;
+ }
+
+ // A InputStream is good if the mime primary type is "text"
+ if ((InputStream.class.isAssignableFrom(c))
+ && ("text".equals(df.getPrimaryType())))
+ {
+ String encoding = availableFlavors[i].getParameter("charset");
+ if (encoding == null)
+ encoding = "us-ascii";
+ Reader r = null;
+ try
+ {
+ // Try to construct a dummy reader with the found encoding
+ r = new InputStreamReader
+ (new ByteArrayInputStream(new byte[0]), encoding);
+ }
+ catch(UnsupportedEncodingException uee) { /* ignore */ }
+ if (r != null)
+ return df;
+ }
+ }
+
+ // Nothing found
+ return(null);
+}
+
+/*************************************************************************/
+
+/**
+ * Creates a <code>Reader</code> for a given <code>Transferable</code>.
+ *
+ * If the representation class is a (subclass of) <code>Reader</code>
+ * then an instance of the representation class is returned. If the
+ * representatation class is a <code>String</code> then a
+ * <code>StringReader</code> is returned. And if the representation class
+ * is a (subclass of) <code>InputStream</code> and the primary MIME type
+ * is "text" then a <code>InputStreamReader</code> for the correct charset
+ * encoding is returned.
+ *
+ * @param transferable The <code>Transferable</code> for which a text
+ * <code>Reader</code> is requested.
+ *
+ * @exception IllegalArgumentException If the representation class is not one
+ * of the seven listed above or the Transferable has null data.
+ * @exception NullPointerException If the Transferable is null.
+ * @exception UnsupportedFlavorException when the transferable doesn't
+ * support this <code>DataFlavor</code>. Or if the representable class
+ * isn't a (subclass of) <code>Reader</code>, <code>String</code>,
+ * <code>InputStream</code> and/or the primary MIME type isn't "text".
+ * @exception IOException when any IOException occurs.
+ * @exception UnsupportedEncodingException if the "charset" isn't supported
+ * on this platform.
+ */
+public Reader getReaderForText(Transferable transferable)
+ throws UnsupportedFlavorException, IOException
+{
+ if (!transferable.isDataFlavorSupported(this))
+ throw new UnsupportedFlavorException(this);
+
+ if (Reader.class.isAssignableFrom(representationClass))
+ return((Reader)transferable.getTransferData(this));
+
+ if (String.class.isAssignableFrom(representationClass))
+ return(new StringReader((String)transferable.getTransferData(this)));
+
+ if (InputStream.class.isAssignableFrom(representationClass)
+ && "text".equals(getPrimaryType()))
+ {
+ InputStream in = (InputStream)transferable.getTransferData(this);
+ String encoding = getParameter("charset");
+ if (encoding == null)
+ encoding = "us-ascii";
+ return(new InputStreamReader(in, encoding));
+ }
+
+ throw new UnsupportedFlavorException(this);
+}
+
+ /**
+ * Returns whether the representation class for this DataFlavor is
+ * @see java.nio.ByteBuffer or a subclass thereof.
+ *
+ * @since 1.4
+ */
+ public boolean isRepresentationClassByteBuffer ()
+ {
+ return ByteBuffer.class.isAssignableFrom (representationClass);
+ }
+
+ /**
+ * Returns whether the representation class for this DataFlavor is
+ * @see java.nio.CharBuffer or a subclass thereof.
+ *
+ * @since 1.4
+ */
+ public boolean isRepresentationClassCharBuffer ()
+ {
+ return CharBuffer.class.isAssignableFrom (representationClass);
+ }
+
+ /**
+ * Returns whether the representation class for this DataFlavor is
+ * @see java.io.Reader or a subclass thereof.
+ *
+ * @since 1.4
+ */
+ public boolean isRepresentationClassReader ()
+ {
+ return Reader.class.isAssignableFrom (representationClass);
+ }
+
+} // class DataFlavor
+
diff --git a/libjava/classpath/java/awt/datatransfer/FlavorMap.java b/libjava/classpath/java/awt/datatransfer/FlavorMap.java
new file mode 100644
index 0000000..59718c4
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/FlavorMap.java
@@ -0,0 +1,75 @@
+/* FlavorMap.java -- Maps between flavor names and MIME types.
+ Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+import java.util.Map;
+
+/**
+ * This interface maps between native platform type names and DataFlavors.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface FlavorMap
+{
+ /**
+ * Maps the specified <code>DataFlavor</code> objects to the native
+ * data type name. The returned <code>Map</code> has keys that are
+ * the data flavors and values that are strings. The returned map
+ * may be modified. This can be useful for implementing nested mappings.
+ *
+ * @param flavors An array of data flavors to map
+ * or null for all data flavors.
+ *
+ * @return A <code>Map</code> of native data types.
+ */
+ Map getNativesForFlavors (DataFlavor[] flavors);
+
+ /**
+ * Maps the specified native type names to <code>DataFlavor</code>'s.
+ * The returned <code>Map</code> has keys that are strings and values
+ * that are <code>DataFlavor</code>'s. The returned map may be
+ * modified. This can be useful for implementing nested mappings.
+ *
+ * @param natives An array of native types to map
+ * or null for all native types.
+ *
+ * @return A <code>Map</code> of data flavors.
+ */
+ Map getFlavorsForNatives (String[] natives);
+}
diff --git a/libjava/classpath/java/awt/datatransfer/FlavorTable.java b/libjava/classpath/java/awt/datatransfer/FlavorTable.java
new file mode 100644
index 0000000..11cdda0
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/FlavorTable.java
@@ -0,0 +1,73 @@
+/* FlavorTable.java -- A relaxed mapping between flavors
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+import java.util.List;
+
+/**
+ * A FlavorMap which no longer requires a 1-to-1 mapping between flavors. Any
+ * native can map to multiple flavors, and any flavor can map to multiple
+ * natives; although the mappings are usually symmetric.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public interface FlavorTable extends FlavorMap
+{
+ /**
+ * Returns a list of String natives corresponding to the given flavor. The
+ * list should be sorted from best to worst. The list must be modifiable
+ * without affecting this table.
+ *
+ * @param flavor the flavor to look up, or null to return all natives
+ * @return the sorted list of natives
+ */
+ List getNativesForFlavor(DataFlavor flavor);
+
+ /**
+ * Returns a list of flavors corresponding to the given String native. The
+ * list should be sorted from best to worst. The list must be modifiable
+ * without affecting this table.
+ *
+ * @param name the native name to look up, or null to return all flavors
+ * @return the sorted list of flavors
+ */
+ List getFlavorsForNative(String name);
+}
diff --git a/libjava/classpath/java/awt/datatransfer/MimeTypeParseException.java b/libjava/classpath/java/awt/datatransfer/MimeTypeParseException.java
new file mode 100644
index 0000000..6113ab7
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/MimeTypeParseException.java
@@ -0,0 +1,70 @@
+/* MimeTypeParseException.java -- thrown when MIME string couldn't be parsed
+ Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+/**
+ * MIME string couldn't be parsed correctly.
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ * @status updated to 1.4
+ */
+public class MimeTypeParseException extends Exception
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -5604407764691570741L;
+
+ /**
+ * Create a new instance without any message.
+ */
+ public MimeTypeParseException()
+ {
+ }
+
+ /**
+ * Create a new instance with a specified detailed error message.
+ *
+ * @param message the message
+ */
+ public MimeTypeParseException(String message)
+ {
+ super(message);
+ }
+} // class MimeTypeParseException
diff --git a/libjava/classpath/java/awt/datatransfer/StringSelection.java b/libjava/classpath/java/awt/datatransfer/StringSelection.java
new file mode 100644
index 0000000..b74f2fa
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/StringSelection.java
@@ -0,0 +1,158 @@
+/* StringSelection.java -- Clipboard handler for text.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * This class transfers a string as plain text using the clipboard.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class StringSelection implements Transferable, ClipboardOwner
+{
+
+/*
+ * Class Variables
+ */
+
+// List of flavors we support
+// XXX: DataFlavor.plainTextFlavor is deprecated.
+static final DataFlavor[] supported_flavors
+ = { DataFlavor.stringFlavor,
+ DataFlavor.plainTextFlavor };
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+// This is the data to transfer
+private String data;
+
+ /**
+ * Transfer the specfied string as text.
+ *
+ * @param data the data for the string selection
+ */
+ public StringSelection(String data)
+ {
+ this.data = data;
+ }
+
+/**
+ * Returns a list of supported data flavors.
+ *
+ * @return A list of supported data flavors.
+ */
+public DataFlavor[]
+getTransferDataFlavors()
+{
+ return(supported_flavors);
+}
+
+/*************************************************************************/
+
+/**
+ * Tests whether or not the specified data flavor is supported.
+ *
+ * @param flavor The data flavor to test.
+ *
+ * @return <code>true</code> if the data flavor is supported,
+ * <code>false</code> otherwise.
+ */
+public boolean
+isDataFlavorSupported(DataFlavor flavor)
+{
+ for (int i = 0; i < supported_flavors.length; i++)
+ if (supported_flavors[i].equals(flavor))
+ return(true);
+
+ return(false);
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the data in the requested format.
+ *
+ * @param flavor The desired data flavor.
+ *
+ * @return The transferred data.
+ *
+ * @exception UnsupportedFlavorException If the specified flavor is not
+ * supported.
+ * @exception IOException If any other error occurs.
+ */
+public Object
+getTransferData(DataFlavor flavor) throws UnsupportedFlavorException,
+ IOException
+{
+ if (!isDataFlavorSupported(flavor))
+ throw new UnsupportedFlavorException(flavor);
+
+ if (DataFlavor.plainTextFlavor == flavor)
+ /* The behavior of this method for DataFlavor.plainTextFlavor and
+ equivalent DataFlavors is inconsistent with the definition of
+ DataFlavor.plainTextFlavor. We choose to do like Sun's implementation
+ and return a Reader instead of an InputString. */
+ /* return(new StringBufferInputStream(data)); */
+ return(new StringReader(data));
+ else // DataFlavor.stringFlavor
+ return data;
+}
+
+/*************************************************************************/
+
+/**
+ * Called when ownership of the clipboard object is lost.
+ *
+ * @param clipboard The affected clipboard.
+ * @param contents The clipboard contents.
+ */
+public void
+lostOwnership(Clipboard clipboard, Transferable contents)
+{
+ // FIXME: What does this do?
+}
+
+} // class StringSelection
+
diff --git a/libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java b/libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java
new file mode 100644
index 0000000..f6530f5
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java
@@ -0,0 +1,169 @@
+/* SystemFlavorMap.java -- Maps between native flavor names and MIME types.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class maps between native platform type names and DataFlavors.
+ *
+ * XXX - The current implementation does no mapping at all.
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ *
+ * @since 1.2
+ */
+public final class SystemFlavorMap implements FlavorMap, FlavorTable
+{
+ /**
+ * The default (instance) flavor map.
+ */
+ private static FlavorMap defaultFlavorMap;
+
+ /**
+ * Private constructor.
+ */
+ private SystemFlavorMap ()
+ {
+ }
+
+ /**
+ * Maps the specified <code>DataFlavor</code> objects to the native
+ * data type name. The returned <code>Map</code> has keys that are
+ * the data flavors and values that are strings. The returned map
+ * may be modified. This can be useful for implementing nested mappings.
+ *
+ * @param flavors An array of data flavors to map
+ * or null for all data flavors.
+ *
+ * @return A <code>Map</code> of native data types to data flavors.
+ */
+ public Map getNativesForFlavors (DataFlavor[] flavors)
+ {
+ return new HashMap();
+ }
+
+ /**
+ * Maps the specified native type names to <code>DataFlavor</code>'s.
+ * The returned <code>Map</code> has keys that are strings and values
+ * that are <code>DataFlavor</code>'s. The returned map may be
+ * modified. This can be useful for implementing nested mappings.
+ *
+ * @param natives An array of native types to map
+ * or null for all native types.
+ *
+ * @return A <code>Map</code> of data flavors to native type names.
+ */
+ public Map getFlavorsForNatives (String[] natives)
+ {
+ return new HashMap();
+ }
+
+ /**
+ * Returns the default (instance) (System)FlavorMap.
+ */
+ public static FlavorMap getDefaultFlavorMap ()
+ {
+ if (defaultFlavorMap == null)
+ defaultFlavorMap = new SystemFlavorMap ();
+
+ return defaultFlavorMap;
+ }
+
+ /**
+ * Returns the native type name for the given java mime type.
+ */
+ public static String encodeJavaMIMEType (String mime)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the native type name for the given data flavor.
+ */
+ public static String encodeDataFlavor (DataFlavor df)
+ {
+ return null;
+ }
+
+ /**
+ * Returns true if the native type name can be represented as
+ * a java mime type.
+ */
+ public static boolean isJavaMIMEType (String name)
+ {
+ return false;
+ }
+
+ /**
+ * Returns the java mime type for the given the native type name.
+ */
+ public static String decodeJavaMIMEType (String name)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the data flavor given the native type name
+ * or null when no such data flavor exists.
+ */
+ public static DataFlavor decodeDataFlavor (String name)
+ throws ClassNotFoundException
+ {
+ String javaMIMEType = decodeJavaMIMEType (name);
+
+ if (javaMIMEType != null)
+ return new DataFlavor (javaMIMEType);
+ else
+ return null;
+ }
+
+ public List getFlavorsForNative (String nat)
+ {
+ throw new Error ("Not implemented");
+ }
+
+ public List getNativesForFlavor (DataFlavor flav)
+ {
+ throw new Error ("Not implemented");
+ }
+
+} // class SystemFlavorMap
diff --git a/libjava/classpath/java/awt/datatransfer/Transferable.java b/libjava/classpath/java/awt/datatransfer/Transferable.java
new file mode 100644
index 0000000..8075392
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/Transferable.java
@@ -0,0 +1,83 @@
+/* Transferable.java -- Data transfer source
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+import java.io.IOException;
+
+/**
+ * This interface is implemented by classes that can transfer data.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface Transferable
+{
+ /**
+ * This method returns a list of available data flavors for the data being
+ * transferred. The array returned will be sorted from most preferred
+ * flavor at the beginning to least preferred at the end.
+ *
+ * @return adA list of data flavors for this data
+ */
+ DataFlavor[] getTransferDataFlavors();
+
+ /**
+ * Tests whether or not this data can be delivered in the specified data
+ * flavor.
+ *
+ * @param flavor the data flavor to test
+ * @return true if the data flavor is supported
+ */
+ boolean isDataFlavorSupported(DataFlavor flavor);
+
+ /**
+ * Returns the data in the specified <code>DataFlavor</code>.
+ *
+ * @param flavor the data flavor to return
+ * @return the data in the appropriate flavor
+ * @throws UnsupportedFlavorException if the flavor is not supported
+ * @throws IOException if the data is not available
+ * @see DataFlavor#getRepresentationClass
+ */
+ Object getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException;
+
+} // interface Transferable
+
diff --git a/libjava/classpath/java/awt/datatransfer/UnsupportedFlavorException.java b/libjava/classpath/java/awt/datatransfer/UnsupportedFlavorException.java
new file mode 100644
index 0000000..1c1da03
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/UnsupportedFlavorException.java
@@ -0,0 +1,65 @@
+/* UnsupportedFlavorException.java -- ata flavor is not valid
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.datatransfer;
+
+/**
+ * The data flavor requested is not supported for the transfer data.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see Transferable#getTransferData(DataFlavor)
+ * @status updated to 1.4
+ */
+public class UnsupportedFlavorException extends Exception
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 5383814944251665601L;
+
+ /**
+ * Initializes a new instance of <code>UnsupportedDataFlavor</code>
+ * for the specified data flavor.
+ *
+ * @param flavor the data flavor that is not supported
+ */
+ public UnsupportedFlavorException(DataFlavor flavor)
+ {
+ super(flavor == null ? null : flavor.getHumanPresentableName());
+ }
+} // class UnsupportedFlavorException
diff --git a/libjava/classpath/java/awt/datatransfer/package.html b/libjava/classpath/java/awt/datatransfer/package.html
new file mode 100644
index 0000000..5ab860c
--- /dev/null
+++ b/libjava/classpath/java/awt/datatransfer/package.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.datatransfer package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.datatransfer</title></head>
+
+<body>
+<p>Classes to represent different flavors of data for transferring native
+and system types through for example a clipboard.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/dnd/Autoscroll.java b/libjava/classpath/java/awt/dnd/Autoscroll.java
new file mode 100644
index 0000000..ba4d447
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/Autoscroll.java
@@ -0,0 +1,70 @@
+/* Autoscroll.java --
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.Insets;
+import java.awt.Point;
+
+/**
+ * During DnD operations it is possible that a user may wish to drop the
+ * subject of the operation on a region of a scrollable GUI control that
+ * is not currently visible to the user.
+ *
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface Autoscroll
+{
+ /**
+ * This method returns the Insets describing the autoscrolling region or
+ * border relative to the geometry of the implementing Component
+ */
+ Insets getAutoscrollInsets ();
+
+ /**
+ * Notify the Component to autoscroll
+ *
+ * @param location A Point indicating the location of the cursor that
+ * triggered this operation
+ */
+ void autoscroll (Point location);
+
+} // interface Autoscroll
+
diff --git a/libjava/classpath/java/awt/dnd/DnDConstants.java b/libjava/classpath/java/awt/dnd/DnDConstants.java
new file mode 100644
index 0000000..85c9c05
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DnDConstants.java
@@ -0,0 +1,77 @@
+/* DnDConstants.java -- constants for drag-and-drop operations
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+/**
+ * This class contains various constants used in drag-and-drop operations.
+ * Why it is not an interface is beyond me.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public final class DnDConstants
+{
+ /** No action takes place. */
+ public static final int ACTION_NONE = 0;
+
+ /** The copy action. */
+ public static final int ACTION_COPY = 1;
+
+ /** The move action. */
+ public static final int ACTION_MOVE = 2;
+
+ /** Either a copy or a move. */
+ public static final int ACTION_COPY_OR_MOVE = 3;
+
+ /**
+ * A link action. This does not copy or move, but creates a reference back
+ * to the original. However, since platforms differ on how a reference should
+ * behave, this action is not recommended for common use.
+ */
+ public static final int ACTION_LINK = 1073741824;
+
+ /** A synonym for {@link #ACTION_LINK}. */
+ public static final int ACTION_REFERENCE = ACTION_LINK;
+
+ private DnDConstants()
+ {
+ // Do nothing here.
+ }
+}
diff --git a/libjava/classpath/java/awt/dnd/DnDEventMulticaster.java b/libjava/classpath/java/awt/dnd/DnDEventMulticaster.java
new file mode 100644
index 0000000..d9f5ec0
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DnDEventMulticaster.java
@@ -0,0 +1,74 @@
+/* DnDEventMulticaster.java -- helper class for listener chains in java.awt.dnd
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.AWTEventMulticaster;
+import java.util.EventListener;
+
+class DnDEventMulticaster extends AWTEventMulticaster
+{
+ protected DnDEventMulticaster (EventListener a, EventListener b)
+ {
+ super (a, b);
+ }
+
+ public static DragSourceListener add (DragSourceListener a,
+ DragSourceListener b)
+ {
+ return (DragSourceListener) addInternal (a, b);
+ }
+
+ public static DragSourceMotionListener add (DragSourceMotionListener a,
+ DragSourceMotionListener b)
+ {
+ return (DragSourceMotionListener) addInternal (a, b);
+ }
+
+ public static DragSourceListener remove (DragSourceListener a,
+ DragSourceListener b)
+ {
+ return (DragSourceListener) removeInternal (a, b);
+ }
+
+ public static DragSourceMotionListener remove (DragSourceMotionListener a,
+ DragSourceMotionListener b)
+ {
+ return (DragSourceMotionListener) removeInternal (a, b);
+ }
+}
diff --git a/libjava/classpath/java/awt/dnd/DragGestureEvent.java b/libjava/classpath/java/awt/dnd/DragGestureEvent.java
new file mode 100644
index 0000000..9f2bc7c
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragGestureEvent.java
@@ -0,0 +1,156 @@
+/* DragGestureEvent.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.datatransfer.Transferable;
+import java.awt.event.InputEvent;
+import java.util.EventObject;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * STUBBED
+ * @see DragGestureRecognizer
+ * @see DragGestureListener
+ * @see DragSource
+ * @since 1.2
+ */
+public class DragGestureEvent extends EventObject
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 9080172649166731306L;
+
+ private DragSource dragSource;
+ private Component component;
+ private final Point origin;
+ private final int action;
+
+ public DragGestureEvent(DragGestureRecognizer dgr, int action, Point origin,
+ List events)
+ {
+ super(dgr);
+ if (origin == null || events == null)
+ throw new IllegalArgumentException();
+ this.origin = origin;
+ this.action = action;
+ }
+
+ public DragGestureRecognizer getSourceAsDragGestureRecognizer()
+ {
+ return (DragGestureRecognizer) source;
+ }
+ public Component getComponent()
+ {
+ return null;
+ }
+ public DragSource getDragSource()
+ {
+ return null;
+ }
+ public Point getDragOrigin()
+ {
+ return origin;
+ }
+ public Iterator iterator()
+ {
+ return null;
+ }
+ public Object[] toArray()
+ {
+ return null;
+ }
+ public Object[] toArray(Object[] array)
+ {
+ return array;
+ }
+ public int getDragAction()
+ {
+ return 0;
+ }
+ public InputEvent getTriggerEvent()
+ {
+ return null;
+ }
+
+ /**
+ * Starts the drag given the initial Cursor to display, the Transferable
+ * object, and the DragSourceListener to use.
+ *
+ * @exception InvalidDnDOperationException If the Drag and Drop system is
+ * unable to initiate a drag operation, or if the user attempts to start
+ * a drag while an existing drag operation is still executing.
+ */
+ public void startDrag(Cursor dragCursor, Transferable trans)
+ {
+ startDrag(dragCursor, null, null, trans, null);
+ }
+
+ /**
+ * Starts the drag given the initial Cursor to display, the Transferable
+ * object, and the DragSourceListener to use.
+ *
+ * @exception InvalidDnDOperationException If the Drag and Drop system is
+ * unable to initiate a drag operation, or if the user attempts to start
+ * a drag while an existing drag operation is still executing.
+ */
+ public void startDrag(Cursor dragCursor, Transferable trans,
+ DragSourceListener l)
+ {
+ startDrag(dragCursor, null, null, trans, l);
+ }
+
+ /**
+ * Starts the drag given the initial Cursor to display, the Transferable
+ * object, and the DragSourceListener to use.
+ *
+ * @exception InvalidDnDOperationException If the Drag and Drop system is
+ * unable to initiate a drag operation, or if the user attempts to start
+ * a drag while an existing drag operation is still executing.
+ */
+ public void startDrag(Cursor dragCursor, Image dragImage, Point imageOffset,
+ Transferable trans, DragSourceListener l)
+ {
+ }
+} // class DragGestureEvent
diff --git a/libjava/classpath/java/awt/dnd/DragGestureListener.java b/libjava/classpath/java/awt/dnd/DragGestureListener.java
new file mode 100644
index 0000000..e8befe8
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragGestureListener.java
@@ -0,0 +1,63 @@
+/* DragGestureListener.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.util.EventListener;
+
+/**
+ * This is a listener for starting a drag-and-drop gesture. Upon receiving
+ * notification, the implementor then starts the drag operation.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see DragGestureRecognizer
+ * @see DragGestureEvent
+ * @see DragSource
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface DragGestureListener extends EventListener
+{
+ /**
+ * Called when the native platform notifies the virtual machine that a
+ * drag-and-drop has been initiated.
+ *
+ * @param e the event
+ */
+ void dragGestureRecognized(DragGestureEvent e);
+} // interface DragGestureListener
diff --git a/libjava/classpath/java/awt/dnd/DragGestureRecognizer.java b/libjava/classpath/java/awt/dnd/DragGestureRecognizer.java
new file mode 100644
index 0000000..07b822e
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragGestureRecognizer.java
@@ -0,0 +1,179 @@
+/* DragGestureRecognizer.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.event.InputEvent;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.TooManyListenersException;
+
+/**
+ * STUBBED
+ * @since 1.2
+ */
+public abstract class DragGestureRecognizer implements Serializable
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 8996673345831063337L;
+
+ protected DragSource dragSource;
+ protected Component component;
+ protected transient DragGestureListener dragGestureListener;
+ protected int sourceActions;
+ protected ArrayList events = new ArrayList();
+
+ protected DragGestureRecognizer(DragSource ds, Component c, int sa,
+ DragGestureListener dgl)
+ {
+ if (ds == null)
+ throw new IllegalArgumentException();
+ dragSource = ds;
+ component = c;
+ sourceActions = sa;
+ dragGestureListener = dgl;
+ }
+
+ protected DragGestureRecognizer(DragSource ds, Component c, int sa)
+ {
+ this(ds, c, sa, null);
+ }
+
+ protected DragGestureRecognizer(DragSource ds, Component c)
+ {
+ this(ds, c, 0, null);
+ }
+
+ protected DragGestureRecognizer(DragSource ds)
+ {
+ this(ds, null, 0, null);
+ }
+
+ protected abstract void registerListeners();
+
+ protected abstract void unregisterListeners();
+
+ public DragSource getDragSource()
+ {
+ return dragSource;
+ }
+
+ public Component getComponent()
+ {
+ return component;
+ }
+
+ public void setComponent(Component c)
+ {
+ component = c;
+ }
+
+ public int getSourceActions()
+ {
+ return sourceActions;
+ }
+
+ public void setSourceActions(int sa)
+ {
+ sourceActions = sa;
+ }
+
+ public InputEvent getTriggerEvent()
+ {
+ return events.size() > 0 ? (InputEvent) events.get(0) : null;
+ }
+
+ public void resetRecognizer()
+ {
+ throw new Error("not implemented");
+ }
+
+ /**
+ * Register a new DragGestureListener.
+ *
+ * @exception TooManyListenersException If a DragGestureListener has already
+ * been added.
+ */
+ public void addDragGestureListener(DragGestureListener dgl)
+ throws TooManyListenersException
+ {
+ if (dragGestureListener != null)
+ throw new TooManyListenersException();
+ dragGestureListener = dgl;
+ }
+
+ public void removeDragGestureListener(DragGestureListener dgl)
+ {
+ if (dragGestureListener != dgl)
+ throw new IllegalArgumentException();
+ dragGestureListener = null;
+ }
+
+ protected void fireDragGestureRecognized(int dragAction, Point p)
+ {
+ throw new Error("not implemented");
+ }
+
+ protected void appendEvent(InputEvent e)
+ {
+ if (e == null)
+ return;
+ events.add(e);
+ }
+
+ private void readObject(ObjectInputStream s)
+ throws ClassNotFoundException, IOException
+ {
+ s.defaultReadObject();
+ dragGestureListener = (DragGestureListener) s.readObject();
+ }
+
+ private void writeObject(ObjectOutputStream s) throws IOException
+ {
+ s.defaultWriteObject();
+ s.writeObject(dragGestureListener instanceof Serializable
+ ? dragGestureListener : null);
+ }
+} // class DragGestureRecognizer
diff --git a/libjava/classpath/java/awt/dnd/DragSource.java b/libjava/classpath/java/awt/dnd/DragSource.java
new file mode 100644
index 0000000..13ffc96
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragSource.java
@@ -0,0 +1,257 @@
+/* DragSource.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.datatransfer.FlavorMap;
+import java.awt.datatransfer.SystemFlavorMap;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.peer.DragSourceContextPeer;
+import java.io.Serializable;
+import java.util.EventListener;
+
+/**
+ * @since 1.2
+ */
+public class DragSource implements Serializable
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 6236096958971414066L;
+
+ public static final Cursor DefaultCopyDrop = null;
+ public static final Cursor DefaultMoveDrop = null;
+ public static final Cursor DefaultLinkDrop = null;
+ public static final Cursor DefaultCopyNoDrop = null;
+ public static final Cursor DefaultMoveNoDrop = null;
+ public static final Cursor DefaultLinkNoDrop = null;
+
+ private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap ();
+
+ private transient DragSourceListener dragSourceListener;
+ private transient DragSourceMotionListener dragSourceMotionListener;
+
+ /**
+ * Initializes the drag source.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public DragSource()
+ {
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+ }
+
+ /**
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public static DragSource getDefaultDragSource()
+ {
+ return null;
+ }
+
+ public static boolean isDragImageSupported()
+ {
+ return false;
+ }
+
+ /**
+ * Start a drag, given the DragGestureEvent that initiated the drag.
+ *
+ * @exception InvalidDnDOperationException If the Drag and Drop system is
+ * unable to initiate a drag operation, or if the user attempts to start
+ * a drag while an existing drag operation is still executing.
+ */
+ public void startDrag(DragGestureEvent trigger, Cursor dragCursor,
+ Image dragImage, Point imageOffset,
+ Transferable trans, DragSourceListener dsl,
+ FlavorMap map)
+ {
+ }
+
+ /**
+ * Start a drag, given the DragGestureEvent that initiated the drag.
+ *
+ * @exception InvalidDnDOperationException If the Drag and Drop system is
+ * unable to initiate a drag operation, or if the user attempts to start
+ * a drag while an existing drag operation is still executing.
+ */
+ public void startDrag(DragGestureEvent trigger, Cursor dragCursor,
+ Transferable trans, DragSourceListener dsl,
+ FlavorMap map)
+ {
+ startDrag(trigger, dragCursor, null, null, trans, dsl, map);
+ }
+
+ /**
+ * Start a drag, given the DragGestureEvent that initiated the drag.
+ *
+ * @exception InvalidDnDOperationException If the Drag and Drop system is
+ * unable to initiate a drag operation, or if the user attempts to start
+ * a drag while an existing drag operation is still executing.
+ */
+ public void startDrag(DragGestureEvent trigger, Cursor dragCursor,
+ Image dragImage, Point imageOffset,
+ Transferable trans, DragSourceListener dsl)
+ {
+ startDrag(trigger, dragCursor, dragImage, imageOffset, trans, dsl, null);
+ }
+
+ /**
+ * Start a drag, given the DragGestureEvent that initiated the drag.
+ *
+ * @exception InvalidDnDOperationException If the Drag and Drop system is
+ * unable to initiate a drag operation, or if the user attempts to start
+ * a drag while an existing drag operation is still executing.
+ */
+ public void startDrag(DragGestureEvent trigger, Cursor dragCursor,
+ Transferable trans, DragSourceListener dsl)
+ {
+ startDrag(trigger, dragCursor, null, null, trans, dsl, null);
+ }
+
+ /**
+ * Creates the DragSourceContext to handle this drag.
+ *
+ * @exception IllegalArgumentException FIXME
+ * @exception NullPointerException If dscp, dgl, dragImage or t is null.
+ */
+ protected DragSourceContext
+ createDragSourceContext(DragSourceContextPeer peer, DragGestureEvent dge,
+ Cursor cursor, Image image, Point offset,
+ Transferable t, DragSourceListener dsl)
+ {
+ return null;
+ }
+
+ public FlavorMap getFlavorMap()
+ {
+ return flavorMap;
+ }
+
+ public DragGestureRecognizer
+ createDragGestureRecognizer(Class recognizer, Component c, int actions,
+ DragGestureListener dgl)
+ {
+ return Toolkit.getDefaultToolkit ()
+ .createDragGestureRecognizer (recognizer, this, c, actions,
+ dgl);
+ }
+
+ public DragGestureRecognizer
+ createDefaultDragGestureRecognizer(Component c, int actions,
+ DragGestureListener dgl)
+ {
+ return createDragGestureRecognizer (MouseDragGestureRecognizer.class, c,
+ actions, dgl);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void addDragSourceListener(DragSourceListener l)
+ {
+ DnDEventMulticaster.add (dragSourceListener, l);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void removeDragSourceListener(DragSourceListener l)
+ {
+ DnDEventMulticaster.remove (dragSourceListener, l);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public DragSourceListener[] getDragSourceListeners()
+ {
+ return (DragSourceListener[]) getListeners (DragSourceListener.class);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void addDragSourceMotionListener(DragSourceMotionListener l)
+ {
+ DnDEventMulticaster.add (dragSourceMotionListener, l);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public void removeDragSourceMotionListener(DragSourceMotionListener l)
+ {
+ DnDEventMulticaster.remove (dragSourceMotionListener, l);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public DragSourceMotionListener[] getDragSourceMotionListeners ()
+ {
+ return (DragSourceMotionListener[]) getListeners
+ (DragSourceMotionListener.class);
+ }
+
+ /**
+ * @since 1.4
+ */
+ public EventListener[] getListeners (Class listenerType)
+ {
+ if (listenerType == DragSourceListener.class)
+ return DnDEventMulticaster.getListeners (dragSourceListener,
+ listenerType);
+
+ if (listenerType == DragSourceMotionListener.class)
+ return DnDEventMulticaster.getListeners (dragSourceMotionListener,
+ listenerType);
+
+ // Return an empty EventListener array.
+ return new EventListener [0];
+ }
+} // class DragSource
diff --git a/libjava/classpath/java/awt/dnd/DragSourceAdapter.java b/libjava/classpath/java/awt/dnd/DragSourceAdapter.java
new file mode 100644
index 0000000..90d9a69
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragSourceAdapter.java
@@ -0,0 +1,126 @@
+/* DragSourceAdapter.java -- drag-and-drop listener adapter
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+/**
+ * This class implements <code>DragSourceListener</code> and
+ * <code>DragSourceMotionListener</code>, and implements all methods
+ * with empty bodies. This allows a listener interested in implementing only
+ * a subset of these interfaces to extend this class and override only the
+ * desired methods.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see DragSourceEvent
+ * @see DragSourceListener
+ * @see DragSourceMotionListener
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public abstract class DragSourceAdapter
+ implements DragSourceListener, DragSourceMotionListener
+{
+ /**
+ * Default constructor.
+ */
+ public DragSourceAdapter()
+ {
+ }
+
+ /**
+ * Called when the cursor hotspot enters a drop site which will accept the
+ * drag.
+ *
+ * @param e the event
+ */
+ public void dragEnter(DragSourceDragEvent e)
+ {
+ }
+
+ /**
+ * Called when the cursor hotspot moves inside of a drop site which will
+ * accept the drag.
+ *
+ * @param e the event
+ */
+ public void dragOver(DragSourceDragEvent e)
+ {
+ }
+
+ /**
+ * Called whenever the mouse is moved during a drag-and-drop operation.
+ *
+ * @param e the event
+ */
+ public void dragMouseMoved(DragSourceDragEvent e)
+ {
+ }
+
+ /**
+ * Called when the user modifies the drop gesture. This is often the case
+ * when additional mouse or key events are received during the drag.
+ *
+ * @param e the event
+ */
+ public void dropActionChanged(DragSourceDragEvent e)
+ {
+ }
+
+ /**
+ * Called when the cursor hotspot moves outside of a drop site which will
+ * accept the drag. This could also happen if the drop site is no longer
+ * active, or no longer accepts the drag.
+ *
+ * @param e the event
+ */
+ public void dragExit(DragSourceEvent e)
+ {
+ }
+
+ /**
+ * Called when the drag and drop operation is complete. After this event,
+ * <code>getDropSuccess</code> of the event is valid, and
+ * <code>getDropAction</code> holds the action requested by the drop site.
+ * Furthermore, the <code>DragSourceContext</code> is invalidated.
+ *
+ * @param e the event
+ */
+ public void dragDropEnd(DragSourceDropEvent e)
+ {
+ }
+} // class DragSourceAdapter
diff --git a/libjava/classpath/java/awt/dnd/DragSourceContext.java b/libjava/classpath/java/awt/dnd/DragSourceContext.java
new file mode 100644
index 0000000..2cf0d6d
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragSourceContext.java
@@ -0,0 +1,200 @@
+/* DragSourceContext.java --
+ Copyright (C) 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.peer.DragSourceContextPeer;
+import java.io.Serializable;
+import java.util.TooManyListenersException;
+
+/**
+ * @since 1.2
+ */
+public class DragSourceContext
+ implements DragSourceListener, DragSourceMotionListener, Serializable
+{
+ /**
+ * Compatible with JDK 1.2+
+ */
+ static final long serialVersionUID = -115407898692194719L;
+
+ protected static final int DEFAULT = 0;
+ protected static final int ENTER = 1;
+ protected static final int OVER = 2;
+ protected static final int CHANGED = 3;
+
+ private DragSourceContextPeer peer;
+ private Cursor cursor;
+ private Transferable transferable;
+ private DragGestureEvent trigger;
+ private DragSourceListener dragSourceListener;
+ private boolean useCustomCursor; // FIXME: currently unused but needed for serialization.
+ private int sourceActions; // FIXME: currently unused but needed for serialization.
+ private Image image;
+ private Point offset;
+
+ /**
+ * Initializes a drag source context.
+ *
+ * @exception IllegalArgumentException If Component or DragSource of trigger
+ * are null, the drag action for the trigger event is DnDConstants.ACTION_NONE
+ * or if the source actions for the DragGestureRecognizer associated with the
+ * trigger event are equal to DnDConstants.ACTION_NONE.
+ * @exception NullPointerException If peer or trigger is null.
+ */
+ public DragSourceContext (DragSourceContextPeer peer,
+ DragGestureEvent trigger, Cursor cursor,
+ Image image, Point offset, Transferable trans,
+ DragSourceListener dsl)
+ {
+ if (peer == null
+ || trigger == null)
+ throw new NullPointerException ();
+
+ if (trigger.getComponent () == null
+ || trigger.getDragSource () == null
+ || trigger.getDragAction () == DnDConstants.ACTION_NONE
+ || trigger.getSourceAsDragGestureRecognizer ()
+ .getSourceActions () == DnDConstants.ACTION_NONE)
+ throw new IllegalArgumentException ();
+
+ this.peer = peer;
+ this.trigger = trigger;
+ this.cursor = cursor;
+ this.image = image;
+ this.offset = offset;
+ this.transferable = trans;
+ this.dragSourceListener = dsl;
+
+ throw new Error ("not implemented");
+ }
+
+ public DragSource getDragSource()
+ {
+ return trigger.getDragSource ();
+ }
+
+ public Component getComponent()
+ {
+ return trigger.getComponent ();
+ }
+
+ public DragGestureEvent getTrigger()
+ {
+ return trigger;
+ }
+
+ public int getSourceActions()
+ {
+ return trigger.getSourceAsDragGestureRecognizer ().getSourceActions ();
+ }
+
+ public void setCursor (Cursor cursor)
+ {
+ this.cursor = cursor;
+ // FIXME: Check if we need to do more here
+ }
+
+ public Cursor getCursor()
+ {
+ return cursor;
+ }
+
+ /**
+ * Adds a <code>DragSourceListener</code>.
+ *
+ * @exception TooManyListenersException If a <code>DragSourceListener</code>
+ * has already been added.
+ */
+ public void addDragSourceListener (DragSourceListener dsl)
+ throws TooManyListenersException
+ {
+ if (dragSourceListener != null)
+ throw new TooManyListenersException ();
+
+ dragSourceListener = dsl;
+ }
+
+ public void removeDragSourceListener (DragSourceListener dsl)
+ {
+ if (dragSourceListener == dsl)
+ dragSourceListener = null;
+ }
+
+ public void transferablesFlavorsChanged()
+ {
+ }
+
+ public void dragEnter(DragSourceDragEvent e)
+ {
+ }
+
+ public void dragOver(DragSourceDragEvent e)
+ {
+ }
+
+ public void dragExit(DragSourceEvent e)
+ {
+ }
+
+ public void dropActionChanged(DragSourceDragEvent e)
+ {
+ }
+
+ public void dragDropEnd(DragSourceDropEvent e)
+ {
+ }
+
+ public void dragMouseMoved(DragSourceDragEvent e)
+ {
+ }
+
+ public Transferable getTransferable()
+ {
+ return transferable;
+ }
+
+ protected void updateCurrentCursor(int dropOp, int targetAct, int status)
+ {
+ }
+} // class DragSourceContext
diff --git a/libjava/classpath/java/awt/dnd/DragSourceDragEvent.java b/libjava/classpath/java/awt/dnd/DragSourceDragEvent.java
new file mode 100644
index 0000000..511700b
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragSourceDragEvent.java
@@ -0,0 +1,102 @@
+/* DragSourceDragEvent.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import gnu.java.awt.EventModifier;
+
+/**
+ * @author Michael Koch
+ * @since 1.2
+ */
+public class DragSourceDragEvent extends DragSourceEvent
+{
+ /**
+ * Compatible with JDK 1.2+
+ */
+ private static final long serialVersionUID = 481346297933902471L;
+
+ private final int dropAction;
+ private final int targetActions;
+ private final int gestureModifiers;
+
+ public DragSourceDragEvent(DragSourceContext context, int dropAction,
+ int actions, int modifiers)
+ {
+ super(context);
+ this.dropAction = dropAction;
+ targetActions = actions;
+ gestureModifiers = EventModifier.extend(modifiers);
+ }
+
+ public DragSourceDragEvent(DragSourceContext context, int dropAction,
+ int actions, int modifiers, int x, int y)
+ {
+ super(context, x, y);
+ this.dropAction = dropAction;
+ targetActions = actions;
+ gestureModifiers = EventModifier.extend(modifiers);
+ }
+
+ public int getTargetActions()
+ {
+ return targetActions;
+ }
+
+ public int getGestureModifiers()
+ {
+ return EventModifier.revert(gestureModifiers);
+ }
+
+ public int getGestureModifiersEx()
+ {
+ return gestureModifiers;
+ }
+
+ public int getUserAction()
+ {
+ return dropAction;
+ }
+
+ public int getDropAction()
+ {
+ return (dropAction
+ & targetActions
+ & ((DragSourceContext) source).getSourceActions());
+ }
+} // class DragSourceDragEvent
diff --git a/libjava/classpath/java/awt/dnd/DragSourceDropEvent.java b/libjava/classpath/java/awt/dnd/DragSourceDropEvent.java
new file mode 100644
index 0000000..7621262
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragSourceDropEvent.java
@@ -0,0 +1,89 @@
+/* DragSourceDragEvent.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.dnd;
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.2
+ *
+ * Written using JDK 1.4.1 Online API
+ * Status: JDK 1.4 complete
+ */
+public class DragSourceDropEvent extends DragSourceEvent
+{
+ /**
+ * Compatible with JDK 1.2+
+ */
+ private static final long serialVersionUID = -5571321229470821891L;
+
+ private final int dropAction;
+ private final boolean dropSuccess;
+
+ public DragSourceDropEvent (DragSourceContext context)
+ {
+ super (context);
+ this.dropAction = 0;
+ this.dropSuccess = false;
+ }
+
+ public DragSourceDropEvent (DragSourceContext context, int dropAction,
+ boolean dropSuccess)
+ {
+ super (context);
+ this.dropAction = dropAction;
+ this.dropSuccess = dropSuccess;
+ }
+
+ public DragSourceDropEvent (DragSourceContext context, int dropAction,
+ boolean dropSuccess, int x, int y)
+ {
+ super (context, x, y);
+ this.dropAction = dropAction;
+ this.dropSuccess = dropSuccess;
+ }
+
+ public int getDropAction()
+ {
+ return dropAction & ((DragSourceContext) source).getSourceActions();
+ }
+
+ public boolean getDropSuccess()
+ {
+ return dropSuccess;
+ }
+} // class DragSourceDropEvent
diff --git a/libjava/classpath/java/awt/dnd/DragSourceEvent.java b/libjava/classpath/java/awt/dnd/DragSourceEvent.java
new file mode 100644
index 0000000..c5cd42a
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragSourceEvent.java
@@ -0,0 +1,93 @@
+/* DragSourceEvent.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.Point;
+import java.util.EventObject;
+
+/**
+ * @since 1.2
+ */
+public class DragSourceEvent extends EventObject
+{
+ /**
+ * Compatible with JDK 1.2+
+ */
+ private static final long serialVersionUID = -763287114604032641L;
+
+ private final boolean locationSpecified;
+ private final int x;
+ private final int y;
+
+ public DragSourceEvent(DragSourceContext context)
+ {
+ super(context);
+ locationSpecified = false;
+ x = 0;
+ y = 0;
+ }
+
+ public DragSourceEvent(DragSourceContext context, int x, int y)
+ {
+ super(context);
+ locationSpecified = true;
+ this.x = x;
+ this.y = y;
+ }
+
+ public DragSourceContext getDragSourceContext()
+ {
+ return (DragSourceContext) source;
+ }
+
+ public Point getLocation()
+ {
+ return locationSpecified ? new Point(x, y) : null;
+ }
+
+ public int getX()
+ {
+ return x;
+ }
+
+ public int getY()
+ {
+ return y;
+ }
+} // class DragSourceEvent
diff --git a/libjava/classpath/java/awt/dnd/DragSourceListener.java b/libjava/classpath/java/awt/dnd/DragSourceListener.java
new file mode 100644
index 0000000..aac6e94
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragSourceListener.java
@@ -0,0 +1,97 @@
+/* DragSourceListener.java -- listen to events during the drag
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.util.EventListener;
+
+/**
+ * This class allows an object to listen for drag and drop events. It can
+ * be used to provide appropriate feedback for "drag over" actions. You can
+ * also use a <code>DragSourceAdapter</code> to filter the events you are
+ * interested in.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface DragSourceListener extends EventListener
+{
+ /**
+ * Called when the cursor hotspot enters a drop site which will accept the
+ * drag.
+ *
+ * @param e the drag source drag event
+ */
+ void dragEnter(DragSourceDragEvent e);
+
+ /**
+ * Called when the cursor hotspot moves inside of a drop site which will
+ * accept the drag.
+ *
+ * @param e the drag source drag event
+ */
+ void dragOver(DragSourceDragEvent e);
+
+ /**
+ * Called when the user modifies the drop gesture. This is often the case
+ * when additional mouse or key events are received during the drag.
+ *
+ * @param e the drag source drag event
+ */
+ void dropActionChanged(DragSourceDragEvent e);
+
+ /**
+ * Called when the cursor hotspot moves outside of a drop site which will
+ * accept the drag. This could also happen if the drop site is no longer
+ * active, or no longer accepts the drag.
+ *
+ * @param e the drag source drag event
+ */
+ void dragExit(DragSourceEvent e);
+
+ /**
+ * Called when the drag and drop operation is complete. After this event,
+ * <code>getDropSuccess</code> of the event is valid, and
+ * <code>getDropAction</code> holds the action requested by the drop site.
+ * Furthermore, the <code>DragSourceContext</code> is invalidated.
+ *
+ * @param e the drag source drag event
+ */
+ void dragDropEnd(DragSourceDropEvent e);
+} // interface DragSourceListener
diff --git a/libjava/classpath/java/awt/dnd/DragSourceMotionListener.java b/libjava/classpath/java/awt/dnd/DragSourceMotionListener.java
new file mode 100644
index 0000000..5d04c22
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DragSourceMotionListener.java
@@ -0,0 +1,64 @@
+/* DragSourceMotionListener.java -- tracks motion in the drag source
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.util.EventListener;
+
+/**
+ * This is a listener for mouse motion in the drag source before the drop
+ * event occurs. You can also use a <code>DragSourceAdapter</code> to filter
+ * the events you are interested in.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see DragSourceDragEvent
+ * @see DragSource
+ * @see DragSourceListener
+ * @see DragSourceAdapter
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public interface DragSourceMotionListener extends EventListener
+{
+ /**
+ * Called whenever the mouse is moved during a drag-and-drop operation.
+ *
+ * @param e the event
+ */
+ void dragMouseMoved(DragSourceDragEvent e);
+} // interface DragSourceMotionListener
diff --git a/libjava/classpath/java/awt/dnd/DropTarget.java b/libjava/classpath/java/awt/dnd/DropTarget.java
new file mode 100644
index 0000000..9fd7ef8
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DropTarget.java
@@ -0,0 +1,293 @@
+/* DropTarget.java --
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.Component;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.Point;
+import java.awt.datatransfer.FlavorMap;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.Serializable;
+import java.util.EventListener;
+import java.util.TooManyListenersException;
+
+/**
+ * @author Michael Koch
+ * @since 1.2
+ */
+public class DropTarget
+ implements DropTargetListener, EventListener, Serializable
+{
+ /**
+ * Compatible with JDK 1.2+
+ */
+ private static final long serialVersionUID = -6283860791671019047L;
+
+ /** @specnote According to the online documentation, this is
+ * protected, but in reality it is public. */
+ public static class DropTargetAutoScroller
+ implements ActionListener
+ {
+ private Component component;
+ private Point point;
+
+ protected DropTargetAutoScroller (Component c, Point p)
+ {
+ component = c;
+ point = p;
+ }
+
+ protected void updateLocation (Point newLocn)
+ {
+ point = newLocn;
+ }
+
+ protected void stop ()
+ {
+ }
+
+ public void actionPerformed (ActionEvent e)
+ {
+ }
+ }
+
+ private Component component;
+ private FlavorMap flavorMap;
+ private int actions;
+ private DropTargetContext dropTargetContext;
+ private DropTargetListener dropTargetListener;
+ private boolean active = true;
+
+ /**
+ * Creates a <code>DropTarget</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+ public DropTarget ()
+ {
+ this (null, 0, null, true, null);
+ }
+
+ /**
+ * Creates a <code>DropTarget</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+ public DropTarget (Component c, DropTargetListener dtl)
+ {
+ this (c, 0, dtl, true, null);
+ }
+
+ /**
+ * Creates a <code>DropTarget</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+ public DropTarget (Component c, int i, DropTargetListener dtl)
+ {
+ this (c, i, dtl, true, null);
+ }
+
+ /**
+ * Creates a <code>DropTarget</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+ public DropTarget (Component c, int i, DropTargetListener dtl, boolean b)
+ {
+ this (c, i, dtl, b, null);
+ }
+
+ /**
+ * Creates a <code>DropTarget</code> object.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless()
+ * returns true.
+ */
+ public DropTarget (Component c, int i, DropTargetListener dtl, boolean b,
+ FlavorMap fm)
+ {
+ if (GraphicsEnvironment.isHeadless ())
+ throw new HeadlessException ();
+
+ component = c;
+ actions = i;
+ dropTargetListener = dtl;
+ flavorMap = fm;
+
+ setActive (b);
+ }
+
+ /**
+ * Sets the component associated with this drop target object.
+ */
+ public void setComponent (Component c)
+ {
+ component = c;
+ }
+
+ /**
+ * Returns the component associated with this drop target object.
+ */
+ public Component getComponent ()
+ {
+ return component;
+ }
+
+ /**
+ * Sets the default actions.
+ */
+ public void setDefaultActions (int ops)
+ {
+ actions = ops;
+ }
+
+ /**
+ * Returns the default actions.
+ */
+ public int getDefaultActions ()
+ {
+ return actions;
+ }
+
+ public void setActive (boolean active)
+ {
+ this.active = active;
+ }
+
+ public boolean isActive()
+ {
+ return active;
+ }
+
+ /**
+ * Adds a new <code>DropTargetListener</code>.
+ *
+ * @exception TooManyListenersException Sun's JDK does not, despite
+ * documentation, throw this exception here when you install an additional
+ * <code>DropTargetListener</code>. So to be compatible, we do the same
+ * thing.
+ */
+ public void addDropTargetListener (DropTargetListener dtl)
+ throws TooManyListenersException
+ {
+ dropTargetListener = dtl;
+ }
+
+ public void removeDropTargetListener(DropTargetListener dtl)
+ {
+ // FIXME: Do we need to do something with dtl ?
+ dropTargetListener = null;
+ }
+
+ public void dragEnter(DropTargetDragEvent dtde)
+ {
+ }
+
+ public void dragOver(DropTargetDragEvent dtde)
+ {
+ }
+
+ public void dropActionChanged(DropTargetDragEvent dtde)
+ {
+ }
+
+ public void dragExit(DropTargetEvent dte)
+ {
+ }
+
+ public void drop(DropTargetDropEvent dtde)
+ {
+ }
+
+ public FlavorMap getFlavorMap()
+ {
+ return flavorMap;
+ }
+
+ public void setFlavorMap(FlavorMap fm)
+ {
+ flavorMap = fm;
+ }
+
+ public void addNotify(java.awt.peer.ComponentPeer peer)
+ {
+ }
+
+ public void removeNotify(java.awt.peer.ComponentPeer peer)
+ {
+ }
+
+ public DropTargetContext getDropTargetContext()
+ {
+ if (dropTargetContext == null)
+ dropTargetContext = createDropTargetContext ();
+
+ return dropTargetContext;
+ }
+
+ protected DropTargetContext createDropTargetContext()
+ {
+ return new DropTargetContext (this);
+ }
+
+ protected DropTarget.DropTargetAutoScroller createDropTargetAutoScroller
+ (Component c, Point p)
+ {
+ return new DropTarget.DropTargetAutoScroller (c, p);
+ }
+
+ protected void initializeAutoscrolling(Point p)
+ {
+ }
+
+ protected void updateAutoscroll(Point dragCursorLocn)
+ {
+ }
+
+ protected void clearAutoscroll()
+ {
+ }
+} // class DropTarget
diff --git a/libjava/classpath/java/awt/dnd/DropTargetAdapter.java b/libjava/classpath/java/awt/dnd/DropTargetAdapter.java
new file mode 100644
index 0000000..13c6b9f
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DropTargetAdapter.java
@@ -0,0 +1,100 @@
+/* DragSourceAdapter.java -- drag-and-drop listener adapter
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.dnd;
+
+/**
+ * This class implements <code>DropTargetListener</code>, and implements all methods
+ * with empty bodies. This allows a listener interested in implementing only
+ * a subset of these interfaces to extend this class and override only the
+ * desired methods.
+ *
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public abstract class DropTargetAdapter
+ implements DropTargetListener
+{
+ /**
+ * Default constructor.
+ */
+ public DropTargetAdapter()
+ {
+ }
+
+ /**
+ * Called when the cursor hotspot enters a drop site which will accept the
+ * drag.
+ *
+ * @param e the event
+ */
+ public void dragEnter (DropTargetDragEvent e)
+ {
+ }
+
+ /**
+ * Called when the cursor hotspot moves inside of a drop site which will
+ * accept the drag.
+ *
+ * @param e the event
+ */
+ public void dragOver (DropTargetDragEvent e)
+ {
+ }
+
+ /**
+ * Called when the user modifies the drop gesture. This is often the case
+ * when additional mouse or key events are received during the drag.
+ *
+ * @param e the event
+ */
+ public void dropActionChanged (DropTargetDragEvent e)
+ {
+ }
+
+ /**
+ * Called when the cursor hotspot moves outside of a drop site which will
+ * accept the drag. This could also happen if the drop site is no longer
+ * active, or no longer accepts the drag.
+ *
+ * @param e the event
+ */
+ public void dragExit(DropTargetEvent e)
+ {
+ }
+} // class DropTargetAdapter
diff --git a/libjava/classpath/java/awt/dnd/DropTargetContext.java b/libjava/classpath/java/awt/dnd/DropTargetContext.java
new file mode 100644
index 0000000..d1fb66e
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DropTargetContext.java
@@ -0,0 +1,188 @@
+/* DropTargetContext.java --
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.dnd;
+
+import java.awt.Component;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.2
+ */
+public class DropTargetContext implements Serializable
+{
+ static final long serialVersionUID = -634158968993743371L;
+
+ /** @specnote According to the online documentation, this is
+ * protected, but in reality it is public. */
+ public class TransferableProxy implements Transferable
+ {
+ protected boolean isLocal;
+ protected Transferable transferable;
+
+ TransferableProxy (Transferable t, boolean local)
+ {
+ this.transferable = t;
+ this.isLocal = local;
+ }
+
+ public DataFlavor[] getTransferDataFlavors ()
+ {
+ return transferable.getTransferDataFlavors ();
+ }
+
+ public boolean isDataFlavorSupported (DataFlavor flavor)
+ {
+ return transferable.isDataFlavorSupported (flavor);
+ }
+
+ public Object getTransferData (DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException
+ {
+ return transferable.getTransferData (flavor);
+ }
+ }
+
+ private DropTarget dropTarget;
+ private int targetActions;
+ private java.awt.dnd.peer.DropTargetContextPeer dtcp;
+
+ // package private
+ DropTargetContext (DropTarget dropTarget)
+ {
+ this.dropTarget = dropTarget;
+ }
+
+ public DropTarget getDropTarget ()
+ {
+ return dropTarget;
+ }
+
+ public Component getComponent ()
+ {
+ return dropTarget.getComponent ();
+ }
+
+ public void addNotify (java.awt.dnd.peer.DropTargetContextPeer dtcp)
+ {
+ this.dtcp = dtcp;
+ }
+
+ public void removeNotify ()
+ {
+ this.dtcp = null;
+ }
+
+ protected void setTargetActions (int actions)
+ {
+ targetActions = actions;
+ }
+
+ protected int getTargetActions()
+ {
+ return targetActions;
+ }
+
+ /**
+ * Signals that the drop is completed.
+ *
+ * @exception InvalidDnDOperationException If a drop is not outstanding.
+ */
+ public void dropComplete (boolean success)
+ {
+ // FIXME: implement this
+ }
+
+ protected void acceptDrag (int dragOperation)
+ {
+ // FIXME: implement this
+ }
+
+ protected void rejectDrag ()
+ {
+ // FIXME: implement this
+ }
+
+ protected void acceptDrop (int dropOperation)
+ {
+ // FIXME: implement this
+ }
+
+ protected void rejectDrop ()
+ {
+ // FIXME: implement this
+ }
+
+ protected DataFlavor[] getCurrentDataFlavors ()
+ {
+ // FIXME: implement this
+ return null;
+ }
+
+ protected List getCurrentDataFlavorsAsList ()
+ {
+ return Arrays.asList (getCurrentDataFlavors ());
+ }
+
+ protected boolean isDataFlavorSupported (DataFlavor flavor)
+ {
+ return getCurrentDataFlavorsAsList ().contains (flavor);
+ }
+
+ /**
+ * Return the <code>Transferable</code> operandof this operation.
+ *
+ * @exception InvalidDnDOperationException If a drag is not outstanding.
+ */
+ protected Transferable getTransferable() throws InvalidDnDOperationException
+ {
+ // FIXME: implement this
+ return null;
+ }
+
+ protected Transferable createTransferableProxy(Transferable t, boolean local)
+ {
+ return new TransferableProxy (t, local);
+ }
+} // class DropTargetContext
diff --git a/libjava/classpath/java/awt/dnd/DropTargetDragEvent.java b/libjava/classpath/java/awt/dnd/DropTargetDragEvent.java
new file mode 100644
index 0000000..6cdc3a2
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DropTargetDragEvent.java
@@ -0,0 +1,140 @@
+/* DropTargetDragEvent.java --
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.awt.Point;
+import java.awt.datatransfer.DataFlavor;
+import java.util.List;
+
+/**
+ * @since 1.2
+ */
+public class DropTargetDragEvent extends DropTargetEvent
+{
+ /**
+ * Compatible with 1.2+
+ */
+ private static final long serialVersionUID = -8422265619058953682L;
+
+ private final int dropAction;
+ private final int srcActions;
+ private final Point location;
+
+ /**
+ * Initializes a <code>DropTargetDragEvent</code>.
+ *
+ * @exception IllegalArgumentException If dropAction is not one of DnDConstants,
+ * srcActions is not a bitwise mask of DnDConstants, or dtc is null.
+ * @exception NullPointerException If location is null.
+ */
+ public DropTargetDragEvent (DropTargetContext context, Point location,
+ int dropAction, int srcActions)
+ {
+ super (context);
+
+ if (location == null)
+ throw new NullPointerException ();
+
+ if (context == null)
+ throw new IllegalArgumentException ();
+
+ if (dropAction != DnDConstants.ACTION_NONE
+ && dropAction != DnDConstants.ACTION_COPY
+ && dropAction != DnDConstants.ACTION_MOVE
+ && dropAction != DnDConstants.ACTION_COPY_OR_MOVE
+ && dropAction != DnDConstants.ACTION_LINK
+ && dropAction != DnDConstants.ACTION_REFERENCE)
+ throw new IllegalArgumentException ();
+
+ int srcActionsMask = DnDConstants.ACTION_NONE
+ | DnDConstants.ACTION_COPY
+ | DnDConstants.ACTION_MOVE
+ | DnDConstants.ACTION_COPY_OR_MOVE
+ | DnDConstants.ACTION_LINK
+ | DnDConstants.ACTION_REFERENCE;
+
+ if (~(srcActions ^ srcActionsMask) != 0)
+ throw new IllegalArgumentException ();
+
+ this.dropAction = dropAction;
+ this.srcActions = srcActions;
+ this.location = location;
+ }
+
+ public void acceptDrag (int dragOperation)
+ {
+ context.acceptDrag (dragOperation);
+ }
+
+ public DataFlavor[] getCurrentDataFlavors ()
+ {
+ return context.getCurrentDataFlavors ();
+ }
+
+ public List getCurrentDataFlavorsAsList ()
+ {
+ return context.getCurrentDataFlavorsAsList ();
+ }
+
+ public int getDropAction()
+ {
+ return 0;
+ //return dropAction & ((DropTargetContext) source).getTargetActions();
+ }
+
+ public Point getLocation ()
+ {
+ return location;
+ }
+
+ public int getSourceActions ()
+ {
+ return srcActions;
+ }
+
+ public boolean isDataFlavorSupported (DataFlavor df)
+ {
+ return context.isDataFlavorSupported (df);
+ }
+
+ public void rejectDrag ()
+ {
+ context.rejectDrag ();
+ }
+} // class DropTargetDragEvent
diff --git a/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java b/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java
new file mode 100644
index 0000000..0c0777f
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java
@@ -0,0 +1,170 @@
+/* DropTargetDropEvent.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.dnd;
+
+import java.awt.Point;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.util.List;
+
+/**
+ * @since 1.2
+ */
+public class DropTargetDropEvent extends DropTargetEvent
+{
+ /**
+ * Compatible with JDK 1.2+
+ */
+ private static final long serialVersionUID = -1721911170440459322L;
+
+ private final int dropAction;
+ private final int actions;
+ private final Point location;
+ private final boolean isLocalTx;
+
+ /**
+ * Initializes a <code>DropTargetDropEvent</code>. By default this constructor
+ * assumes that the target is not int same JVM.
+ *
+ * @exception IllegalArgumentException If dropAction is not one of DnDConstants,
+ * actions is not a bitwise mask of DnDConstants, or dtc is null.
+ * @exception NullPointerException If location is null.
+ */
+ public DropTargetDropEvent (DropTargetContext dtc, Point location,
+ int dropAction, int actions)
+ {
+ this (dtc, location, dropAction, actions, false);
+ }
+
+ /**
+ * Initializes a <code>DropTargetDropEvent</code>.
+ *
+ * @exception IllegalArgumentException If dropAction is not one of DnDConstants,
+ * actions is not a bitwise mask of DnDConstants, or dtc is null.
+ * @exception NullPointerException If location is null.
+ */
+ public DropTargetDropEvent (DropTargetContext dtc, Point location,
+ int dropAction, int actions, boolean isLocalTx)
+ {
+ super (dtc);
+
+ if (location == null)
+ throw new NullPointerException ();
+
+ if (dtc == null)
+ throw new IllegalArgumentException ();
+
+ if (dropAction != DnDConstants.ACTION_NONE
+ && dropAction != DnDConstants.ACTION_COPY
+ && dropAction != DnDConstants.ACTION_MOVE
+ && dropAction != DnDConstants.ACTION_COPY_OR_MOVE
+ && dropAction != DnDConstants.ACTION_LINK
+ && dropAction != DnDConstants.ACTION_REFERENCE)
+ throw new IllegalArgumentException ();
+
+ int actionsMask = DnDConstants.ACTION_NONE
+ | DnDConstants.ACTION_COPY
+ | DnDConstants.ACTION_MOVE
+ | DnDConstants.ACTION_COPY_OR_MOVE
+ | DnDConstants.ACTION_LINK
+ | DnDConstants.ACTION_REFERENCE;
+
+ if (~(actions ^ actionsMask) != 0)
+ throw new IllegalArgumentException ();
+
+ this.dropAction = dropAction;
+ this.actions = actions;
+ this.location = location;
+ this.isLocalTx = isLocalTx;
+ }
+
+ public Point getLocation ()
+ {
+ return location;
+ }
+
+ public DataFlavor[] getCurrentDataFlavors ()
+ {
+ return context.getCurrentDataFlavors ();
+ }
+
+ public List getCurrentDataFlavorsAsList ()
+ {
+ return context.getCurrentDataFlavorsAsList ();
+ }
+
+ public boolean isDataFlavorSupported (DataFlavor flavor)
+ {
+ return context.isDataFlavorSupported (flavor);
+ }
+
+ public int getSourceActions ()
+ {
+ return actions;
+ }
+
+ public int getDropAction ()
+ {
+ return dropAction;
+ }
+
+ public Transferable getTransferable ()
+ {
+ return context.getTransferable ();
+ }
+
+ public void acceptDrop (int dropAction)
+ {
+ context.acceptDrop (dropAction);
+ }
+
+ public void rejectDrop ()
+ {
+ context.rejectDrop ();
+ }
+
+ public void dropComplete (boolean success)
+ {
+ // FIXME: implement this
+ }
+
+ public boolean isLocalTransfer()
+ {
+ return isLocalTx;
+ }
+} // class DropTargetDropEvent
diff --git a/libjava/classpath/java/awt/dnd/DropTargetEvent.java b/libjava/classpath/java/awt/dnd/DropTargetEvent.java
new file mode 100644
index 0000000..56a4d48
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DropTargetEvent.java
@@ -0,0 +1,56 @@
+/* DropTarget.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.dnd;
+
+import java.util.EventObject;
+
+public class DropTargetEvent extends EventObject
+{
+ protected DropTargetContext context;
+
+ public DropTargetEvent (DropTargetContext context)
+ {
+ super (context);
+ this.context = context;
+ }
+
+ public DropTargetContext getDropTargetContext ()
+ {
+ return context;
+ }
+}
diff --git a/libjava/classpath/java/awt/dnd/DropTargetListener.java b/libjava/classpath/java/awt/dnd/DropTargetListener.java
new file mode 100644
index 0000000..ceb839b
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/DropTargetListener.java
@@ -0,0 +1,89 @@
+/* DropTargetListener.java -- listen to events during the drop
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+import java.util.EventListener;
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface DropTargetListener extends EventListener
+{
+ /**
+ * Called when the cursor hotspot enters a drop site which will accept the
+ * drag.
+ *
+ * @param e the drag source drag event
+ */
+ void dragEnter (DropTargetDragEvent e);
+
+ /**
+ * Called when the cursor hotspot moves inside of a drop site which will
+ * accept the drag.
+ *
+ * @param e the drag source drag event
+ */
+ void dragOver (DropTargetDragEvent e);
+
+ /**
+ * Called when the user modifies the drop gesture. This is often the case
+ * when additional mouse or key events are received during the drag.
+ *
+ * @param e the drag source drag event
+ */
+ void dropActionChanged (DropTargetDragEvent e);
+
+ /**
+ * Called when the cursor hotspot moves outside of a drop site which will
+ * accept the drag. This could also happen if the drop site is no longer
+ * active, or no longer accepts the drag.
+ *
+ * @param e the drag source drag event
+ */
+ void dragExit (DropTargetEvent e);
+
+ /**
+ * Called when the drag operation has terminated with a drop.
+ *
+ * @param e the drag source drag event
+ */
+ void drop (DropTargetDropEvent e);
+} // interface DropTargetListener
diff --git a/libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java b/libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java
new file mode 100644
index 0000000..2fd9767
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java
@@ -0,0 +1,73 @@
+/* InvalidDnDOperationException.java -- thrown when drag-and-drop fails
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd;
+
+/**
+ * Thrown when a method in the java.awt.dnd package is unable to perform a
+ * requested operation, usually because the underlying DnD system is in the
+ * wrong state.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public class InvalidDnDOperationException extends IllegalStateException
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = -6062568741193956678L;
+
+ /**
+ * Create an exception without a message.
+ */
+ public InvalidDnDOperationException()
+ {
+ }
+
+ /**
+ * Create an exception with a message.
+ *
+ * @param s the message
+ */
+ public InvalidDnDOperationException(String s)
+ {
+ super(s);
+ }
+} // class InvalidDnDOperationException
diff --git a/libjava/classpath/java/awt/dnd/MouseDragGestureRecognizer.java b/libjava/classpath/java/awt/dnd/MouseDragGestureRecognizer.java
new file mode 100644
index 0000000..9a2a7bc
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/MouseDragGestureRecognizer.java
@@ -0,0 +1,131 @@
+/* MouseDragGestureRecognizer.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.dnd;
+
+import java.awt.Component;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ */
+public abstract class MouseDragGestureRecognizer
+ extends DragGestureRecognizer
+ implements MouseListener, MouseMotionListener
+{
+ /**
+ * Creates a <code>MouseDragGestureRecognizer</code> object.
+ */
+ protected MouseDragGestureRecognizer (DragSource ds, Component c, int act,
+ DragGestureListener dgl)
+ {
+ super (ds, c, act, dgl);
+ }
+
+ /**
+ * Creates a <code>MouseDragGestureRecognizer</code> object.
+ */
+ protected MouseDragGestureRecognizer (DragSource ds, Component c, int act)
+ {
+ super (ds, c, act);
+ }
+
+ /**
+ * Creates a <code>MouseDragGestureRecognizer</code> object.
+ */
+ protected MouseDragGestureRecognizer (DragSource ds, Component c)
+ {
+ super (ds, c);
+ }
+
+ /**
+ * Creates a <code>MouseDragGestureRecognizer</code> object.
+ */
+ protected MouseDragGestureRecognizer (DragSource ds)
+ {
+ super (ds);
+ }
+
+ protected void registerListeners ()
+ {
+ component.addMouseListener (this);
+ component.addMouseMotionListener (this);
+ }
+
+ protected void unregisterListeners ()
+ {
+ component.removeMouseListener (this);
+ component.removeMouseMotionListener (this);
+ }
+
+ public void mouseClicked (MouseEvent e)
+ {
+ // Do nothing in here by default.
+ }
+
+ public void mousePressed (MouseEvent e)
+ {
+ // Do nothing in here by default.
+ }
+
+ public void mouseReleased (MouseEvent e)
+ {
+ // Do nothing in here by default.
+ }
+
+ public void mouseEntered (MouseEvent e)
+ {
+ // Do nothing in here by default.
+ }
+
+ public void mouseExited (MouseEvent e)
+ {
+ // Do nothing in here by default.
+ }
+
+ public void mouseDragged (MouseEvent e)
+ {
+ // Do nothing in here by default.
+ }
+
+ public void mouseMoved (MouseEvent e)
+ {
+ // Do nothing in here by default.
+ }
+} // class MouseDragGestureRecognizer
diff --git a/libjava/classpath/java/awt/dnd/package.html b/libjava/classpath/java/awt/dnd/package.html
new file mode 100644
index 0000000..d1ae521
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.dnd package.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.dnd</title></head>
+
+<body>
+<p>Events and listeners for drag and drop sources and targets.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/dnd/peer/DragSourceContextPeer.java b/libjava/classpath/java/awt/dnd/peer/DragSourceContextPeer.java
new file mode 100644
index 0000000..8c134b6
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/peer/DragSourceContextPeer.java
@@ -0,0 +1,57 @@
+/* DragSourceContextPeer.java -- interface for drag-and-drop peers
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd.peer;
+
+import java.awt.Cursor;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.dnd.DragSourceContext;
+import java.awt.dnd.InvalidDnDOperationException;
+
+/**
+ * STUBBED
+ */
+public interface DragSourceContextPeer
+{
+ void startDrag(DragSourceContext context, Cursor c, Image i, Point p)
+ throws InvalidDnDOperationException;
+ Cursor getCursor();
+ void setCursor(Cursor c) throws InvalidDnDOperationException;
+ void transferablesFlavorsChanged();
+} // interface DragSourceContextPeer
diff --git a/libjava/classpath/java/awt/dnd/peer/DropTargetContextPeer.java b/libjava/classpath/java/awt/dnd/peer/DropTargetContextPeer.java
new file mode 100644
index 0000000..6eae29b
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/peer/DropTargetContextPeer.java
@@ -0,0 +1,68 @@
+/* DropTargetContextPeer.java -- interface for drag-and-drop peers
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.dnd.peer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.InvalidDnDOperationException;
+
+
+/**
+ * Used to control state of recipient protocol from the
+ * <code>DropTargetListener</code>. Occurs when a <code>Component</code>
+ * with an associated <code>DropTarget</code> and visible geometry is first
+ * intersected by a logical cursor.
+ *
+ * @author Michael Koch (konqueror@gmx.de)
+ */
+public interface DropTargetContextPeer
+{
+ void setTargetActions(int actions);
+ int getTargetActions();
+ DropTarget getDropTarget();
+ DataFlavor[] getTransferDataFlavors();
+ Transferable getTransferable() throws InvalidDnDOperationException;
+ boolean isTransferableJVMLocal();
+ void acceptDrag(int dragAction);
+ void rejectDrag();
+ void acceptDrop(int dropAction);
+ void rejectDrop();
+ void dropComplete(boolean success);
+}
diff --git a/libjava/classpath/java/awt/dnd/peer/DropTargetPeer.java b/libjava/classpath/java/awt/dnd/peer/DropTargetPeer.java
new file mode 100644
index 0000000..ec17cbe
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/peer/DropTargetPeer.java
@@ -0,0 +1,48 @@
+/* DropTargetPeer.java -- interface for drag-and-drop peers
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.dnd.peer;
+
+import java.awt.dnd.DropTarget;
+
+/**
+ */
+public interface DropTargetPeer
+{
+ void addDropTarget (DropTarget target);
+ void removeDropTarget (DropTarget target);
+} // interface DropTargetContextPeer
diff --git a/libjava/classpath/java/awt/dnd/peer/package.html b/libjava/classpath/java/awt/dnd/peer/package.html
new file mode 100644
index 0000000..52ec19cb
--- /dev/null
+++ b/libjava/classpath/java/awt/dnd/peer/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.dnd.peer package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.dnd.peer</title></head>
+
+<body>
+<p>Interfaces for using native interface components.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/event/AWTEventListener.java b/libjava/classpath/java/awt/event/AWTEventListener.java
new file mode 100644
index 0000000..079a91d
--- /dev/null
+++ b/libjava/classpath/java/awt/event/AWTEventListener.java
@@ -0,0 +1,65 @@
+/* AWTEventListener.java -- listen for all events in the AWT system
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Toolkit;
+import java.util.EventListener;
+
+/**
+ * This listener is for classes that need to listen to all events in the AWT
+ * system. In general, this should not be used except for classes like
+ * javax.accessibility or by event recorders.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see AWTEvent
+ * @see Toolkit#addAWTEventListener(AWTEventListener, long)
+ * @see Toolkit#removeAWTEventListener(AWTEventListener)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface AWTEventListener extends EventListener
+{
+ /**
+ * This method is called when any event in the AWT system is dispatched.
+ *
+ * @param event the AWTEvent that was dispatched
+ */
+ void eventDispatched(AWTEvent event);
+} // interface AWTEventListener
diff --git a/libjava/classpath/java/awt/event/AWTEventListenerProxy.java b/libjava/classpath/java/awt/event/AWTEventListenerProxy.java
new file mode 100644
index 0000000..3d9958b
--- /dev/null
+++ b/libjava/classpath/java/awt/event/AWTEventListenerProxy.java
@@ -0,0 +1,155 @@
+/* AWTEventListenerProxy.java -- wrapper/filter for AWTEventListener
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Toolkit;
+import java.util.EventListenerProxy;
+
+/**
+ * This class allows adding an AWTEventListener which only pays attention to
+ * a specific event mask.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Toolkit
+ * @see EventListenerProxy
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public class AWTEventListenerProxy extends EventListenerProxy
+ implements AWTEventListener
+{
+ /** The event mask. */
+ private final long mask;
+
+ /**
+ * Construct an AWT Event Listener which only listens to events in the given
+ * mask, passing the work on to the real listener.
+ *
+ * @param eventMask the mask of events to listen to
+ * @param listener the wrapped listener
+ */
+ public AWTEventListenerProxy(long eventMask, AWTEventListener listener)
+ {
+ super(listener);
+ mask = eventMask;
+ }
+
+ /**
+ * Forwards events on to the delegate if they meet the event mask.
+ *
+ * @param event the property change event to filter
+ * @throws NullPointerException if the delegate this was created with is null
+ */
+ public void eventDispatched(AWTEvent event)
+ {
+ int id = event == null ? 0 : event.getID();
+ if (((mask & AWTEvent.ACTION_EVENT_MASK) != 0
+ && event instanceof ActionEvent)
+ || ((mask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0
+ && event instanceof AdjustmentEvent)
+ || ((mask & AWTEvent.COMPONENT_EVENT_MASK) != 0
+ && event instanceof ComponentEvent
+ && (id >= ComponentEvent.COMPONENT_FIRST
+ && id <= ComponentEvent.COMPONENT_LAST))
+ || ((mask & AWTEvent.CONTAINER_EVENT_MASK) != 0
+ && event instanceof ContainerEvent)
+ || ((mask & AWTEvent.FOCUS_EVENT_MASK) != 0
+ && event instanceof FocusEvent)
+ || ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
+ && event instanceof HierarchyEvent
+ && (id == HierarchyEvent.ANCESTOR_MOVED
+ || id == HierarchyEvent.ANCESTOR_RESIZED))
+ || ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0
+ && event instanceof HierarchyEvent
+ && id == HierarchyEvent.HIERARCHY_CHANGED)
+ || ((mask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0
+ && event instanceof InputMethodEvent)
+ || ((mask & AWTEvent.INVOCATION_EVENT_MASK) != 0
+ && event instanceof InvocationEvent)
+ || ((mask & AWTEvent.ITEM_EVENT_MASK) != 0
+ && event instanceof ItemEvent)
+ || ((mask & AWTEvent.KEY_EVENT_MASK) != 0
+ && event instanceof KeyEvent)
+ || ((mask & AWTEvent.MOUSE_EVENT_MASK) != 0
+ && event instanceof MouseEvent
+ && (id == MouseEvent.MOUSE_PRESSED
+ || id == MouseEvent.MOUSE_RELEASED
+ || id == MouseEvent.MOUSE_CLICKED
+ || id == MouseEvent.MOUSE_ENTERED
+ || id == MouseEvent.MOUSE_EXITED))
+ || ((mask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0
+ && event instanceof MouseEvent
+ && (id == MouseEvent.MOUSE_MOVED
+ || id == MouseEvent.MOUSE_DRAGGED))
+ || ((mask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0
+ && event instanceof MouseWheelEvent)
+ || ((mask & AWTEvent.PAINT_EVENT_MASK) != 0
+ && event instanceof PaintEvent)
+ || ((mask & AWTEvent.TEXT_EVENT_MASK) != 0
+ && event instanceof TextEvent)
+ || ((mask & AWTEvent.WINDOW_EVENT_MASK) != 0
+ && event instanceof WindowEvent
+ && (id == WindowEvent.WINDOW_OPENED
+ || id == WindowEvent.WINDOW_CLOSING
+ || id == WindowEvent.WINDOW_CLOSED
+ || id == WindowEvent.WINDOW_ICONIFIED
+ || id == WindowEvent.WINDOW_DEICONIFIED
+ || id == WindowEvent.WINDOW_ACTIVATED
+ || id == WindowEvent.WINDOW_DEACTIVATED))
+ || ((mask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0
+ && event instanceof WindowEvent
+ && (id == WindowEvent.WINDOW_GAINED_FOCUS
+ || id == WindowEvent.WINDOW_LOST_FOCUS))
+ || ((mask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0
+ && event instanceof WindowEvent
+ && id == WindowEvent.WINDOW_STATE_CHANGED))
+ ((AWTEventListener) getListener()).eventDispatched(event);
+ }
+
+ /**
+ * This returns the event mask associated with this listener.
+ *
+ * @return the event mask
+ */
+ public long getEventMask()
+ {
+ return mask;
+ }
+} // class AWTEventListenerProxy
diff --git a/libjava/classpath/java/awt/event/ActionEvent.java b/libjava/classpath/java/awt/event/ActionEvent.java
new file mode 100644
index 0000000..4bce7d4
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ActionEvent.java
@@ -0,0 +1,226 @@
+/* ActionEvent.java -- an action has been triggered
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.EventQueue;
+
+/**
+ * This event is generated when an action on a component (such as a
+ * button press) occurs.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ActionListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class ActionEvent extends AWTEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -7671078796273832149L;
+
+ /** Bit mask indicating the shift key was pressed. */
+ public static final int SHIFT_MASK = InputEvent.SHIFT_MASK;
+
+ /** Bit mask indicating the control key was pressed. */
+ public static final int CTRL_MASK = InputEvent.CTRL_MASK;
+
+ /** Bit mask indicating the that meta key was pressed. */
+ public static final int META_MASK = InputEvent.META_MASK;
+
+ /** Bit mask indicating that the alt key was pressed. */
+ public static final int ALT_MASK = InputEvent.ALT_MASK;
+
+ /** The first id number in the range of action id's. */
+ public static final int ACTION_FIRST = 1001;
+
+ /** The last id number in the range of action id's. */
+ public static final int ACTION_LAST = 1001;
+
+ /** An event id indicating that an action has occurred. */
+ public static final int ACTION_PERFORMED = 1001;
+
+ /**
+ * A nonlocalized string that gives more specific details of the event cause.
+ *
+ * @see #getActionCommand()
+ * @serial the command for this event
+ */
+ private final String actionCommand;
+
+ /**
+ * The bitmask of the modifiers that were pressed during the action.
+ *
+ * @see #getModifiers()
+ * @serial modifiers for this event
+ */
+ private final int modifiers;
+
+ /**
+ * The timestamp of this event; usually the same as the underlying input
+ * event.
+ *
+ * @see #getWhen()
+ * @serial the timestamp of the event
+ * @since 1.4
+ */
+ private final long when;
+
+ /**
+ * Initializes a new instance of <code>ActionEvent</code> with the
+ * specified source, id, and command. Note that an invalid id leads to
+ * unspecified results.
+ *
+ * @param source the event source
+ * @param id the event id
+ * @param command the command string for this action
+ * @throws IllegalArgumentException if source is null
+ */
+ public ActionEvent(Object source, int id, String command)
+ {
+ this(source, id, command, EventQueue.getMostRecentEventTime(), 0);
+ }
+
+ /**
+ * Initializes a new instance of <code>ActionEvent</code> with the
+ * specified source, id, command, and modifiers. Note that an invalid id
+ * leads to unspecified results.
+ *
+ * @param source the event source
+ * @param id the event id
+ * @param command the command string for this action
+ * @param modifiers the bitwise or of modifier keys down during the action
+ * @throws IllegalArgumentException if source is null
+ */
+ public ActionEvent(Object source, int id, String command, int modifiers)
+ {
+ this(source, id, command, EventQueue.getMostRecentEventTime(), modifiers);
+ }
+
+ /**
+ * Initializes a new instance of <code>ActionEvent</code> with the
+ * specified source, id, command, and modifiers, and timestamp. Note that
+ * an invalid id leads to unspecified results.
+ *
+ * @param source the event source
+ * @param id the event id
+ * @param command the command string for this action
+ * @param when the timestamp of the event
+ * @param modifiers the bitwise or of modifier keys down during the action
+ * @throws IllegalArgumentException if source is null
+ * @since 1.4
+ */
+ public ActionEvent(Object source, int id, String command, long when,
+ int modifiers)
+ {
+ super(source, id);
+ actionCommand = command;
+ this.when = when;
+ this.modifiers = modifiers;
+ }
+
+ /**
+ * Returns the command string associated with this action.
+ *
+ * @return the command string associated with this action
+ */
+ public String getActionCommand()
+ {
+ return actionCommand;
+ }
+
+ /**
+ * Gets the timestamp of when this action took place. Usually, this
+ * corresponds to the timestamp of the underlying InputEvent.
+ *
+ * @return the timestamp of this action
+ * @since 1.4
+ */
+ public long getWhen()
+ {
+ return when;
+ }
+
+ /**
+ * Returns the keys held down during the action. This value will be a
+ * combination of the bit mask constants defined in this class, or 0 if no
+ * modifiers were pressed.
+ *
+ * @return the modifier bits
+ */
+ public int getModifiers()
+ {
+ return modifiers;
+ }
+
+ /**
+ * Returns a string that identifies the action event. This is in the format
+ * <code>"ACTION_PERFORMED,cmd=" + getActionCommand() + ",when=" + getWhen()
+ * + ",modifiers=" + &lt;modifier string&gt;</code>, where the modifier
+ * string is in the order "Meta", "Ctrl", "Alt", "Shift", "Alt Graph", and
+ * "Button1", separated by '+', according to the bits set in getModifiers().
+ *
+ * @return a string identifying the event
+ */
+ public String paramString()
+ {
+ StringBuffer s = new StringBuffer(id == ACTION_PERFORMED
+ ? "ACTION_PERFORMED,cmd="
+ : "unknown type,cmd=");
+ s.append(actionCommand).append(",when=").append(when).append(",modifiers");
+ int len = s.length();
+ s.setLength(len + 1);
+ if ((modifiers & META_MASK) != 0)
+ s.append("+Meta");
+ if ((modifiers & CTRL_MASK) != 0)
+ s.append("+Ctrl");
+ if ((modifiers & ALT_MASK) != 0)
+ s.append("+Alt");
+ if ((modifiers & SHIFT_MASK) != 0)
+ s.append("+Shift");
+ if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0)
+ s.append("+Alt Graph");
+ if ((modifiers & InputEvent.BUTTON1_MASK) != 0)
+ s.append("+Button1");
+ s.setCharAt(len, '=');
+ return s.toString();
+ }
+} // class ActionEvent
diff --git a/libjava/classpath/java/awt/event/ActionListener.java b/libjava/classpath/java/awt/event/ActionListener.java
new file mode 100644
index 0000000..4c302cc
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ActionListener.java
@@ -0,0 +1,59 @@
+/* ActionListener.java -- listens for action events
+ Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that listen for action events.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ActionEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface ActionListener extends EventListener
+{
+ /**
+ * This method is invoked when an action occurs.
+ *
+ * @param event the <code>ActionEvent</code> that occurred
+ */
+ void actionPerformed(ActionEvent event);
+}
diff --git a/libjava/classpath/java/awt/event/AdjustmentEvent.java b/libjava/classpath/java/awt/event/AdjustmentEvent.java
new file mode 100644
index 0000000..867c577
--- /dev/null
+++ b/libjava/classpath/java/awt/event/AdjustmentEvent.java
@@ -0,0 +1,222 @@
+/* AdjustmentEvent.java -- an adjustable value was changed
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Adjustable;
+
+/**
+ * This class represents an event that is generated when an adjustable
+ * value is changed.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see Adjustable
+ * @see AdjustmentListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class AdjustmentEvent extends AWTEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 5700290645205279921L;
+
+ /** This is the first id in the range of ids used by adjustment events. */
+ public static final int ADJUSTMENT_FIRST = 601;
+
+ /** This is the last id in the range of ids used by adjustment events. */
+ public static final int ADJUSTMENT_LAST = 601;
+
+ /** This is the id indicating an adjustment value changed. */
+ public static final int ADJUSTMENT_VALUE_CHANGED = 601;
+
+ /** Adjustment type for unit increments. */
+ public static final int UNIT_INCREMENT = 1;
+
+ /** Adjustment type for unit decrements. */
+ public static final int UNIT_DECREMENT = 2;
+
+ /** Adjustment type for block decrements. */
+ public static final int BLOCK_DECREMENT = 3;
+
+ /** Adjustment type for block increments. */
+ public static final int BLOCK_INCREMENT = 4;
+
+ /** Adjustment type for tracking adjustments. */
+ public static final int TRACK = 5;
+
+ /**
+ * The adjustable object that caused the event.
+ *
+ * @see #getAdjustable()
+ * @serial the cause
+ */
+ private final Adjustable adjustable;
+
+ /**
+ * The type of adjustment, one of {@link #UNIT_INCREMENT},
+ * {@link #UNIT_DECREMENT}, {@link #BLOCK_INCREMENT},
+ * {@link #BLOCK_DECREMENT}, or {@link #TRACK}.
+ *
+ * @see #getAdjustmentType()
+ * @serial the adjustment type
+ */
+ private final int adjustmentType;
+
+ /**
+ * The new value of the adjustable; it should be in the range of the
+ * adjustable cause.
+ *
+ * @see #getValue()
+ * @serial the adjustment value
+ */
+ private final int value;
+
+ /**
+ * True if this is in a series of multiple adjustment events.
+ *
+ * @see #getValueIsAdjusting()
+ * @serial true if this is not the last adjustment
+ * @since 1.4
+ */
+ private final boolean isAdjusting;
+
+ /**
+ * Initializes an instance of <code>AdjustmentEvent</code> with the
+ * specified source, id, type, and value. Note that an invalid id leads to
+ * unspecified results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @param type the event type, one of the constants of this class
+ * @param value the value of the adjustment
+ * @throws IllegalArgumentException if source is null
+ */
+ public AdjustmentEvent(Adjustable source, int id, int type, int value)
+ {
+ this(source, id, type, value, false);
+ }
+
+ /**
+ * Initializes an instance of <code>AdjustmentEvent</code> with the
+ * specified source, id, type, and value. Note that an invalid id leads to
+ * unspecified results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @param type the event type, one of the constants of this class
+ * @param value the value of the adjustment
+ * @param isAdjusting if this event is in a chain of adjustments
+ * @throws IllegalArgumentException if source is null
+ * @since 1.4
+ */
+ public AdjustmentEvent(Adjustable source, int id, int type, int value,
+ boolean isAdjusting)
+ {
+ super(source, id);
+ this.adjustmentType = type;
+ this.value = value;
+ adjustable = source;
+ this.isAdjusting = isAdjusting;
+ }
+
+ /**
+ * This method returns the source of the event as an <code>Adjustable</code>.
+ *
+ * @return the <code>Adjustable</code> source of the event
+ */
+ public Adjustable getAdjustable()
+ {
+ return adjustable;
+ }
+
+ /**
+ * Returns the new value of the adjustable object.
+ *
+ * @return the value of the event
+ */
+ public int getValue()
+ {
+ return value;
+ }
+
+ /**
+ * Returns the type of the event, which will be one of
+ * {@link #UNIT_INCREMENT}, {@link #UNIT_DECREMENT},
+ * {@link #BLOCK_INCREMENT}, {@link #BLOCK_DECREMENT}, or {@link #TRACK}.
+ *
+ * @return the type of the event
+ */
+ public int getAdjustmentType()
+ {
+ return adjustmentType;
+ }
+
+ /**
+ * Test if this event is part of a sequence of multiple adjustements.
+ *
+ * @return true if this is not the last adjustment
+ * @since 1.4
+ */
+ public boolean getValueIsAdjusting()
+ {
+ return isAdjusting;
+ }
+
+ /**
+ * Returns a string that describes the event. This is in the format
+ * <code>"ADJUSTMENT_VALUE_CHANGED,adjType=" + &lt;type&gt; + ",value="
+ * + getValue() + ",isAdjusting=" + getValueIsAdjusting()</code>, where
+ * type is the name of the constant returned by getAdjustmentType().
+ *
+ * @return a string that describes the event
+ */
+ public String paramString()
+ {
+ return (id == ADJUSTMENT_VALUE_CHANGED
+ ? "ADJUSTMENT_VALUE_CHANGED,adjType=" : "unknown type,adjType=")
+ + (adjustmentType == UNIT_INCREMENT ? "UNIT_INCREMENT,value="
+ : adjustmentType == UNIT_DECREMENT ? "UNIT_DECREMENT,value="
+ : adjustmentType == BLOCK_INCREMENT ? "BLOCK_INCREMENT,value="
+ : adjustmentType == BLOCK_DECREMENT ? "BLOCK_DECREMENT,value="
+ : adjustmentType == TRACK ? "TRACK,value=" : "unknown type,value=")
+ + value + ",isAdjusting=" + isAdjusting;
+ }
+} // class AdjustmentEvent
diff --git a/libjava/classpath/java/awt/event/AdjustmentListener.java b/libjava/classpath/java/awt/event/AdjustmentListener.java
new file mode 100644
index 0000000..1eb2e3b
--- /dev/null
+++ b/libjava/classpath/java/awt/event/AdjustmentListener.java
@@ -0,0 +1,58 @@
+/* AdjustmentListener.java -- listen for adjustment events
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * Interface for classes that listen for adjustment events.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface AdjustmentListener extends EventListener
+{
+ /**
+ * This method is called when an adjustable value changes.
+ *
+ * @param event the <code>AdjustmentEvent</code> that occurred
+ */
+ void adjustmentValueChanged(AdjustmentEvent event);
+} // interface AdjustmentListener
diff --git a/libjava/classpath/java/awt/event/ComponentAdapter.java b/libjava/classpath/java/awt/event/ComponentAdapter.java
new file mode 100644
index 0000000..6b4893f
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ComponentAdapter.java
@@ -0,0 +1,97 @@
+/* ComponentAdapter.java -- convenience class for writing component listeners
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+/**
+ * This class implements <code>ComponentListener</code> and implements
+ * all methods with empty bodies. This allows a listener interested in
+ * implementing only a subset of the <code>ComponentListener</code>
+ * interface to extend this class and override only the desired methods.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ComponentEvent
+ * @see ComponentListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class ComponentAdapter implements ComponentListener
+{
+ /**
+ * Do nothing default constructor for subclasses.
+ */
+ public ComponentAdapter()
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void componentResized(ComponentEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void componentMoved(ComponentEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void componentShown(ComponentEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void componentHidden(ComponentEvent event)
+ {
+ }
+} // class ComponentAdapter
diff --git a/libjava/classpath/java/awt/event/ComponentEvent.java b/libjava/classpath/java/awt/event/ComponentEvent.java
new file mode 100644
index 0000000..ba9c2a5
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ComponentEvent.java
@@ -0,0 +1,137 @@
+/* ComponentEvent.java -- notification of events for components
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+
+/**
+ * This class is for events generated when a component is moved, resized,
+ * hidden, or shown. These events normally do not need to be handled by the
+ * application, since the AWT system automatically takes care of them. This
+ * is also the superclass for other events on components, but
+ * ComponentListeners ignore such subclasses.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ComponentAdapter
+ * @see ComponentListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class ComponentEvent extends AWTEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 8101406823902992965L;
+
+ /** This is the first id in the range of ids used by this class. */
+ public static final int COMPONENT_FIRST = 100;
+
+ /** This is the last id in the range of ids used by this class. */
+ public static final int COMPONENT_LAST = 103;
+
+ /** This id indicates that a component was moved. */
+ public static final int COMPONENT_MOVED = 100;
+
+ /** This id indicates that a component was resized. */
+ public static final int COMPONENT_RESIZED = 101;
+
+ /** This id indicates that a component was shown. */
+ public static final int COMPONENT_SHOWN = 102;
+
+ /** This id indicates that a component was hidden. */
+ public static final int COMPONENT_HIDDEN = 103;
+
+ /**
+ * Initializes a new instance of <code>ComponentEvent</code> with the
+ * specified source and id. Note that an invalid id leads to unspecified
+ * results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @throws IllegalArgumentException if source is null
+ */
+ public ComponentEvent(Component source, int id)
+ {
+ super(source, id);
+ }
+
+ /**
+ * This method returns the event source as a <code>Component</code>. If the
+ * source has subsequently been modified to a non-Component, this returns
+ * null.
+ *
+ * @return the event source as a <code>Component</code>, or null
+ */
+ public Component getComponent()
+ {
+ return source instanceof Component ? (Component) source : null;
+ }
+
+ /**
+ * This method returns a string identifying this event. This is the field
+ * name of the id type, and for COMPONENT_MOVED or COMPONENT_RESIZED, the
+ * new bounding box of the component.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ // Unlike Sun, we don't throw NullPointerException or ClassCastException
+ // when source was illegally changed.
+ switch (id)
+ {
+ case COMPONENT_MOVED:
+ return "COMPONENT_MOVED "
+ + (source instanceof Component
+ ? ((Component) source).getBounds() : (Object) "");
+ case COMPONENT_RESIZED:
+ return "COMPONENT_RESIZED "
+ + (source instanceof Component
+ ? ((Component) source).getBounds() : (Object) "");
+ case COMPONENT_SHOWN:
+ return "COMPONENT_SHOWN";
+ case COMPONENT_HIDDEN:
+ return "COMPONENT_HIDDEN";
+ default:
+ return "unknown type";
+ }
+ }
+} // class ComponentEvent
diff --git a/libjava/classpath/java/awt/event/ComponentListener.java b/libjava/classpath/java/awt/event/ComponentListener.java
new file mode 100644
index 0000000..b43faae
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ComponentListener.java
@@ -0,0 +1,84 @@
+/* ComponentListener.java -- receive all events for a component
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that receive all events from a component.
+ * Normally it is not necessary to process these events since the AWT
+ * handles them internally, taking all appropriate actions. To watch a subset
+ * of these events, use a ComponentAdapter.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ComponentAdapter
+ * @see ComponentEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface ComponentListener extends EventListener
+{
+ /**
+ * This method is called when the component is resized.
+ *
+ * @param event the <code>ComponentEvent</code> indicating the resize
+ */
+ void componentResized(ComponentEvent event);
+
+ /**
+ * This method is called when the component is moved.
+ *
+ * @param event the <code>ComponentEvent</code> indicating the move
+ */
+ void componentMoved(ComponentEvent event);
+
+ /**
+ * This method is called when the component is made visible.
+ *
+ * @param event the <code>ComponentEvent</code> indicating the visibility
+ */
+ void componentShown(ComponentEvent event);
+
+ /**
+ * This method is called when the component is hidden.
+ *
+ * @param event the <code>ComponentEvent</code> indicating the visibility
+ */
+ void componentHidden(ComponentEvent event);
+} // interface ComponentListener
diff --git a/libjava/classpath/java/awt/event/ContainerAdapter.java b/libjava/classpath/java/awt/event/ContainerAdapter.java
new file mode 100644
index 0000000..c847adf
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ContainerAdapter.java
@@ -0,0 +1,79 @@
+/* ContainerAdapter.java -- convenience class for writing container listeners
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+/**
+ * This class implements <code>ContainerListener</code> and implements
+ * all methods with empty bodies. This allows a listener interested in
+ * implementing only a subset of the <code>ContainerListener</code>
+ * interface to extend this class and override only the desired methods.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ContainerEvent
+ * @see ContainerListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class ContainerAdapter implements ContainerListener
+{
+ /**
+ * Do nothing default constructor for subclasses.
+ */
+ public ContainerAdapter()
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void componentAdded(ContainerEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void componentRemoved(ContainerEvent event)
+ {
+ }
+} // class ContainerAdapter
diff --git a/libjava/classpath/java/awt/event/ContainerEvent.java b/libjava/classpath/java/awt/event/ContainerEvent.java
new file mode 100644
index 0000000..3c401fe
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ContainerEvent.java
@@ -0,0 +1,135 @@
+/* ContainerEvent.java -- components added/removed from a container
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Container;
+
+/**
+ * This event is generated when a component is added or removed from a
+ * container. Applications do not ordinarily need to handle these events
+ * since the AWT system handles them internally.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ContainerAdapter
+ * @see ContainerListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class ContainerEvent extends ComponentEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -4114942250539772041L;
+
+ /** This is the first id in the id range used by this class. */
+ public static final int CONTAINER_FIRST = 300;
+
+ /** This is the last id in the id range used by this class. */
+ public static final int CONTAINER_LAST = 301;
+
+ /** This id indicates a component was added to the container. */
+ public static final int COMPONENT_ADDED = 300;
+
+ /** This id indicates a component was removed from the container. */
+ public static final int COMPONENT_REMOVED = 301;
+
+ /**
+ * The non-null child component that was added or removed.
+ *
+ * @serial the child component that changed
+ */
+ private final Component child;
+
+ /**
+ * Initializes a new instance of <code>ContainerEvent</code> with the
+ * specified source and id. Additionally, the affected child component
+ * is also passed as a parameter. Note that an invalid id leads to
+ * unspecified results.
+ *
+ * @param source the source container of the event
+ * @param id the event id
+ * @param child the child component affected by this event
+ * @throws IllegalArgumentException if source is null
+ */
+ public ContainerEvent(Component source, int id, Component child)
+ {
+ super(source, id);
+ this.child = child;
+ }
+
+ /**
+ * Returns the source of this event as a <code>Container</code>.
+ *
+ * @return the source of the event
+ * @throws ClassCastException if the source is changed to a non-Container
+ */
+ public Container getContainer()
+ {
+ return (Container) source;
+ }
+
+ /**
+ * This method returns the child object that was added or removed from
+ * the container.
+ *
+ * @return the child object added or removed
+ */
+ public Component getChild()
+ {
+ return child;
+ }
+
+ /**
+ * This method returns a string identifying this event. It is formatted as:
+ * <code>(getID() == COMPONENT_ADDED ? "COMPONENT_ADDED"
+ * : "COMPONENT_REMOVED") + ",child=" + getChild().getName()</code>.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ // Unlike Sun, we don't throw NullPointerException if child is illegally
+ // null.
+ return (id == COMPONENT_ADDED ? "COMPONENT_ADDED,child="
+ : id == COMPONENT_REMOVED ? "COMPONENT_REMOVED,child="
+ : "unknown type,child=") + (child == null ? "" : child.getName());
+ }
+} // class ContainerEvent
diff --git a/libjava/classpath/java/awt/event/ContainerListener.java b/libjava/classpath/java/awt/event/ContainerListener.java
new file mode 100644
index 0000000..b37d434
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ContainerListener.java
@@ -0,0 +1,70 @@
+/* ContainerListener.java -- listen for container events
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to listen for all events from
+ * container objects. This is normally not necessary since the AWT system
+ * listens for and processes these events. To watch a subset of these events,
+ * use a ContainerAdapter.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ContainerAdapter
+ * @see ContainerEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface ContainerListener extends EventListener
+{
+ /**
+ * This method is called when a component is added to the container.
+ *
+ * @param event the <code>ContainerEvent</code> indicating component addition
+ */
+ void componentAdded(ContainerEvent event);
+
+ /**
+ * This method is called when a component is removed from the container.
+ *
+ * @param event the <code>ContainerEvent</code> indicating component removal
+ */
+ void componentRemoved(ContainerEvent event);
+} // interface ContainerListener
diff --git a/libjava/classpath/java/awt/event/FocusAdapter.java b/libjava/classpath/java/awt/event/FocusAdapter.java
new file mode 100644
index 0000000..fb0532a
--- /dev/null
+++ b/libjava/classpath/java/awt/event/FocusAdapter.java
@@ -0,0 +1,79 @@
+/* FocusAdapter.java -- convenience class for writing focus listeners
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+/**
+ * This class implements <code>FocusListener</code> and implements all
+ * methods with empty bodies. This allows a listener interested in
+ * implementing only a subset of the <code>FocusListener</code> interface to
+ * extend this class and override only the desired methods.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see FocusEvent
+ * @see FocusListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class FocusAdapter implements FocusListener
+{
+ /**
+ * Do nothing default constructor for subclasses.
+ */
+ public FocusAdapter()
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void focusGained(FocusEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void focusLost(FocusEvent event)
+ {
+ }
+} // class FocusAdapter
diff --git a/libjava/classpath/java/awt/event/FocusEvent.java b/libjava/classpath/java/awt/event/FocusEvent.java
new file mode 100644
index 0000000..a44284a
--- /dev/null
+++ b/libjava/classpath/java/awt/event/FocusEvent.java
@@ -0,0 +1,181 @@
+/* FocusEvent.java -- generated for a focus change
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.Component;
+
+/**
+ * This class represents an event generated when a focus change occurs for a
+ * component. There are both temporary changes, such as when focus is stolen
+ * during a sroll then returned, and permanent changes, such as when the user
+ * TABs through focusable components.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see FocusAdapter
+ * @see FocusListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class FocusEvent extends ComponentEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 523753786457416396L;
+
+ /** This is the first id in the range of ids used by this class. */
+ public static final int FOCUS_FIRST = 1004;
+
+ /** This is the last id in the range of ids used by this class. */
+ public static final int FOCUS_LAST = 1005;
+
+ /** This is the event id for a focus gained event. */
+ public static final int FOCUS_GAINED = 1004;
+
+ /** This is the event id for a focus lost event. */
+ public static final int FOCUS_LOST = 1005;
+
+ /**
+ * Indicates whether or not the focus change is temporary.
+ *
+ * @see #isTemporary()
+ * @serial true if the focus change is temporary
+ */
+ private final boolean temporary;
+
+ /**
+ * The other component which is giving up or stealing focus from this
+ * component, if known.
+ *
+ * @see #getOppositeComponent()
+ * @serial the component with the opposite focus event, or null
+ * @since 1.4
+ */
+ private final Component opposite;
+
+ /**
+ * Initializes a new instance of <code>FocusEvent</code> with the
+ * specified source, id, temporary status, and opposite counterpart. Note
+ * that an invalid id leads to unspecified results.
+ *
+ * @param source the component that is gaining or losing focus
+ * @param id the event id
+ * @param temporary true if the focus change is temporary
+ * @param opposite the component receiving the opposite focus event, or null
+ * @throws IllegalArgumentException if source is null
+ */
+ public FocusEvent(Component source, int id, boolean temporary,
+ Component opposite)
+ {
+ super(source, id);
+ this.temporary = temporary;
+ this.opposite = opposite;
+ }
+
+ /**
+ * Initializes a new instance of <code>FocusEvent</code> with the
+ * specified source, id, and temporary status. Note that an invalid id
+ * leads to unspecified results.
+ *
+ * @param source the component that is gaining or losing focus
+ * @param id the event id
+ * @param temporary true if the focus change is temporary
+ * @throws IllegalArgumentException if source is null
+ */
+ public FocusEvent(Component source, int id, boolean temporary)
+ {
+ this(source, id, temporary, null);
+ }
+
+ /**
+ * Initializes a new instance of <code>FocusEvent</code> with the
+ * specified source and id. Note that an invalid id leads to unspecified
+ * results.
+ *
+ * @param source the component that is gaining or losing focus
+ * @param id the event id
+ * @throws IllegalArgumentException if source is null
+ */
+ public FocusEvent(Component source, int id)
+ {
+ this(source, id, false, null);
+ }
+
+ /**
+ * This method tests whether or not the focus change is temporary or
+ * permanent.
+ *
+ * @return true if the focus change is temporary
+ */
+ public boolean isTemporary()
+ {
+ return temporary;
+ }
+
+ /**
+ * Returns the component which received the opposite focus event. If this
+ * component gained focus, the opposite lost focus; likewise if this
+ * component is giving up focus, the opposite is gaining it. If this
+ * information is unknown, perhaps because the opposite is a native
+ * application, this returns null.
+ *
+ * @return the component with the focus opposite, or null
+ * @since 1.4
+ */
+ public Component getOppositeComponent()
+ {
+ return opposite;
+ }
+
+ /**
+ * Returns a string identifying this event. This is formatted as:
+ * <code>(getID() == FOCUS_GAINED ? "FOCUS_GAINED" : "FOCUS_LOST")
+ * + (isTemporary() ? ",temporary," : ",permanent,") + "opposite="
+ * + getOppositeComponent()</code>.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ return (id == FOCUS_GAINED ? "FOCUS_GAINED"
+ : id == FOCUS_LOST ? "FOCUS_LOST" : "unknown type")
+ + (temporary ? ",temporary,opposite=" : ",permanent,opposite=")
+ + opposite;
+ }
+} // class FocusEvent
diff --git a/libjava/classpath/java/awt/event/FocusListener.java b/libjava/classpath/java/awt/event/FocusListener.java
new file mode 100644
index 0000000..1f72018
--- /dev/null
+++ b/libjava/classpath/java/awt/event/FocusListener.java
@@ -0,0 +1,69 @@
+/* FocusListener.java -- listen for focus changes
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to be notified of changes of
+ * keyboard focus for a component. To watch a subset of these events, use a
+ * FocusAdapter.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see FocusAdapter
+ * @see FocusEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface FocusListener extends EventListener
+{
+ /**
+ * This method is called when a component gains the keyboard focus.
+ *
+ * @param event the <code>FocusEvent</code> indicating that focus was gained
+ */
+ void focusGained(FocusEvent event);
+
+ /**
+ * This method is invoked when a component loses the keyboard focus.
+ *
+ * @param event the <code>FocusEvent</code> indicating that focus was lost
+ */
+ void focusLost(FocusEvent event);
+} // interface FocusListener
diff --git a/libjava/classpath/java/awt/event/HierarchyBoundsAdapter.java b/libjava/classpath/java/awt/event/HierarchyBoundsAdapter.java
new file mode 100644
index 0000000..340cf01
--- /dev/null
+++ b/libjava/classpath/java/awt/event/HierarchyBoundsAdapter.java
@@ -0,0 +1,78 @@
+/* HierarchyBoundsAdapter.java -- convenience class for writing listeners
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.event;
+
+/**
+ * This class implements <code>HierarchyBoundsListener</code> and implements
+ * all methods with empty bodies. This allows a listener interested in
+ * implementing only a subset of the <code>HierarchyBoundsListener</code>
+ * interface to extend this class and override only the desired methods.
+ *
+ * @author Bryce McKinlay
+ * @see HierarchyBoundsListener
+ * @see HierarchyEvent
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener
+{
+ /**
+ * Do nothing default constructor for subclasses.
+ */
+ public HierarchyBoundsAdapter()
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void ancestorMoved(HierarchyEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void ancestorResized(HierarchyEvent event)
+ {
+ }
+}
diff --git a/libjava/classpath/java/awt/event/HierarchyBoundsListener.java b/libjava/classpath/java/awt/event/HierarchyBoundsListener.java
new file mode 100644
index 0000000..6896237
--- /dev/null
+++ b/libjava/classpath/java/awt/event/HierarchyBoundsListener.java
@@ -0,0 +1,70 @@
+/* HierarchyBoundsListener.java -- listens to bounds changes of parents
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This listens for changes in an ancestors size or location. Normally it is
+ * not necessary to process these events since the AWT handles them
+ * internally, taking all appropriate actions. To watch a subset of these
+ * events, use a HierarchyBoundsAdapter.
+ *
+ * @author Bryce McKinlay
+ * @see HierarchyBoundsAdapter
+ * @see HierarchyEvent
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public interface HierarchyBoundsListener extends EventListener
+{
+ /**
+ * Called when an ancestor component of the source is moved.
+ *
+ * @param e the event describing the ancestor's motion
+ */
+ void ancestorMoved(HierarchyEvent e);
+
+ /**
+ * Called when an ancestor component is resized.
+ *
+ * @param e the event describing the ancestor's resizing
+ */
+ void ancestorResized(HierarchyEvent e);
+} // interface HierarchyBoundsListener
diff --git a/libjava/classpath/java/awt/event/HierarchyEvent.java b/libjava/classpath/java/awt/event/HierarchyEvent.java
new file mode 100644
index 0000000..e10cefb
--- /dev/null
+++ b/libjava/classpath/java/awt/event/HierarchyEvent.java
@@ -0,0 +1,253 @@
+/* HierarchyEvent.java -- generated for a change in hierarchy
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.Container;
+
+/**
+ * This class represents an event generated for an ancestor component which
+ * may affect this component. These events normally do not need to be handled
+ * by the application, since the AWT system automatically takes care of them.
+ *
+ * <p>There are two types of hierarchy events. The first type is handled by
+ * HierarchyListener, and includes addition or removal of an ancestor, or
+ * an ancestor changing its on-screen status (visible and/or displayble). The
+ * second type is handled by HierarchyBoundsListener, and includes resizing
+ * or moving of an ancestor.
+ *
+ * @author Bryce McKinlay
+ * @see HierarchyListener
+ * @see HierarchyBoundsAdapter
+ * @see HierarchyBoundsListener
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public class HierarchyEvent extends AWTEvent
+{
+ /**
+ * Compatible with JDK 1.3+.
+ */
+ private static final long serialVersionUID = -5337576970038043990L;
+
+ /** This is the first id in the range of ids used by this class. */
+ public static final int HIERARCHY_FIRST = 1400;
+
+ /** This id indicates that the hierarchy tree changed. */
+ public static final int HIERARCHY_CHANGED = 1400;
+
+ /** This id indicates that an ancestor was moved. */
+ public static final int ANCESTOR_MOVED = 1401;
+
+ /** This id indicates that an ancestor was resized. */
+ public static final int ANCESTOR_RESIZED = 1402;
+
+ /** This is the last id in the range of ids used by this class. */
+ public static final int HIERARCHY_LAST = 1402;
+
+ /** This indicates that the HIERARCHY_CHANGED is a changed parent. */
+ public static final int PARENT_CHANGED = 1;
+
+ /**
+ * This indicates that the HIERARCHY_CHANGED is caused by a change in
+ * displayability.
+ *
+ * @see Component#isDisplayable()
+ * @see Component#addNotify()
+ * @see Component#removeNotify()
+ */
+ public static final int DISPLAYABILITY_CHANGED = 2;
+
+ /**
+ * This indicates that the HIERARCHY_CHANGED is a changed visibility.
+ *
+ * @see Component#isShowing()
+ * @see Component#addNotify()
+ * @see Component#removeNotify()
+ * @see Component#show()
+ * @see Component#hide()
+ */
+ public static final int SHOWING_CHANGED = 4;
+
+ /**
+ * The component at the top of the changed hierarchy.
+ *
+ * @serial the top component changed
+ */
+ private final Component changed;
+
+ /**
+ * The parent of this component, either before or after the change depending
+ * on the type of change.
+ *
+ * @serial the parent component changed
+ */
+ private final Container changedParent;
+
+ /**
+ * The bitmask of HIERARCHY_CHANGED event types.
+ *
+ * @serial the change flags
+ */
+ private final long changeFlags;
+
+ /**
+ * Initializes a new instance of <code>HierarchyEvent</code> with the
+ * specified parameters. Note that an invalid id leads to unspecified
+ * results.
+ *
+ * @param source the component whose hierarchy changed
+ * @param id the event id
+ * @param changed the top component in the tree of changed hierarchy
+ * @param changedParent the updated parent of this object
+ * @throws IllegalArgumentException if source is null
+ */
+ public HierarchyEvent(Component source, int id, Component changed,
+ Container changedParent)
+ {
+ this(source, id, changed, changedParent, 0);
+ }
+
+ /**
+ * Initializes a new instance of <code>HierarchyEvent</code> with the
+ * specified parameters. Note that an invalid id leads to unspecified
+ * results.
+ *
+ * @param source the component whose hierarchy changed
+ * @param id the event id
+ * @param changed the top component in the tree of changed hierarchy
+ * @param changedParent the updated parent of this object
+ * @param changeFlags the bitmask of specific HIERARCHY_CHANGED events
+ * @throws IllegalArgumentException if source is null
+ */
+ public HierarchyEvent(Component source, int id, Component changed,
+ Container changedParent, long changeFlags)
+ {
+ super(source, id);
+ this.changed = changed;
+ this.changedParent = changedParent;
+ this.changeFlags = changeFlags;
+ }
+
+ /**
+ * This method returns the event source as a <code>Component</code>. If the
+ * source has subsequently been modified to a non-Component, this returns
+ * null.
+ *
+ * @return the event source as a <code>Component</code>, or null
+ */
+ public Component getComponent()
+ {
+ return source instanceof Component ? (Component) source : null;
+ }
+
+ /**
+ * Returns the component at the top of the hierarchy which changed.
+ *
+ * @return the top changed component
+ */
+ public Component getChanged()
+ {
+ return changed;
+ }
+
+ /**
+ * Returns the parent of the component listed in <code>getChanged()</code>.
+ * If the cause of this event was <code>Container.add</code>, this is the
+ * new parent; if the cause was <code>Container.remove</code>, this is the
+ * old parent; otherwise it is the unchanged parent.
+ *
+ * @return the parent container of the changed component
+ */
+ public Container getChangedParent()
+ {
+ return changedParent;
+ }
+
+ /**
+ * If this is a HIERARCHY_CHANGED event, this returns a bitmask of the
+ * types of changes that took place.
+ *
+ * @return the bitwise or of hierarchy change types, or 0
+ * @see #PARENT_CHANGED
+ * @see #DISPLAYABILITY_CHANGED
+ * @see #SHOWING_CHANGED
+ */
+ public long getChangeFlags()
+ {
+ return changeFlags;
+ }
+
+ /**
+ * This method returns a string identifying this event. This is the field
+ * name of the id type, followed by a parenthesized listing of the changed
+ * component and its parent container. In addition, if the type is
+ * HIERARCHY_CHANGED, the flags preceed the changed component, in the
+ * order PARENT_CHANGED, DISPLAYABILITY_CHANGED, and SHOWING_CHANGED.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ StringBuffer r = new StringBuffer();
+ switch (id)
+ {
+ case HIERARCHY_CHANGED:
+ r.append("HIERARCHY_CHANGED (");
+ if ((changeFlags & PARENT_CHANGED) != 0)
+ r.append("PARENT_CHANGED,");
+ if ((changeFlags & DISPLAYABILITY_CHANGED) != 0)
+ r.append("DISPLAYABILITY_CHANGED,");
+ if ((changeFlags & SHOWING_CHANGED) != 0)
+ r.append("SHOWING_CHANGED,");
+ break;
+ case ANCESTOR_MOVED:
+ r.append("ANCESTOR_MOVED (");
+ break;
+ case ANCESTOR_RESIZED:
+ r.append("ANCESTOR_RESIZED (");
+ break;
+ default:
+ return "unknown type";
+ }
+ r.append(changed).append(',').append(changedParent).append(')');
+ return r.toString();
+ }
+} // class HierarchyEvent
diff --git a/libjava/classpath/java/awt/event/HierarchyListener.java b/libjava/classpath/java/awt/event/HierarchyListener.java
new file mode 100644
index 0000000..f90414b
--- /dev/null
+++ b/libjava/classpath/java/awt/event/HierarchyListener.java
@@ -0,0 +1,62 @@
+/* HierarchyListener.java -- listens to changes in the component hierarchy
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This listens for changes in the hierarchy tree of components. Normally it is
+ * not necessary to process these events since the AWT handles them
+ * internally, taking all appropriate actions.
+ *
+ * @author Bryce McKinlay
+ * @see HierarchyEvent
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public interface HierarchyListener extends EventListener
+{
+ /**
+ * Called when the hierarchy of this component changes. Use
+ * <code>getChangeFlags()</code> on the event to see what exactly changed.
+ *
+ * @param e the event describing the change
+ */
+ void hierarchyChanged(HierarchyEvent e);
+} // interface HierarchyListener
diff --git a/libjava/classpath/java/awt/event/InputEvent.java b/libjava/classpath/java/awt/event/InputEvent.java
new file mode 100644
index 0000000..8f9aed6
--- /dev/null
+++ b/libjava/classpath/java/awt/event/InputEvent.java
@@ -0,0 +1,381 @@
+/* InputEvent.java -- common superclass of component input events
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import gnu.java.awt.EventModifier;
+
+import java.awt.Component;
+
+/**
+ * This is the common superclass for all component input classes. These are
+ * passed to listeners before the component, so that listeners can consume
+ * the event before it does its default behavior.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see KeyEvent
+ * @see KeyAdapter
+ * @see MouseEvent
+ * @see MouseAdapter
+ * @see MouseMotionAdapter
+ * @see MouseWheelEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class InputEvent extends ComponentEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -2482525981698309786L;
+
+ /**
+ * This is the bit mask which indicates the shift key is down. It is
+ * recommended that SHIFT_DOWN_MASK be used instead.
+ *
+ * @see #SHIFT_DOWN_MASK
+ */
+ public static final int SHIFT_MASK = 1;
+
+ /**
+ * This is the bit mask which indicates the control key is down. It is
+ * recommended that CTRL_DOWN_MASK be used instead.
+ *
+ * @see #CTRL_DOWN_MASK
+ */
+ public static final int CTRL_MASK = 2;
+
+ /**
+ * This is the bit mask which indicates the meta key is down. It is
+ * recommended that META_DOWN_MASK be used instead.
+ *
+ * @see #META_DOWN_MASK
+ */
+ public static final int META_MASK = 4;
+
+ /**
+ * This is the bit mask which indicates the alt key is down. It is
+ * recommended that ALT_DOWN_MASK be used instead.
+ *
+ * @see #ALT_DOWN_MASK
+ */
+ public static final int ALT_MASK = 8;
+
+ /**
+ * This is the bit mask which indicates the alt-graph modifier is in effect.
+ * It is recommended that ALT_GRAPH_DOWN_MASK be used instead.
+ *
+ * @see #ALT_GRAPH_DOWN_MASK
+ */
+ public static final int ALT_GRAPH_MASK = 0x20;
+
+ /**
+ * This bit mask indicates mouse button one is down. It is recommended that
+ * BUTTON1_DOWN_MASK be used instead.
+ *
+ * @see #BUTTON1_DOWN_MASK
+ */
+ public static final int BUTTON1_MASK = 0x10;
+
+ /**
+ * This bit mask indicates mouse button two is down. It is recommended that
+ * BUTTON2_DOWN_MASK be used instead.
+ *
+ * @see #BUTTON2_DOWN_MASK
+ */
+ public static final int BUTTON2_MASK = 8;
+
+ /**
+ * This bit mask indicates mouse button three is down. It is recommended
+ * that BUTTON3_DOWN_MASK be used instead.
+ *
+ * @see #BUTTON3_DOWN_MASK
+ */
+ public static final int BUTTON3_MASK = 4;
+
+ /**
+ * The SHIFT key extended modifier.
+ *
+ * @since 1.4
+ */
+ public static final int SHIFT_DOWN_MASK = 0x0040;
+
+ /**
+ * The CTRL key extended modifier.
+ *
+ * @since 1.4
+ */
+ public static final int CTRL_DOWN_MASK = 0x0080;
+
+ /**
+ * The META key extended modifier.
+ *
+ * @since 1.4
+ */
+ public static final int META_DOWN_MASK = 0x0100;
+
+ /**
+ * The ALT key extended modifier.
+ *
+ * @since 1.4
+ */
+ public static final int ALT_DOWN_MASK = 0x0200;
+
+ /**
+ * The mouse button1 key extended modifier.
+ *
+ * @since 1.4
+ */
+ public static final int BUTTON1_DOWN_MASK = 0x0400;
+
+ /**
+ * The mouse button2 extended modifier.
+ *
+ * @since 1.4
+ */
+ public static final int BUTTON2_DOWN_MASK = 0x0800;
+
+ /**
+ * The mouse button3 extended modifier.
+ *
+ * @since 1.4
+ */
+ public static final int BUTTON3_DOWN_MASK = 0x1000;
+
+ /**
+ * The ALT_GRAPH key extended modifier.
+ *
+ * @since 1.4
+ */
+ public static final int ALT_GRAPH_DOWN_MASK = 0x2000;
+
+ /** The mask to convert new to old, package visible for use in subclasses. */
+ static final int CONVERT_MASK
+ = EventModifier.NEW_MASK & ~(BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK);
+
+ /**
+ * The timestamp when this event occurred.
+ *
+ * @see #getWhen()
+ * @serial the timestamp
+ */
+ private final long when;
+
+ /**
+ * The modifiers in effect for this event. Package visible for use by
+ * subclasses. The old style (bitmask 0x3f) should not be mixed with the
+ * new style (bitmasks 0xffffffc0).
+ *
+ * @see #getModifiers()
+ * @see MouseEvent
+ * @serial the modifier state, stored in the new style
+ */
+ int modifiers;
+
+ /**
+ * Initializes a new instance of <code>InputEvent</code> with the specified
+ * source, id, timestamp, and modifiers. Note that an invalid id leads to
+ * unspecified results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @param when the timestamp when the event occurred
+ * @param modifiers the modifiers in effect for this event, old or new style
+ * @throws IllegalArgumentException if source is null
+ */
+ InputEvent(Component source, int id, long when, int modifiers)
+ {
+ super(source, id);
+ this.when = when;
+ this.modifiers = EventModifier.extend(modifiers);
+ }
+
+ /**
+ * This method tests whether or not the shift key was down during the event.
+ *
+ * @return true if the shift key is down
+ */
+ public boolean isShiftDown()
+ {
+ return (modifiers & SHIFT_DOWN_MASK) != 0;
+ }
+
+ /**
+ * This method tests whether or not the control key was down during the
+ * event.
+ *
+ * @return true if the control key is down
+ */
+ public boolean isControlDown()
+ {
+ return (modifiers & CTRL_DOWN_MASK) != 0;
+ }
+
+ /**
+ * This method tests whether or not the meta key was down during the event.
+ *
+ * @return true if the meta key is down
+ */
+ public boolean isMetaDown()
+ {
+ return (modifiers & META_DOWN_MASK) != 0;
+ }
+
+ /**
+ * This method tests whether or not the alt key was down during the event.
+ *
+ * @return true if the alt key is down
+ */
+ public boolean isAltDown()
+ {
+ return (modifiers & ALT_DOWN_MASK) != 0;
+ }
+
+ /**
+ * This method tests whether or not the alt-graph modifier was in effect
+ * during the event.
+ *
+ * @return true if the alt-graph modifier is down
+ */
+ public boolean isAltGraphDown()
+ {
+ return (modifiers & ALT_GRAPH_DOWN_MASK) != 0;
+ }
+
+ /**
+ * This method returns the timestamp when this event occurred.
+ *
+ * @return the timestamp when this event occurred
+ */
+ public long getWhen()
+ {
+ return when;
+ }
+
+ /**
+ * This method returns the old-style modifiers in effect for this event.
+ * Note that this is ambiguous between button2 and alt, and between
+ * button3 and meta. Also, code which generated these modifiers tends to
+ * only list the modifier that just changed, even if others were down at
+ * the time. Consider using getModifiersEx instead. This will be a union
+ * of the bit masks defined in this class that are applicable to the event.
+ *
+ * @return the modifiers in effect for this event
+ * @see #getModifiersEx()
+ */
+ public int getModifiers()
+ {
+ return EventModifier.revert(modifiers);
+ }
+
+ /**
+ * Returns the extended modifiers (new-style) for this event. This represents
+ * the state of all modal keys and mouse buttons at the time of the event,
+ * and does not suffer from the problems mentioned in getModifiers.
+ *
+ * <p>For an example of checking multiple modifiers, this code will return
+ * true only if SHIFT and BUTTON1 were pressed and CTRL was not:
+ * <pre>
+ * int onmask = InputEvent.SHIFT_DOWN_MASK | InputEvent.BUTTON1_DOWN_MASK;
+ * int offmask = InputEvent.CTRL_DOWN_MASK;
+ * return (event.getModifiersEx() & (onmask | offmask)) == onmask;
+ * </pre>
+ *
+ * @return the bitwise or of all modifiers pressed during the event
+ * @since 1.4
+ */
+ public int getModifiersEx()
+ {
+ return modifiers;
+ }
+
+ /**
+ * Consumes this event. A consumed event is not processed further by the AWT
+ * system.
+ */
+ public void consume()
+ {
+ consumed = true;
+ }
+
+ /**
+ * This method tests whether or not this event has been consumed.
+ *
+ * @return true if this event has been consumed
+ */
+ public boolean isConsumed()
+ {
+ return consumed;
+ }
+
+ /**
+ * Convert the extended modifier bitmask into a String, such as "Shift" or
+ * "Ctrl+Button1".
+ *
+ * XXX Sun claims this can be localized via the awt.properties file - how
+ * do we implement that?
+ *
+ * @param modifiers the modifiers
+ * @return a string representation of the modifiers in this bitmask
+ * @since 1.4
+ */
+ public static String getModifiersExText(int modifiers)
+ {
+ modifiers &= EventModifier.NEW_MASK;
+ if (modifiers == 0)
+ return "";
+ StringBuffer s = new StringBuffer();
+ if ((modifiers & META_DOWN_MASK) != 0)
+ s.append("Meta+");
+ if ((modifiers & CTRL_DOWN_MASK) != 0)
+ s.append("Ctrl+");
+ if ((modifiers & ALT_DOWN_MASK) != 0)
+ s.append("Alt+");
+ if ((modifiers & SHIFT_DOWN_MASK) != 0)
+ s.append("Shift+");
+ if ((modifiers & ALT_GRAPH_DOWN_MASK) != 0)
+ s.append("Alt Graph+");
+ if ((modifiers & BUTTON1_DOWN_MASK) != 0)
+ s.append("Button1+");
+ if ((modifiers & BUTTON2_DOWN_MASK) != 0)
+ s.append("Button2+");
+ if ((modifiers & BUTTON3_DOWN_MASK) != 0)
+ s.append("Button3+");
+ return s.substring(0, s.length() - 1);
+ }
+} // class InputEvent
diff --git a/libjava/classpath/java/awt/event/InputMethodEvent.java b/libjava/classpath/java/awt/event/InputMethodEvent.java
new file mode 100644
index 0000000..f6711a8
--- /dev/null
+++ b/libjava/classpath/java/awt/event/InputMethodEvent.java
@@ -0,0 +1,303 @@
+/* InputMethodEvent.java -- events from a text input method
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.font.TextHitInfo;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * This class is for event generated by change in a text input method.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see InputMethodListener
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public class InputMethodEvent extends AWTEvent
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 4727190874778922661L;
+
+ /** This is the first id in the range of event ids used by this class. */
+ public static final int INPUT_METHOD_FIRST = 1100;
+
+ /** This event id indicates that the text in the input method has changed. */
+ public static final int INPUT_METHOD_TEXT_CHANGED = 1100;
+
+ /** This event id indicates that the input method curor point has changed. */
+ public static final int CARET_POSITION_CHANGED = 1101;
+
+ /** This is the last id in the range of event ids used by this class. */
+ public static final int INPUT_METHOD_LAST = 1101;
+
+ /**
+ * The timestamp when this event was created.
+ *
+ * @serial the timestamp
+ * @since 1.4
+ */
+ private long when;
+
+ /** The input method text. */
+ private final transient AttributedCharacterIterator text;
+
+ /** The number of committed characters in the text. */
+ private final transient int committedCharacterCount;
+
+ /** The caret. */
+ private final transient TextHitInfo caret;
+
+ /** The most important position to be visible. */
+ private final transient TextHitInfo visiblePosition;
+
+ /**
+ * Initializes a new instance of <code>InputMethodEvent</code> with the
+ * specified source, id, timestamp, text, char count, caret, and visible
+ * position.
+ *
+ * @param source the source that generated the event
+ * @param id the event id
+ * @param when the timestamp of the event
+ * @param text the input text
+ * @param committedCharacterCount the number of committed characters
+ * @param caret the caret position
+ * @param visiblePosition the position most important to make visible
+ * @throws IllegalArgumentException if source is null, id is invalid, id is
+ * CARET_POSITION_CHANGED and text is non-null, or if
+ * committedCharacterCount is out of range
+ * @since 1.4
+ */
+ public InputMethodEvent(Component source, int id, long when,
+ AttributedCharacterIterator text,
+ int committedCharacterCount, TextHitInfo caret,
+ TextHitInfo visiblePosition)
+ {
+ super(source, id);
+ this.when = when;
+ this.text = text;
+ this.committedCharacterCount = committedCharacterCount;
+ this.caret = caret;
+ this.visiblePosition = visiblePosition;
+ if (id < INPUT_METHOD_FIRST || id > INPUT_METHOD_LAST
+ || (id == CARET_POSITION_CHANGED && text != null)
+ || committedCharacterCount < 0
+ || (committedCharacterCount
+ > (text == null ? 0 : text.getEndIndex() - text.getBeginIndex())))
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Initializes a new instance of <code>InputMethodEvent</code> with the
+ * specified source, id, text, char count, caret, and visible position.
+ *
+ * @param source the source that generated the event
+ * @param id the event id
+ * @param text the input text
+ * @param committedCharacterCount the number of committed characters
+ * @param caret the caret position
+ * @param visiblePosition the position most important to make visible
+ * @throws IllegalArgumentException if source is null, id is invalid, id is
+ * CARET_POSITION_CHANGED and text is non-null, or if
+ * committedCharacterCount is out of range
+ * @since 1.4
+ */
+ public InputMethodEvent(Component source, int id,
+ AttributedCharacterIterator text,
+ int committedCharacterCount, TextHitInfo caret,
+ TextHitInfo visiblePosition)
+ {
+ this(source, id, EventQueue.getMostRecentEventTime(), text,
+ committedCharacterCount, caret, visiblePosition);
+ }
+
+ /**
+ * Initializes a new instance of <code>InputMethodEvent</code> with the
+ * specified source, id, caret, and visible position, and with a null
+ * text and char count.
+ *
+ * @param source the source that generated the event
+ * @param id the event id
+ * @param caret the caret position
+ * @param visiblePosition the position most important to make visible
+ * @throws IllegalArgumentException if source is null or id is invalid
+ * @since 1.4
+ */
+ public InputMethodEvent(Component source, int id, TextHitInfo caret,
+ TextHitInfo visiblePosition)
+ {
+ this(source, id, EventQueue.getMostRecentEventTime(), null, 0, caret,
+ visiblePosition);
+ }
+
+ /**
+ * This method returns the input method text. This can be <code>null</code>,
+ * and will always be null for <code>CARET_POSITION_CHANGED</code> events.
+ * Characters from 0 to <code>getCommittedCharacterCount()-1</code> have
+ * been committed, the remaining characters are composed text.
+ *
+ * @return the input method text, or null
+ */
+ public AttributedCharacterIterator getText()
+ {
+ return text;
+ }
+
+ /**
+ * Returns the number of committed characters in the input method text.
+ *
+ * @return the number of committed characters in the input method text
+ */
+ public int getCommittedCharacterCount()
+ {
+ return committedCharacterCount;
+ }
+
+ /**
+ * Returns the caret position. The caret offset is relative to the composed
+ * text of the most recent <code>INPUT_METHOD_TEXT_CHANGED</code> event.
+ *
+ * @return the caret position, or null
+ */
+ public TextHitInfo getCaret()
+ {
+ return caret;
+ }
+
+ /**
+ * Returns the position that is most important to be visible, or null if
+ * such a hint is not necessary. The caret offset is relative to the composed
+ * text of the most recent <code>INPUT_METHOD_TEXT_CHANGED</code> event.
+ *
+ * @return the position that is most important to be visible
+ */
+ public TextHitInfo getVisiblePosition()
+ {
+ return visiblePosition;
+ }
+
+ /**
+ * This method consumes the event. A consumed event is not processed
+ * in the default manner by the component that generated it.
+ */
+ public void consume()
+ {
+ consumed = true;
+ }
+
+ /**
+ * This method tests whether or not this event has been consumed.
+ *
+ * @return true if the event has been consumed
+ */
+ public boolean isConsumed()
+ {
+ return consumed;
+ }
+
+ /**
+ * Return the timestamp of this event.
+ *
+ * @return the timestamp
+ * @since 1.4
+ */
+ public long getWhen()
+ {
+ return when;
+ }
+
+ /**
+ * This method returns a string identifying the event. This contains the
+ * event ID, the committed and composed characters separated by '+', the
+ * number of committed characters, the caret, and the visible position.
+ *
+ * @return a string identifying the event
+ */
+ public String paramString()
+ {
+ StringBuffer s
+ = new StringBuffer(80 + (text == null ? 0
+ : text.getEndIndex() - text.getBeginIndex()));
+ s.append(id == INPUT_METHOD_TEXT_CHANGED ? "INPUT_METHOD_TEXT_CHANGED, "
+ : "CARET_POSITION_CHANGED, ");
+ if (text == null)
+ s.append("no text, 0 characters committed, caret: ");
+ else
+ {
+ s.append('"');
+ int i = text.getBeginIndex();
+ int j = committedCharacterCount;
+ while (--j >= 0)
+ s.append(text.setIndex(i++));
+ s.append("\" + \"");
+ j = text.getEndIndex() - i;
+ while (--j >= 0)
+ s.append(text.setIndex(i++));
+ s.append("\", ").append(committedCharacterCount)
+ .append(" characters committed, caret: ");
+ }
+ s.append(caret == null ? (Object) "no caret" : caret).append(", ")
+ .append(visiblePosition == null ? (Object) "no visible position"
+ : visiblePosition);
+ return s.toString();
+ }
+
+ /**
+ * Reads in the object from a serial stream, updating when to
+ * {@link EventQueue#getMostRecentEventTime()} if necessary.
+ *
+ * @param s the stream to read from
+ * @throws IOException if deserialization fails
+ * @throws ClassNotFoundException if deserialization fails
+ * @serialData default, except for updating when
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ if (when == 0)
+ when = EventQueue.getMostRecentEventTime();
+ }
+} // class InputMethodEvent
diff --git a/libjava/classpath/java/awt/event/InputMethodListener.java b/libjava/classpath/java/awt/event/InputMethodListener.java
new file mode 100644
index 0000000..e2f6a4e
--- /dev/null
+++ b/libjava/classpath/java/awt/event/InputMethodListener.java
@@ -0,0 +1,70 @@
+/* InputMethodListener.java -- listen for input method events
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.im.InputMethodRequests;
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to receive events from an input
+ * method. For a text component to use input methods, it must also install
+ * an InputMethodRequests handler.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see InputMethodEvent
+ * @see InputMethodRequests
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface InputMethodListener extends EventListener
+{
+ /**
+ * This method is called when the text is changed.
+ *
+ * @param event the <code>InputMethodEvent</code> indicating the text change
+ */
+ void inputMethodTextChanged(InputMethodEvent event);
+
+ /**
+ * This method is called when the cursor position within the text is changed.
+ *
+ * @param event the <code>InputMethodEvent</code> indicating the change
+ */
+ void caretPositionChanged(InputMethodEvent event);
+} // interface InputMethodListener
diff --git a/libjava/classpath/java/awt/event/InvocationEvent.java b/libjava/classpath/java/awt/event/InvocationEvent.java
new file mode 100644
index 0000000..75feb62
--- /dev/null
+++ b/libjava/classpath/java/awt/event/InvocationEvent.java
@@ -0,0 +1,237 @@
+/* InvocationEvent.java -- call a runnable when dispatched
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
+import java.awt.EventQueue;
+
+/**
+ * This event executes {@link Runnable#run()} of a target object when it is
+ * dispatched. This class is used by calls to <code>invokeLater</code> and
+ * <code>invokeAndWait</code>, so client code can use this fact to avoid
+ * writing special-casing AWTEventListener objects.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ActiveEvent
+ * @see EventQueue#invokeLater(Runnable)
+ * @see EventQueue#invokeAndWait(Runnable)
+ * @see AWTEventListener
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public class InvocationEvent extends AWTEvent implements ActiveEvent
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 436056344909459450L;
+
+ /** This is the first id in the range of event ids used by this class. */
+ public static final int INVOCATION_FIRST = 1200;
+
+ /** This is the default id for this event type. */
+ public static final int INVOCATION_DEFAULT = 1200;
+
+ /** This is the last id in the range of event ids used by this class. */
+ public static final int INVOCATION_LAST = 1200;
+
+ /**
+ * This is the <code>Runnable</code> object to call when dispatched.
+ *
+ * @serial the runnable to execute
+ */
+ protected Runnable runnable;
+
+ /**
+ * This is the object to call <code>notifyAll()</code> on when
+ * the call to <code>run()</code> returns, or <code>null</code> if no
+ * object is to be notified.
+ *
+ * @serial the object to notify
+ */
+ protected Object notifier;
+
+ /**
+ * This variable is set to <code>true</code> if exceptions are caught
+ * and stored in a variable during the call to <code>run()</code>, otherwise
+ * exceptions are ignored and propagate up.
+ *
+ * @serial true to catch exceptions
+ */
+ protected boolean catchExceptions;
+
+ /**
+ * This is the caught exception thrown in the <code>run()</code> method. It
+ * is null if exceptions are ignored, the run method hasn't completed, or
+ * there were no exceptions.
+ *
+ * @serial the caught exception, if any
+ */
+ private Exception exception;
+
+ /**
+ * The timestamp when this event was created.
+ *
+ * @see #getWhen()
+ * @serial the timestamp
+ * @since 1.4
+ */
+ private final long when = EventQueue.getMostRecentEventTime();
+
+ /**
+ * Initializes a new instance of <code>InvocationEvent</code> with the
+ * specified source and runnable.
+ *
+ * @param source the source of the event
+ * @param runnable the <code>Runnable</code> object to invoke
+ * @throws IllegalArgumentException if source is null
+ */
+ public InvocationEvent(Object source, Runnable runnable)
+ {
+ this(source, INVOCATION_DEFAULT, runnable, null, false);
+ }
+
+ /**
+ * Initializes a new instance of <code>InvocationEvent</code> with the
+ * specified source, runnable, and notifier. It will also catch exceptions
+ * if specified. If notifier is non-null, this will call notifyAll() on
+ * the object when the runnable is complete. If catchExceptions is true,
+ * this traps any exception in the runnable, otherwise it lets the exception
+ * propagate up the Event Dispatch thread.
+ *
+ * @param source the source of the event
+ * @param runnable the <code>Runnable</code> object to invoke
+ * @param notifier the object to notify, or null
+ * @param catchExceptions true to catch exceptions from the runnable
+ */
+ public InvocationEvent(Object source, Runnable runnable, Object notifier,
+ boolean catchExceptions)
+ {
+ this(source, INVOCATION_DEFAULT, runnable, notifier, catchExceptions);
+ }
+
+ /**
+ * Initializes a new instance of <code>InvocationEvent</code> with the
+ * specified source, runnable, and notifier. It will also catch exceptions
+ * if specified. If notifier is non-null, this will call notifyAll() on
+ * the object when the runnable is complete. If catchExceptions is true,
+ * this traps any exception in the runnable, otherwise it lets the exception
+ * propagate up the Event Dispatch thread. Note that an invalid id leads to
+ * unspecified results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @param runnable the <code>Runnable</code> object to invoke
+ * @param notifier the object to notify, or null
+ * @param catchExceptions true to catch exceptions from the runnable
+ */
+ protected InvocationEvent(Object source, int id, Runnable runnable,
+ Object notifier, boolean catchExceptions)
+ {
+ super(source, id);
+ this.runnable = runnable;
+ this.notifier = notifier;
+ this.catchExceptions = catchExceptions;
+ }
+
+ /**
+ * This method calls the <code>run()</code> method of the runnable, traps
+ * exceptions if instructed to do so, and calls <code>notifyAll()</code>
+ * on any notifier if all worked successfully.
+ */
+ public void dispatch()
+ {
+ if (catchExceptions)
+ try
+ {
+ runnable.run();
+ }
+ catch (Exception e)
+ {
+ exception = e;
+ }
+ else
+ runnable.run();
+
+ Object o = notifier;
+ if (o != null)
+ synchronized(o)
+ {
+ o.notifyAll();
+ }
+ }
+
+ /**
+ * This method returns the exception that occurred during the execution of
+ * the runnable, or <code>null</code> if not exception was thrown or
+ * exceptions were not caught.
+ *
+ * @return the exception thrown by the runnable
+ */
+ public Exception getException()
+ {
+ return exception;
+ }
+
+ /**
+ * Gets the timestamp of when this event was created.
+ *
+ * @return the timestamp of this event
+ * @since 1.4
+ */
+ public long getWhen()
+ {
+ return when;
+ }
+
+ /**
+ * This method returns a string identifying this event. This is formatted as:
+ * <code>"INVOCATION_DEFAULT,runnable=" + runnable + ",notifier=" + notifier
+ * + ",catchExceptions=" + catchExceptions + ",when=" + getWhen()</code>.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ return (id == INVOCATION_DEFAULT ? "INVOCATION_DEFAULT,runnable="
+ : "unknown type,runnable=") + runnable + ",notifier=" + notifier
+ + ",catchExceptions=" + catchExceptions + ",when=" + when;
+ }
+} // class InvocationEvent
diff --git a/libjava/classpath/java/awt/event/ItemEvent.java b/libjava/classpath/java/awt/event/ItemEvent.java
new file mode 100644
index 0000000..467815b
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ItemEvent.java
@@ -0,0 +1,155 @@
+/* ItemEvent.java -- event for item state changes
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ItemSelectable;
+
+/**
+ * This event is generated when a selection item changes state. This is an
+ * abstraction that distills a large number of individual mouse or keyboard
+ * events into a simpler "item selected" and "item deselected" events.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ItemSelectable
+ * @see ItemListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class ItemEvent extends AWTEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -608708132447206933L;
+
+ /** This is the first id in the event id range used by this class. */
+ public static final int ITEM_FIRST = 701;
+
+ /** This is the last id in the event id range used by this class. */
+ public static final int ITEM_LAST = 701;
+
+ /** This event id indicates a state change occurred. */
+ public static final int ITEM_STATE_CHANGED = 701;
+
+ /** This type indicates that the item was selected. */
+ public static final int SELECTED = 1;
+
+ /** This type indicates that the item was deselected. */
+ public static final int DESELECTED = 2;
+
+ /**
+ * The item affected by this event.
+ *
+ * @serial the item of the selection
+ */
+ private final Object item;
+
+ /**
+ * The state change direction, one of {@link #SELECTED} or
+ * {@link #DESELECTED}.
+ *
+ * @serial the selection state
+ */
+ private final int stateChange;
+
+ /**
+ * Initializes a new instance of <code>ItemEvent</code> with the specified
+ * source, id, and state change constant. Note that an invalid id leads to
+ * unspecified results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @param item the item affected by the state change
+ * @param stateChange one of {@link #SELECTED} or {@link #DESELECTED}
+ */
+ public ItemEvent(ItemSelectable source, int id, Object item, int stateChange)
+ {
+ super(source, id);
+ this.item = item;
+ this.stateChange = stateChange;
+ }
+
+ /**
+ * This method returns the event source as an <code>ItemSelectable</code>.
+ *
+ * @return the event source as an <code>ItemSelected</code>
+ * @throws ClassCastException if source is changed to a non-ItemSelectable
+ */
+ public ItemSelectable getItemSelectable()
+ {
+ return (ItemSelectable) source;
+ }
+
+ /**
+ * Returns the item affected by this state change.
+ *
+ * @return the item affected by this state change
+ */
+ public Object getItem()
+ {
+ return item;
+ }
+
+ /**
+ * Returns the type of state change, either {@link #SELECTED} or
+ * {@link #DESELECTED}.
+ *
+ * @return the type of state change
+ */
+ public int getStateChange()
+ {
+ return stateChange;
+ }
+
+ /**
+ * Returns a string identifying this event. This is in the format:
+ * <code>"ITEM_STATE_CHANGED,item=" + item + ",stateChange="
+ * + (getStateChange() == DESELECTED ? "DESELECTED" : "SELECTED")</code>.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ return (id == ITEM_STATE_CHANGED ? "ITEM_STATE_CHANGED,item="
+ : "unknown type,item=") + item + ",stateChange="
+ + (stateChange == SELECTED ? "SELECTED"
+ : stateChange == DESELECTED ? "DESELECTED" : "unknown type");
+ }
+} // class ItemEvent
diff --git a/libjava/classpath/java/awt/event/ItemListener.java b/libjava/classpath/java/awt/event/ItemListener.java
new file mode 100644
index 0000000..fa5f3aa
--- /dev/null
+++ b/libjava/classpath/java/awt/event/ItemListener.java
@@ -0,0 +1,62 @@
+/* ItemListener.java -- listen for item events
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.ItemSelectable;
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to receive events when an
+ * item's selection state changes.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ItemSelectable
+ * @see ItemEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface ItemListener extends EventListener
+{
+ /**
+ * This method is called when an item's state is changed.
+ *
+ * @param event the <code>ItemEvent</code> indicating the change
+ */
+ void itemStateChanged(ItemEvent event);
+} // interface ItemListener
diff --git a/libjava/classpath/java/awt/event/KeyAdapter.java b/libjava/classpath/java/awt/event/KeyAdapter.java
new file mode 100644
index 0000000..c01d61f
--- /dev/null
+++ b/libjava/classpath/java/awt/event/KeyAdapter.java
@@ -0,0 +1,88 @@
+/* KeyAdapter.java -- convenience class for writing key listeners
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+/**
+ * This class implements <code>KeyListener</code> and implements all methods
+ * with empty bodies. This allows a listener interested in implementing only
+ * a subset of the <code>KeyListener</code> interface to extend this class
+ * and override only the desired methods.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see KeyEvent
+ * @see KeyListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class KeyAdapter implements KeyListener
+{
+ /**
+ * Do nothing default constructor for subclasses.
+ */
+ public KeyAdapter()
+ {
+ }
+
+ /**
+ * Implements this method in the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void keyTyped(KeyEvent event)
+ {
+ }
+
+ /**
+ * Implements this method in the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void keyPressed(KeyEvent event)
+ {
+ }
+
+ /**
+ * Implements this method in the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void keyReleased(KeyEvent event)
+ {
+ }
+} // class KeyAdapter
diff --git a/libjava/classpath/java/awt/event/KeyEvent.java b/libjava/classpath/java/awt/event/KeyEvent.java
new file mode 100644
index 0000000..a40a8e1
--- /dev/null
+++ b/libjava/classpath/java/awt/event/KeyEvent.java
@@ -0,0 +1,1740 @@
+/* KeyEvent.java -- event for key presses
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import gnu.java.awt.EventModifier;
+
+import java.awt.Component;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * This event is generated when a key is pressed or released. There are two
+ * categories of key events:
+ *
+ * <p><em>"Key typed" events</em> are higher-level, and have already
+ * compensated for modifiers and keyboard layout to generate a single Unicode
+ * character. It may take several key press events to generate one key typed.
+ * The <code>getKeyCode</code> method will return <code>VK_UNDEFINED</code>,
+ * and <code>getKeyChar</code> will return a valid Unicode character or
+ * <code>CHAR_UNDEFINED</code>.
+ *
+ * <p><em>"Key pressed" and "key released" events</em> are lower-level, and
+ * are platform and keyboard dependent. They correspond to the actaul motion
+ * on a keyboard, and return a virtual key code which labels the key that was
+ * pressed. The <code>getKeyCode</code> method will return one of the
+ * <code>VK_*</code> constants (except VK_UNDEFINED), and the
+ * <code>getKeyChar</code> method is undefined.
+ *
+ * <p>Some keys do not generate key typed events, such as the F1 or HELP keys.
+ * Not all keyboards can generate all virtual keys, and no attempt is made to
+ * simulate the ones that can't be typed. Virtual keys correspond to the
+ * keyboard layout, so for example, VK_Q in English is VK_A in French. Also,
+ * there are some additional virtual keys to ease handling of actions, such
+ * as VK_ALL_CANDIDATES in place of ALT+VK_CONVERT. Do not rely on the value
+ * of the VK_* constants, except for VK_ENTER, VK_BACK_SPACE, and VK_TAB.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see KeyAdapter
+ * @see KeyListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class KeyEvent extends InputEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -2352130953028126954L;
+
+ /** This is the first id in the range of event ids used by this class. */
+ public static final int KEY_FIRST = 400;
+
+ /** This is the last id in the range of event ids used by this class. */
+ public static final int KEY_LAST = 402;
+
+ /**
+ * This event id indicates a key was typed, which is a key press followed
+ * by a key release to generate an actual Unicode character. It may take
+ * several key presses to generate one key typed event, and some action
+ * keys have no corresponding key typed.
+ */
+ public static final int KEY_TYPED = 400;
+
+ /** This event id indicates a key was pressed. */
+ public static final int KEY_PRESSED = 401;
+
+ /** This event it indicates a key was released. */
+ public static final int KEY_RELEASED = 402;
+
+ /** The virtual key Enter, which will always map to '\n'. */
+ public static final int VK_ENTER = '\n';
+
+ /** The virtual key Backspace, which will always map to '\b'. */
+ public static final int VK_BACK_SPACE = '\b';
+
+ /** The virtual key Tab, which will always map to '\t'. */
+ public static final int VK_TAB = '\t';
+
+ /** The virtual key Cancel. */
+ public static final int VK_CANCEL = 3;
+
+ /** The virtual key VK_CLEAR. */
+ public static final int VK_CLEAR = 12;
+
+ /** The virtual key VK_SHIFT. */
+ public static final int VK_SHIFT = 16;
+
+ /** The virtual key VK_CONTROL. */
+ public static final int VK_CONTROL = 17;
+
+ /** The virtual key VK_ALT. */
+ public static final int VK_ALT = 18;
+
+ /** The virtual key VK_PAUSE. */
+ public static final int VK_PAUSE = 19;
+
+ /** The virtual key VK_CAPS_LOCK. */
+ public static final int VK_CAPS_LOCK = 20;
+
+ /** The virtual key VK_ESCAPE. */
+ public static final int VK_ESCAPE = 27;
+
+ /** The virtual key VK_SPACE. */
+ public static final int VK_SPACE = ' ';
+
+ /** The virtual key VK_PAGE_UP. */
+ public static final int VK_PAGE_UP = 33;
+
+ /** The virtual key VK_PAGE_DOWN. */
+ public static final int VK_PAGE_DOWN = 34;
+
+ /** The virtual key VK_END. */
+ public static final int VK_END = 35;
+
+ /** The virtual key VK_HOME. */
+ public static final int VK_HOME = 36;
+
+ /**
+ * The virtual key for the non-numpad VK_LEFT.
+ *
+ * @see #VK_KP_LEFT
+ */
+ public static final int VK_LEFT = 37;
+
+ /**
+ * The virtual key for the non-numpad VK_UP.
+ *
+ * @see #VK_KP_UP
+ */
+ public static final int VK_UP = 38;
+
+ /**
+ * The virtual key for the non-numpad VK_RIGHT.
+ *
+ * @see #VK_KP_RIGHT
+ */
+ public static final int VK_RIGHT = 39;
+
+ /**
+ * The virtual key for the non-numpad VK_DOWN.
+ *
+ * @see #VK_KP_DOWN
+ */
+ public static final int VK_DOWN = 40;
+
+ /** The virtual key VK_COMMA. */
+ public static final int VK_COMMA = ',';
+
+ /**
+ * The virtual key VK_MINUS.
+ *
+ * @since 1.2
+ */
+ public static final int VK_MINUS = '-';
+
+ /** The virtual key VK_PERIOD. */
+ public static final int VK_PERIOD = '.';
+
+ /** The virtual key VK_SLASH. */
+ public static final int VK_SLASH = '/';
+
+ /** The virtual key VK_0. */
+ public static final int VK_0 = '0';
+
+ /** The virtual key VK_1. */
+ public static final int VK_1 = '1';
+
+ /** The virtual key VK_2. */
+ public static final int VK_2 = '2';
+
+ /** The virtual key VK_3. */
+ public static final int VK_3 = '3';
+
+ /** The virtual key VK_4. */
+ public static final int VK_4 = '4';
+
+ /** The virtual key VK_5. */
+ public static final int VK_5 = '5';
+
+ /** The virtual key VK_6. */
+ public static final int VK_6 = '6';
+
+ /** The virtual key VK_7. */
+ public static final int VK_7 = '7';
+
+ /** The virtual key VK_8. */
+ public static final int VK_8 = '8';
+
+ /** The virtual key VK_9. */
+ public static final int VK_9 = '9';
+
+ /** The virtual key VK_SEMICOLON. */
+ public static final int VK_SEMICOLON = ';';
+
+ /** The virtual key VK_EQUALS. */
+ public static final int VK_EQUALS = '=';
+
+ /** The virtual key VK_A. */
+ public static final int VK_A = 'A';
+
+ /** The virtual key VK_B. */
+ public static final int VK_B = 'B';
+
+ /** The virtual key VK_C. */
+ public static final int VK_C = 'C';
+
+ /** The virtual key VK_D. */
+ public static final int VK_D = 'D';
+
+ /** The virtual key VK_E. */
+ public static final int VK_E = 'E';
+
+ /** The virtual key VK_F. */
+ public static final int VK_F = 'F';
+
+ /** The virtual key VK_G. */
+ public static final int VK_G = 'G';
+
+ /** The virtual key VK_H. */
+ public static final int VK_H = 'H';
+
+ /** The virtual key VK_I. */
+ public static final int VK_I = 'I';
+
+ /** The virtual key VK_J. */
+ public static final int VK_J = 'J';
+
+ /** The virtual key VK_K. */
+ public static final int VK_K = 'K';
+
+ /** The virtual key VK_L. */
+ public static final int VK_L = 'L';
+
+ /** The virtual key VK_M. */
+ public static final int VK_M = 'M';
+
+ /** The virtual key VK_N. */
+ public static final int VK_N = 'N';
+
+ /** The virtual key VK_O. */
+ public static final int VK_O = 'O';
+
+ /** The virtual key VK_P. */
+ public static final int VK_P = 'P';
+
+ /** The virtual key VK_Q. */
+ public static final int VK_Q = 'Q';
+
+ /** The virtual key VK_R. */
+ public static final int VK_R = 'R';
+
+ /** The virtual key VK_S. */
+ public static final int VK_S = 'S';
+
+ /** The virtual key VK_T. */
+ public static final int VK_T = 'T';
+
+ /** The virtual key VK_U. */
+ public static final int VK_U = 'U';
+
+ /** The virtual key VK_V. */
+ public static final int VK_V = 'V';
+
+ /** The virtual key VK_W. */
+ public static final int VK_W = 'W';
+
+ /** The virtual key VK_X. */
+ public static final int VK_X = 'X';
+
+ /** The virtual key VK_Y. */
+ public static final int VK_Y = 'Y';
+
+ /** The virtual key VK_Z. */
+ public static final int VK_Z = 'Z';
+
+ /** The virtual key VK_OPEN_BRACKET. */
+ public static final int VK_OPEN_BRACKET = '[';
+
+ /** The virtual key VK_BACK_SLASH. */
+ public static final int VK_BACK_SLASH = '\\';
+
+ /** The virtual key VK_CLOSE_BRACKET. */
+ public static final int VK_CLOSE_BRACKET = ']';
+
+ /** The virtual key VK_NUMPAD0. */
+ public static final int VK_NUMPAD0 = 96;
+
+ /** The virtual key VK_NUMPAD1. */
+ public static final int VK_NUMPAD1 = 97;
+
+ /** The virtual key VK_NUMPAD2. */
+ public static final int VK_NUMPAD2 = 98;
+
+ /** The virtual key VK_NUMPAD3. */
+ public static final int VK_NUMPAD3 = 99;
+
+ /** The virtual key VK_NUMPAD4. */
+ public static final int VK_NUMPAD4 = 100;
+
+ /** The virtual key VK_NUMPAD5. */
+ public static final int VK_NUMPAD5 = 101;
+
+ /** The virtual key VK_NUMPAD6. */
+ public static final int VK_NUMPAD6 = 102;
+
+ /** The virtual key VK_NUMPAD7. */
+ public static final int VK_NUMPAD7 = 103;
+
+ /** The virtual key VK_NUMPAD8. */
+ public static final int VK_NUMPAD8 = 104;
+
+ /** The virtual key VK_NUMPAD9. */
+ public static final int VK_NUMPAD9 = 105;
+
+ /** The virtual key VK_MULTIPLY. */
+ public static final int VK_MULTIPLY = 106;
+
+ /** The virtual key VK_ADD. */
+ public static final int VK_ADD = 107;
+
+ /**
+ * The virtual key VK_SEPARATOR, handily mispelled for those who can't
+ * figure it out.
+ *
+ * @deprecated use {@link #VK_SEPARATOR}
+ */
+ public static final int VK_SEPARATER = 108;
+
+ /**
+ * The virtual key VK_SEPARATOR.
+ *
+ * @since 1.4
+ */
+ public static final int VK_SEPARATOR = 108;
+
+ /** The virtual key VK_SUBTRACT. */
+ public static final int VK_SUBTRACT = 109;
+
+ /** The virtual key VK_DECIMAL. */
+ public static final int VK_DECIMAL = 110;
+
+ /** The virtual key VK_DIVIDE. */
+ public static final int VK_DIVIDE = 111;
+
+ /** The virtual key VK_DELETE. */
+ public static final int VK_DELETE = 127;
+
+ /** The virtual key VK_NUM_LOCK. */
+ public static final int VK_NUM_LOCK = 144;
+
+ /** The virtual key VK_SCROLL_LOCK. */
+ public static final int VK_SCROLL_LOCK = 145;
+
+ /** The virtual key VK_F1. */
+ public static final int VK_F1 = 112;
+
+ /** The virtual key VK_F2. */
+ public static final int VK_F2 = 113;
+
+ /** The virtual key VK_F3. */
+ public static final int VK_F3 = 114;
+
+ /** The virtual key VK_F4. */
+ public static final int VK_F4 = 115;
+
+ /** The virtual key VK_F5. */
+ public static final int VK_F5 = 116;
+
+ /** The virtual key VK_F6. */
+ public static final int VK_F6 = 117;
+
+ /** The virtual key VK_F7. */
+ public static final int VK_F7 = 118;
+
+ /** The virtual key VK_F8. */
+ public static final int VK_F8 = 119;
+
+ /** The virtual key VK_F9. */
+ public static final int VK_F9 = 120;
+
+ /** The virtual key VK_F10. */
+ public static final int VK_F10 = 121;
+
+ /** The virtual key VK_F11. */
+ public static final int VK_F11 = 122;
+
+ /** The virtual key VK_F12. */
+ public static final int VK_F12 = 123;
+
+ /**
+ * The virtual key VK_F13.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F13 = 61440;
+
+ /**
+ * The virtual key VK_F14.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F14 = 61441;
+
+ /**
+ * The virtual key VK_F15.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F15 = 61442;
+
+ /**
+ * The virtual key VK_F16.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F16 = 61443;
+
+ /**
+ * The virtual key VK_F17.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F17 = 61444;
+
+ /**
+ * The virtual key VK_F18.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F18 = 61445;
+
+ /**
+ * The virtual key VK_F19.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F19 = 61446;
+
+ /**
+ * The virtual key VK_F20.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F20 = 61447;
+
+ /**
+ * The virtual key VK_F21.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F21 = 61448;
+
+ /**
+ * The virtual key VK_F22.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F22 = 61449;
+
+ /**
+ * The virtual key VK_F23.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F23 = 61450;
+
+ /**
+ * The virtual key VK_F24.
+ *
+ * @since 1.2
+ */
+ public static final int VK_F24 = 61451;
+
+ /** The virtual key VK_PRINTSCREEN. */
+ public static final int VK_PRINTSCREEN = 154;
+
+ /** The virtual key VK_INSERT. */
+ public static final int VK_INSERT = 155;
+
+ /** The virtual key VK_HELP. */
+ public static final int VK_HELP = 156;
+
+ /** The virtual key VK_META. */
+ public static final int VK_META = 157;
+
+ /** The virtual key VK_BACK_QUOTE. */
+ public static final int VK_BACK_QUOTE = 192;
+
+ /** The virtual key VK_QUOTE. */
+ public static final int VK_QUOTE = 222;
+
+ /**
+ * The virtual key for the numpad VK_KP_UP.
+ *
+ * @see #VK_UP
+ * @since 1.2
+ */
+ public static final int VK_KP_UP = 224;
+
+ /**
+ * The virtual key for the numpad VK_KP_DOWN.
+ *
+ * @see #VK_DOWN
+ * @since 1.2
+ */
+ public static final int VK_KP_DOWN = 225;
+
+ /**
+ * The virtual key for the numpad VK_KP_LEFT.
+ *
+ * @see #VK_LEFT
+ * @since 1.2
+ */
+ public static final int VK_KP_LEFT = 226;
+
+ /**
+ * The virtual key for the numpad VK_KP_RIGHT.
+ *
+ * @see #VK_RIGHT
+ * @since 1.2
+ */
+ public static final int VK_KP_RIGHT = 227;
+
+ /**
+ * The virtual key VK_DEAD_GRAVE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_GRAVE = 128;
+
+ /**
+ * The virtual key VK_DEAD_ACUTE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_ACUTE = 129;
+
+ /**
+ * The virtual key VK_DEAD_CIRCUMFLEX.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_CIRCUMFLEX = 130;
+
+ /**
+ * The virtual key VK_DEAD_TILDE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_TILDE = 131;
+
+ /**
+ * The virtual key VK_DEAD_MACRON.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_MACRON = 132;
+
+ /**
+ * The virtual key VK_DEAD_BREVE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_BREVE = 133;
+
+ /**
+ * The virtual key VK_DEAD_ABOVEDOT.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_ABOVEDOT = 134;
+
+ /**
+ * The virtual key VK_DEAD_DIAERESIS.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_DIAERESIS = 135;
+
+ /**
+ * The virtual key VK_DEAD_ABOVERING.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_ABOVERING = 136;
+
+ /**
+ * The virtual key VK_DEAD_DOUBLEACUTE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_DOUBLEACUTE = 137;
+
+ /**
+ * The virtual key VK_DEAD_CARON.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_CARON = 138;
+
+ /**
+ * The virtual key VK_DEAD_CEDILLA.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_CEDILLA = 139;
+
+ /**
+ * The virtual key VK_DEAD_OGONEK.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_OGONEK = 140;
+
+ /**
+ * The virtual key VK_DEAD_IOTA.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_IOTA = 141;
+
+ /**
+ * The virtual key VK_DEAD_VOICED_SOUND.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_VOICED_SOUND = 142;
+
+ /**
+ * The virtual key VK_DEAD_SEMIVOICED_SOUND.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DEAD_SEMIVOICED_SOUND = 143;
+
+ /**
+ * The virtual key VK_AMPERSAND.
+ *
+ * @since 1.2
+ */
+ public static final int VK_AMPERSAND = 150;
+
+ /**
+ * The virtual key VK_ASTERISK.
+ *
+ * @since 1.2
+ */
+ public static final int VK_ASTERISK = 151;
+
+ /**
+ * The virtual key VK_QUOTEDBL.
+ *
+ * @since 1.2
+ */
+ public static final int VK_QUOTEDBL = 152;
+
+ /**
+ * The virtual key VK_LESS.
+ *
+ * @since 1.2
+ */
+ public static final int VK_LESS = 153;
+
+ /**
+ * The virtual key VK_GREATER.
+ *
+ * @since 1.2
+ */
+ public static final int VK_GREATER = 160;
+
+ /**
+ * The virtual key VK_BRACELEFT.
+ *
+ * @since 1.2
+ */
+ public static final int VK_BRACELEFT = 161;
+
+ /**
+ * The virtual key VK_BRACERIGHT.
+ *
+ * @since 1.2
+ */
+ public static final int VK_BRACERIGHT = 162;
+
+ /**
+ * The virtual key VK_AT.
+ *
+ * @since 1.2
+ */
+ public static final int VK_AT = 512;
+
+ /**
+ * The virtual key VK_COLON.
+ *
+ * @since 1.2
+ */
+ public static final int VK_COLON = 513;
+
+ /**
+ * The virtual key VK_CIRCUMFLEX.
+ *
+ * @since 1.2
+ */
+ public static final int VK_CIRCUMFLEX = 514;
+
+ /**
+ * The virtual key VK_DOLLAR.
+ *
+ * @since 1.2
+ */
+ public static final int VK_DOLLAR = 515;
+
+ /**
+ * The virtual key VK_EURO_SIGN.
+ *
+ * @since 1.2
+ */
+ public static final int VK_EURO_SIGN = 516;
+
+ /**
+ * The virtual key VK_EXCLAMATION_MARK.
+ *
+ * @since 1.2
+ */
+ public static final int VK_EXCLAMATION_MARK = 517;
+
+ /**
+ * The virtual key VK_INVERTED_EXCLAMATION_MARK.
+ *
+ * @since 1.2
+ */
+ public static final int VK_INVERTED_EXCLAMATION_MARK = 518;
+
+ /**
+ * The virtual key VK_LEFT_PARENTHESIS.
+ *
+ * @since 1.2
+ */
+ public static final int VK_LEFT_PARENTHESIS = 519;
+
+ /**
+ * The virtual key VK_NUMBER_SIGN.
+ *
+ * @since 1.2
+ */
+ public static final int VK_NUMBER_SIGN = 520;
+
+ /**
+ * The virtual key VK_PLUS.
+ *
+ * @since 1.2
+ */
+ public static final int VK_PLUS = 521;
+
+ /**
+ * The virtual key VK_RIGHT_PARENTHESIS.
+ *
+ * @since 1.2
+ */
+ public static final int VK_RIGHT_PARENTHESIS = 522;
+
+ /**
+ * The virtual key VK_UNDERSCORE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_UNDERSCORE = 523;
+
+ /** The virtual key VK_FINAL. */
+ public static final int VK_FINAL = 24;
+
+ /** The virtual key VK_CONVERT. */
+ public static final int VK_CONVERT = 28;
+
+ /** The virtual key VK_NONCONVERT. */
+ public static final int VK_NONCONVERT = 29;
+
+ /** The virtual key VK_ACCEPT. */
+ public static final int VK_ACCEPT = 30;
+
+ /** The virtual key VK_MODECHANGE. */
+ public static final int VK_MODECHANGE = 31;
+
+ /** The virtual key VK_KANA. */
+ public static final int VK_KANA = 21;
+
+ /** The virtual key VK_KANJI. */
+ public static final int VK_KANJI = 25;
+
+ /**
+ * The virtual key VK_ALPHANUMERIC.
+ *
+ * @since 1.2
+ */
+ public static final int VK_ALPHANUMERIC = 240;
+
+ /**
+ * The virtual key VK_KATAKANA.
+ *
+ * @since 1.2
+ */
+ public static final int VK_KATAKANA = 241;
+
+ /**
+ * The virtual key VK_HIRAGANA.
+ *
+ * @since 1.2
+ */
+ public static final int VK_HIRAGANA = 242;
+
+ /**
+ * The virtual key VK_FULL_WIDTH.
+ *
+ * @since 1.2
+ */
+ public static final int VK_FULL_WIDTH = 243;
+
+ /**
+ * The virtual key VK_HALF_WIDTH.
+ *
+ * @since 1.2
+ */
+ public static final int VK_HALF_WIDTH = 244;
+
+ /**
+ * The virtual key VK_ROMAN_CHARACTERS.
+ *
+ * @since 1.2
+ */
+ public static final int VK_ROMAN_CHARACTERS = 245;
+
+ /**
+ * The virtual key VK_ALL_CANDIDATES.
+ *
+ * @since 1.2
+ */
+ public static final int VK_ALL_CANDIDATES = 256;
+
+ /**
+ * The virtual key VK_PREVIOUS_CANDIDATE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_PREVIOUS_CANDIDATE = 257;
+
+ /**
+ * The virtual key VK_CODE_INPUT.
+ *
+ * @since 1.2
+ */
+ public static final int VK_CODE_INPUT = 258;
+
+ /**
+ * The virtual key VK_JAPANESE_KATAKANA.
+ *
+ * @since 1.2
+ */
+ public static final int VK_JAPANESE_KATAKANA = 259;
+
+ /**
+ * The virtual key VK_JAPANESE_HIRAGANA.
+ *
+ * @since 1.2
+ */
+ public static final int VK_JAPANESE_HIRAGANA = 260;
+
+ /**
+ * The virtual key VK_JAPANESE_ROMAN.
+ *
+ * @since 1.2
+ */
+ public static final int VK_JAPANESE_ROMAN = 261;
+
+ /**
+ * The virtual key VK_KANA_LOCK.
+ *
+ * @since 1.3
+ */
+ public static final int VK_KANA_LOCK = 262;
+
+ /**
+ * The virtual key VK_INPUT_METHOD_ON_OFF.
+ *
+ * @since 1.3
+ */
+ public static final int VK_INPUT_METHOD_ON_OFF = 263;
+
+ /**
+ * The virtual key VK_CUT.
+ *
+ * @since 1.2
+ */
+ public static final int VK_CUT = 65489;
+
+ /**
+ * The virtual key VK_COPY.
+ *
+ * @since 1.2
+ */
+ public static final int VK_COPY = 65485;
+
+ /**
+ * The virtual key VK_PASTE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_PASTE = 65487;
+
+ /**
+ * The virtual key VK_UNDO.
+ *
+ * @since 1.2
+ */
+ public static final int VK_UNDO = 65483;
+
+ /**
+ * The virtual key VK_AGAIN.
+ *
+ * @since 1.2
+ */
+ public static final int VK_AGAIN = 65481;
+
+ /**
+ * The virtual key VK_FIND.
+ *
+ * @since 1.2
+ */
+ public static final int VK_FIND = 65488;
+
+ /**
+ * The virtual key VK_PROPS.
+ *
+ * @since 1.2
+ */
+ public static final int VK_PROPS = 65482;
+
+ /**
+ * The virtual key VK_STOP.
+ *
+ * @since 1.2
+ */
+ public static final int VK_STOP = 65480;
+
+ /**
+ * The virtual key VK_COMPOSE.
+ *
+ * @since 1.2
+ */
+ public static final int VK_COMPOSE = 65312;
+
+ /**
+ * The virtual key VK_ALT_GRAPH.
+ *
+ * @since 1.2
+ */
+ public static final int VK_ALT_GRAPH = 65406;
+
+ /**
+ * The virtual key VK_UNDEFINED. This is used for key typed events, which
+ * do not have a virtual key.
+ */
+ public static final int VK_UNDEFINED = 0;
+
+ /**
+ * The only char with no valid Unicode interpretation. This is used for
+ * key pressed and key released events which do not have a valid keyChar.
+ */
+ public static final char CHAR_UNDEFINED = '\uffff';
+
+ /**
+ * Indicates unknown or irrelavent key location. This is also used for
+ * key typed events, which do not need a location.
+ *
+ * @since 1.4
+ */
+ public static final int KEY_LOCATION_UNKNOWN = 0;
+
+ /**
+ * Indicates a standard key location, with no left/right variants and not
+ * on the numeric pad.
+ *
+ * @since 1.4
+ */
+ public static final int KEY_LOCATION_STANDARD = 1;
+
+ /**
+ * Indicates the key is on the left side of the keyboard, such as the left
+ * shift.
+ *
+ * @since 1.4
+ */
+ public static final int KEY_LOCATION_LEFT = 2;
+
+ /**
+ * Indicates the key is on the right side of the keyboard, such as the right
+ * shift.
+ *
+ * @since 1.4
+ */
+ public static final int KEY_LOCATION_RIGHT = 3;
+
+ /**
+ * Indicates the key is on the numeric pad, such as the numpad 0.
+ *
+ * @since 1.4
+ */
+ public static final int KEY_LOCATION_NUMPAD = 4;
+
+ /**
+ * The code assigned to the physical keyboard location (as adjusted by the
+ * keyboard layout). Use the symbolic VK_* names instead of numbers.
+ *
+ * @see #getKeyCode()
+ * @serial the VK_ code for this key
+ */
+ private int keyCode;
+
+ /**
+ * The Unicode character produced by the key type event. This has no meaning
+ * for key pressed and key released events.
+ *
+ * @see #getKeyChar()
+ * @serial the Unicode value for this key
+ */
+ private char keyChar;
+
+ /**
+ * The keyboard location of the key. One of {@link #KEY_LOCATION_UNKNOWN},
+ * {@link #KEY_LOCATION_STANDARD}, {@link #KEY_LOCATION_LEFT},
+ * {@link #KEY_LOCATION_RIGHT}, or {@link #KEY_LOCATION_NUMPAD}.
+ *
+ * @see #getKeyLocation()
+ * @serial the key location
+ * @since 1.4
+ */
+ private final int keyLocation;
+
+ /**
+ * Stores the state of the native event dispatching system, to correctly
+ * dispatch in Component#dispatchEventImpl when a proxy is active.
+ *
+ * XXX Does this matter in Classpath?
+ *
+ * @serial whether the proxy is active
+ */
+ private boolean isProxyActive;
+
+
+ /**
+ * Initializes a new instance of <code>KeyEvent</code> with the specified
+ * information. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the component that generated this event
+ * @param id the event id
+ * @param when the timestamp when the even occurred
+ * @param modifiers the modifier keys during the event, in old or new style
+ * @param keyCode the integer constant for the virtual key type
+ * @param keyChar the Unicode value of the key
+ * @param keyLocation the location of the key
+ * @throws IllegalArgumentException if source is null, if keyLocation is
+ * invalid, or if (id == KEY_TYPED && (keyCode != VK_UNDEFINED
+ * || keyChar == CHAR_UNDEFINED))
+ */
+ public KeyEvent(Component source, int id, long when, int modifiers,
+ int keyCode, char keyChar, int keyLocation)
+ {
+ super(source, id, when, modifiers);
+ this.keyCode = keyCode;
+ this.keyChar = keyChar;
+ this.keyLocation = keyLocation;
+ if ((id == KEY_TYPED && (keyCode != VK_UNDEFINED
+ || keyChar == CHAR_UNDEFINED))
+ || keyLocation < KEY_LOCATION_UNKNOWN
+ || keyLocation > KEY_LOCATION_NUMPAD)
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Initializes a new instance of <code>KeyEvent</code> with the specified
+ * information. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the component that generated this event
+ * @param id the event id
+ * @param when the timestamp when the even occurred
+ * @param modifiers the modifier keys during the event, in old or new style
+ * @param keyCode the integer constant for the virtual key type
+ * @param keyChar the Unicode value of the key
+ * @throws IllegalArgumentException if source is null, or if
+ * (id == KEY_TYPED && (keyCode != VK_UNDEFINED
+ * || keyChar == CHAR_UNDEFINED))
+ */
+ public KeyEvent(Component source, int id, long when, int modifiers,
+ int keyCode, char keyChar)
+ {
+ this(source, id, when, modifiers, keyCode, keyChar, KEY_LOCATION_UNKNOWN);
+ }
+
+ /**
+ * Initializes a new instance of <code>KeyEvent</code> with the specified
+ * information. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the component that generated this event
+ * @param id the event id
+ * @param when the timestamp when the even occurred
+ * @param modifiers the modifier keys during the event, in old or new style
+ * @param keyCode the integer constant for the virtual key type
+ * @throws IllegalArgumentException if source is null, or if
+ * id == KEY_TYPED but keyCode != VK_UNDEFINED
+ *
+ * @deprecated
+ */
+ public KeyEvent(Component source, int id, long when, int modifiers,
+ int keyCode)
+ {
+ this(source, id, when, modifiers, keyCode, '\0', KEY_LOCATION_UNKNOWN);
+ }
+
+ /**
+ * Returns the key code for the event key. This will be one of the
+ * <code>VK_*</code> constants defined in this class. If the event type is
+ * KEY_TYPED, the result will be VK_UNDEFINED.
+ *
+ * @return the key code for this event
+ */
+ public int getKeyCode()
+ {
+ return keyCode;
+ }
+
+ /**
+ * Sets the key code for this event. This must be one of the
+ * <code>VK_*</code> constants defined in this class.
+ *
+ * @param keyCode the new key code for this event
+ */
+ public void setKeyCode(int keyCode)
+ {
+ this.keyCode = keyCode;
+ }
+
+ /**
+ * Returns the Unicode value for the event key. This will be
+ * <code>CHAR_UNDEFINED</code> if there is no Unicode equivalent for
+ * this key, usually when this is a KEY_PRESSED or KEY_RELEASED event.
+ *
+ * @return the Unicode character for this event
+ */
+ public char getKeyChar()
+ {
+ return keyChar;
+ }
+
+ /**
+ * Sets the Unicode character for this event to the specified value.
+ *
+ * @param keyChar the new Unicode character for this event
+ */
+ public void setKeyChar(char keyChar)
+ {
+ this.keyChar = keyChar;
+ }
+
+ /**
+ * Sets the modifier keys to the specified value. This should be a union
+ * of the bit mask constants from <code>InputEvent</code>. The use of this
+ * method is not recommended, particularly for KEY_TYPED events, which do
+ * not check if the modifiers were changed.
+ *
+ * @param modifiers the new modifier value, in either old or new style
+ * @see InputEvent
+ *
+ * @deprecated
+ */
+ public void setModifiers(int modifiers)
+ {
+ this.modifiers = EventModifier.extend(modifiers);
+ }
+
+ /**
+ * Returns the keyboard location of the key that generated this event. This
+ * provides a way to distinguish between keys like left and right shift
+ * which share a common key code. The result will be one of
+ * {@link #KEY_LOCATION_UNKNOWN}, {@link #KEY_LOCATION_STANDARD},
+ * {@link #KEY_LOCATION_LEFT}, {@link #KEY_LOCATION_RIGHT}, or
+ * {@link #KEY_LOCATION_NUMPAD}.
+ *
+ * @return the key location
+ * @since 1.4
+ */
+ public int getKeyLocation()
+ {
+ return keyLocation;
+ }
+
+ /**
+ * Returns the text name of key code, such as "HOME", "F1", or "A".
+ *
+ * XXX Sun claims this can be localized via the awt.properties file - how
+ * do we implement that?
+ *
+ * @return the text name of the key code
+ */
+ public static String getKeyText(int keyCode)
+ {
+ switch (keyCode)
+ {
+ case VK_CANCEL:
+ return "Cancel";
+ case VK_BACK_SPACE:
+ return "Backspace";
+ case VK_TAB:
+ return "Tab";
+ case VK_ENTER:
+ return "Enter";
+ case VK_CLEAR:
+ return "Clear";
+ case VK_SHIFT:
+ return "Shift";
+ case VK_CONTROL:
+ return "Ctrl";
+ case VK_ALT:
+ return "Alt";
+ case VK_PAUSE:
+ return "Pause";
+ case VK_CAPS_LOCK:
+ return "Caps Lock";
+ case VK_KANA:
+ return "Kana";
+ case VK_FINAL:
+ return "Final";
+ case VK_KANJI:
+ return "Kanji";
+ case VK_ESCAPE:
+ return "Escape";
+ case VK_CONVERT:
+ return "Convert";
+ case VK_NONCONVERT:
+ return "No Convert";
+ case VK_ACCEPT:
+ return "Accept";
+ case VK_MODECHANGE:
+ return "Mode Change";
+ case VK_SPACE:
+ return "Space";
+ case VK_PAGE_UP:
+ return "Page Up";
+ case VK_PAGE_DOWN:
+ return "Page Down";
+ case VK_END:
+ return "End";
+ case VK_HOME:
+ return "Home";
+ case VK_LEFT:
+ case VK_KP_LEFT:
+ return "Left";
+ case VK_UP:
+ case VK_KP_UP:
+ return "Up";
+ case VK_RIGHT:
+ case VK_KP_RIGHT:
+ return "Right";
+ case VK_DOWN:
+ case VK_KP_DOWN:
+ return "Down";
+ case VK_MINUS:
+ return "Minus";
+ case VK_MULTIPLY:
+ return "NumPad *";
+ case VK_ADD:
+ return "NumPad +";
+ case VK_SEPARATOR:
+ return "NumPad ,";
+ case VK_SUBTRACT:
+ return "NumPad -";
+ case VK_DECIMAL:
+ return "NumPad .";
+ case VK_DIVIDE:
+ return "NumPad /";
+ case VK_DELETE:
+ return "Delete";
+ case VK_DEAD_GRAVE:
+ return "Dead Grave";
+ case VK_DEAD_ACUTE:
+ return "Dead Acute";
+ case VK_DEAD_CIRCUMFLEX:
+ return "Dead Circumflex";
+ case VK_DEAD_TILDE:
+ return "Dead Tilde";
+ case VK_DEAD_MACRON:
+ return "Dead Macron";
+ case VK_DEAD_BREVE:
+ return "Dead Breve";
+ case VK_DEAD_ABOVEDOT:
+ return "Dead Above Dot";
+ case VK_DEAD_DIAERESIS:
+ return "Dead Diaeresis";
+ case VK_DEAD_ABOVERING:
+ return "Dead Above Ring";
+ case VK_DEAD_DOUBLEACUTE:
+ return "Dead Double Acute";
+ case VK_DEAD_CARON:
+ return "Dead Caron";
+ case VK_DEAD_CEDILLA:
+ return "Dead Cedilla";
+ case VK_DEAD_OGONEK:
+ return "Dead Ogonek";
+ case VK_DEAD_IOTA:
+ return "Dead Iota";
+ case VK_DEAD_VOICED_SOUND:
+ return "Dead Voiced Sound";
+ case VK_DEAD_SEMIVOICED_SOUND:
+ return "Dead Semivoiced Sound";
+ case VK_NUM_LOCK:
+ return "Num Lock";
+ case VK_SCROLL_LOCK:
+ return "Scroll Lock";
+ case VK_AMPERSAND:
+ return "Ampersand";
+ case VK_ASTERISK:
+ return "Asterisk";
+ case VK_QUOTEDBL:
+ return "Double Quote";
+ case VK_LESS:
+ return "Less";
+ case VK_PRINTSCREEN:
+ return "Print Screen";
+ case VK_INSERT:
+ return "Insert";
+ case VK_HELP:
+ return "Help";
+ case VK_META:
+ return "Meta";
+ case VK_GREATER:
+ return "Greater";
+ case VK_BRACELEFT:
+ return "Left Brace";
+ case VK_BRACERIGHT:
+ return "Right Brace";
+ case VK_BACK_QUOTE:
+ return "Back Quote";
+ case VK_QUOTE:
+ return "Quote";
+ case VK_ALPHANUMERIC:
+ return "Alphanumeric";
+ case VK_KATAKANA:
+ return "Katakana";
+ case VK_HIRAGANA:
+ return "Hiragana";
+ case VK_FULL_WIDTH:
+ return "Full-Width";
+ case VK_HALF_WIDTH:
+ return "Half-Width";
+ case VK_ROMAN_CHARACTERS:
+ return "Roman Characters";
+ case VK_ALL_CANDIDATES:
+ return "All Candidates";
+ case VK_PREVIOUS_CANDIDATE:
+ return "Previous Candidate";
+ case VK_CODE_INPUT:
+ return "Code Input";
+ case VK_JAPANESE_KATAKANA:
+ return "Japanese Katakana";
+ case VK_JAPANESE_HIRAGANA:
+ return "Japanese Hiragana";
+ case VK_JAPANESE_ROMAN:
+ return "Japanese Roman";
+ case VK_KANA_LOCK:
+ return "Kana Lock";
+ case VK_INPUT_METHOD_ON_OFF:
+ return "Input Method On/Off";
+ case VK_AT:
+ return "At";
+ case VK_COLON:
+ return "Colon";
+ case VK_CIRCUMFLEX:
+ return "Circumflex";
+ case VK_DOLLAR:
+ return "Dollar";
+ case VK_EURO_SIGN:
+ return "Euro";
+ case VK_EXCLAMATION_MARK:
+ return "Exclamation Mark";
+ case VK_INVERTED_EXCLAMATION_MARK:
+ return "Inverted Exclamation Mark";
+ case VK_LEFT_PARENTHESIS:
+ return "Left Parenthesis";
+ case VK_NUMBER_SIGN:
+ return "Number Sign";
+ case VK_PLUS:
+ return "Plus";
+ case VK_RIGHT_PARENTHESIS:
+ return "Right Parenthesis";
+ case VK_UNDERSCORE:
+ return "Underscore";
+ case VK_COMPOSE:
+ return "Compose";
+ case VK_ALT_GRAPH:
+ return "Alt Graph";
+ case VK_STOP:
+ return "Stop";
+ case VK_AGAIN:
+ return "Again";
+ case VK_PROPS:
+ return "Props";
+ case VK_UNDO:
+ return "Undo";
+ case VK_COPY:
+ return "Copy";
+ case VK_PASTE:
+ return "Paste";
+ case VK_FIND:
+ return "Find";
+ case VK_CUT:
+ return "Cut";
+ case VK_COMMA:
+ case VK_PERIOD:
+ case VK_SLASH:
+ case VK_0:
+ case VK_1:
+ case VK_2:
+ case VK_3:
+ case VK_4:
+ case VK_5:
+ case VK_6:
+ case VK_7:
+ case VK_8:
+ case VK_9:
+ case VK_SEMICOLON:
+ case VK_EQUALS:
+ case VK_A:
+ case VK_B:
+ case VK_C:
+ case VK_D:
+ case VK_E:
+ case VK_F:
+ case VK_G:
+ case VK_H:
+ case VK_I:
+ case VK_J:
+ case VK_K:
+ case VK_L:
+ case VK_M:
+ case VK_N:
+ case VK_O:
+ case VK_P:
+ case VK_Q:
+ case VK_R:
+ case VK_S:
+ case VK_T:
+ case VK_U:
+ case VK_V:
+ case VK_W:
+ case VK_X:
+ case VK_Y:
+ case VK_Z:
+ case VK_OPEN_BRACKET:
+ case VK_BACK_SLASH:
+ case VK_CLOSE_BRACKET:
+ return "" + (char) keyCode;
+ case VK_NUMPAD0:
+ case VK_NUMPAD1:
+ case VK_NUMPAD2:
+ case VK_NUMPAD3:
+ case VK_NUMPAD4:
+ case VK_NUMPAD5:
+ case VK_NUMPAD6:
+ case VK_NUMPAD7:
+ case VK_NUMPAD8:
+ case VK_NUMPAD9:
+ return "NumPad-" + (keyCode - VK_NUMPAD0);
+ case VK_F1:
+ case VK_F2:
+ case VK_F3:
+ case VK_F4:
+ case VK_F5:
+ case VK_F6:
+ case VK_F7:
+ case VK_F8:
+ case VK_F9:
+ case VK_F10:
+ case VK_F11:
+ case VK_F12:
+ return "F" + (keyCode - (VK_F1 - 1));
+ case VK_F13:
+ case VK_F14:
+ case VK_F15:
+ case VK_F16:
+ case VK_F17:
+ case VK_F18:
+ case VK_F19:
+ case VK_F20:
+ case VK_F21:
+ case VK_F22:
+ case VK_F23:
+ case VK_F24:
+ return "F" + (keyCode - (VK_F13 - 13));
+ default:
+ // This is funky on negative numbers, but that's Sun's fault.
+ return "Unknown keyCode: 0x" + (keyCode < 0 ? "-" : "")
+ + Integer.toHexString(Math.abs(keyCode));
+ }
+ }
+
+ /**
+ * Returns a string describing the modifiers, such as "Shift" or
+ * "Ctrl+Button1".
+ *
+ * XXX Sun claims this can be localized via the awt.properties file - how
+ * do we implement that?
+ *
+ * @param modifiers the old-style modifiers to convert to text
+ * @return a string representation of the modifiers in this bitmask
+ */
+ public static String getKeyModifiersText(int modifiers)
+ {
+ return getModifiersExText(EventModifier.extend(modifiers
+ & EventModifier.OLD_MASK));
+ }
+
+ /**
+ * Tests whether or not this key is an action key. An action key typically
+ * does not fire a KEY_TYPED event, and is not a modifier.
+ *
+ * @return true if this is an action key
+ */
+ public boolean isActionKey()
+ {
+ switch (keyCode)
+ {
+ case VK_PAUSE:
+ case VK_CAPS_LOCK:
+ case VK_KANA:
+ case VK_FINAL:
+ case VK_KANJI:
+ case VK_CONVERT:
+ case VK_NONCONVERT:
+ case VK_ACCEPT:
+ case VK_MODECHANGE:
+ case VK_PAGE_UP:
+ case VK_PAGE_DOWN:
+ case VK_END:
+ case VK_HOME:
+ case VK_LEFT:
+ case VK_UP:
+ case VK_RIGHT:
+ case VK_DOWN:
+ case VK_F1:
+ case VK_F2:
+ case VK_F3:
+ case VK_F4:
+ case VK_F5:
+ case VK_F6:
+ case VK_F7:
+ case VK_F8:
+ case VK_F9:
+ case VK_F10:
+ case VK_F11:
+ case VK_F12:
+ case VK_NUM_LOCK:
+ case VK_SCROLL_LOCK:
+ case VK_PRINTSCREEN:
+ case VK_INSERT:
+ case VK_HELP:
+ case VK_KP_UP:
+ case VK_KP_DOWN:
+ case VK_KP_LEFT:
+ case VK_KP_RIGHT:
+ case VK_ALPHANUMERIC:
+ case VK_KATAKANA:
+ case VK_HIRAGANA:
+ case VK_FULL_WIDTH:
+ case VK_HALF_WIDTH:
+ case VK_ROMAN_CHARACTERS:
+ case VK_ALL_CANDIDATES:
+ case VK_PREVIOUS_CANDIDATE:
+ case VK_CODE_INPUT:
+ case VK_JAPANESE_KATAKANA:
+ case VK_JAPANESE_HIRAGANA:
+ case VK_JAPANESE_ROMAN:
+ case VK_KANA_LOCK:
+ case VK_INPUT_METHOD_ON_OFF:
+ case VK_F13:
+ case VK_F14:
+ case VK_F15:
+ case VK_F16:
+ case VK_F17:
+ case VK_F18:
+ case VK_F19:
+ case VK_F20:
+ case VK_F21:
+ case VK_F22:
+ case VK_F23:
+ case VK_F24:
+ case VK_STOP:
+ case VK_AGAIN:
+ case VK_PROPS:
+ case VK_UNDO:
+ case VK_COPY:
+ case VK_PASTE:
+ case VK_FIND:
+ case VK_CUT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Returns a string identifying the event. This is formatted as the
+ * field name of the id type, followed by the keyCode, then the
+ * keyChar, modifiers (if any), extModifiers (if any), and
+ * keyLocation.
+ *
+ * @return a string identifying the event
+ */
+ public String paramString()
+ {
+ StringBuffer s = new StringBuffer();
+
+ switch (id)
+ {
+ case KEY_PRESSED:
+ s.append("KEY_PRESSED");
+ break;
+ case KEY_RELEASED:
+ s.append("KEY_RELEASED");
+ break;
+ case KEY_TYPED:
+ s.append("KEY_TYPED");
+ break;
+ default:
+ s.append("unknown type");
+ }
+
+ s.append(",keyCode=").append(keyCode);
+
+ s.append(",keyText=").append(getKeyText(keyCode));
+
+ s.append(",keyChar=");
+ if (isActionKey()
+ || keyCode == VK_SHIFT
+ || keyCode == VK_CONTROL
+ || keyCode == VK_ALT)
+ s.append("Undefined keyChar");
+ else
+ {
+ /* This output string must be selected by examining keyChar
+ * rather than keyCode, because key code information is not
+ * included in KEY_TYPED events.
+ */
+ if (keyChar == VK_BACK_SPACE
+ || keyChar == VK_TAB
+ || keyChar == VK_ENTER
+ || keyChar == VK_ESCAPE
+ || keyChar == VK_DELETE)
+ s.append(getKeyText(keyChar));
+ else
+ s.append("'").append(keyChar).append("'");
+ }
+
+ if ((modifiers & CONVERT_MASK) != 0)
+ s.append(",modifiers=").append(getModifiersExText(modifiers
+ & CONVERT_MASK));
+ if (modifiers != 0)
+ s.append(",extModifiers=").append(getModifiersExText(modifiers));
+
+ s.append(",keyLocation=KEY_LOCATION_");
+ switch (keyLocation)
+ {
+ case KEY_LOCATION_UNKNOWN:
+ s.append("UNKNOWN");
+ break;
+ case KEY_LOCATION_STANDARD:
+ s.append("STANDARD");
+ break;
+ case KEY_LOCATION_LEFT:
+ s.append("LEFT");
+ break;
+ case KEY_LOCATION_RIGHT:
+ s.append("RIGHT");
+ break;
+ case KEY_LOCATION_NUMPAD:
+ s.append("NUMPAD");
+ }
+
+ return s.toString();
+ }
+
+ /**
+ * Reads in the object from a serial stream.
+ *
+ * @param s the stream to read from
+ * @throws IOException if deserialization fails
+ * @throws ClassNotFoundException if deserialization fails
+ * @serialData default, except that the modifiers are converted to new style
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ modifiers = EventModifier.extend(modifiers);
+ }
+} // class KeyEvent
diff --git a/libjava/classpath/java/awt/event/KeyListener.java b/libjava/classpath/java/awt/event/KeyListener.java
new file mode 100644
index 0000000..5c0a640
--- /dev/null
+++ b/libjava/classpath/java/awt/event/KeyListener.java
@@ -0,0 +1,77 @@
+/* KeyListener.java -- listen for keyboard presses
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to receive keyboard events. To
+ * watch a subset of these events, use a KeyAdapter.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see KeyAdapter
+ * @see KeyEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface KeyListener extends EventListener
+{
+ /**
+ * This method is called when a key is typed. A key is considered typed
+ * when it and all modifiers have been pressed and released, mapping to
+ * a single virtual key.
+ *
+ * @param event the <code>KeyEvent</code> indicating that a key was typed
+ */
+ void keyTyped(KeyEvent event);
+
+ /**
+ * This method is called when a key is pressed.
+ *
+ * @param event the <code>KeyEvent</code> indicating the key press
+ */
+ void keyPressed(KeyEvent event);
+
+ /**
+ * This method is called when a key is released.
+ *
+ * @param event the <code>KeyEvent</code> indicating the key release
+ */
+ void keyReleased(KeyEvent event);
+} // interface KeyListener
diff --git a/libjava/classpath/java/awt/event/MouseAdapter.java b/libjava/classpath/java/awt/event/MouseAdapter.java
new file mode 100644
index 0000000..9f40c28
--- /dev/null
+++ b/libjava/classpath/java/awt/event/MouseAdapter.java
@@ -0,0 +1,106 @@
+/* MouseAdapter.java -- convenience class for writing mouse listeners
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+/**
+ * This class implements <code>MouseListener</code> and implements all methods
+ * with empty bodies. This allows a listener interested in implementing only
+ * a subset of the <code>MouseListener</code> interface to extend this class
+ * and override only the desired methods.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see MouseEvent
+ * @see MouseListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class MouseAdapter implements MouseListener
+{
+ /**
+ * Do nothing default constructor for subclasses.
+ */
+ public MouseAdapter()
+ {
+ }
+
+ /**
+ * Implements this method in the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void mouseClicked(MouseEvent event)
+ {
+ }
+
+ /**
+ * Implements this method in the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void mousePressed(MouseEvent event)
+ {
+ }
+
+ /**
+ * Implements this method in the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void mouseReleased(MouseEvent event)
+ {
+ }
+
+ /**
+ * Implements this method in the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void mouseEntered(MouseEvent event)
+ {
+ }
+
+ /**
+ * Implements this method in the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void mouseExited(MouseEvent event)
+ {
+ }
+} // class MouseAdapter
diff --git a/libjava/classpath/java/awt/event/MouseEvent.java b/libjava/classpath/java/awt/event/MouseEvent.java
new file mode 100644
index 0000000..249c3d1
--- /dev/null
+++ b/libjava/classpath/java/awt/event/MouseEvent.java
@@ -0,0 +1,432 @@
+/* MouseEvent.java -- a mouse event
+ Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import gnu.java.awt.EventModifier;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * This event is generated for a mouse event. There are three main categories
+ * of mouse events: Regular events include pressing, releasing, and clicking
+ * buttons, as well as moving over the boundary of the unobscured portion of
+ * a component. Motion events include movement and dragging. Wheel events are
+ * covered separately by the subclass MouseWheelEvent.
+ *
+ * <p>A mouse event is tied to the unobstructed visible component that the
+ * mouse cursor was over at the time of the action. The button that was
+ * most recently pressed is the only one that shows up in
+ * <code>getModifiers</code>, and is returned by <code>getButton</code>,
+ * while all buttons that are down show up in <code>getModifiersEx</code>.
+ *
+ * <p>Drag events may be cut short if native drag-and-drop operations steal
+ * the event. Likewise, if a mouse drag exceeds the bounds of a window or
+ * virtual device, some platforms may clip the path to fit in the bounds of
+ * the component.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see MouseAdapter
+ * @see MouseListener
+ * @see MouseMotionAdapter
+ * @see MouseMotionListener
+ * @see MouseWheelListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class MouseEvent extends InputEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -991214153494842848L;
+
+ /** This is the first id in the range of event ids used by this class. */
+ public static final int MOUSE_FIRST = 500;
+
+ /** This is the last id in the range of event ids used by this class. */
+ public static final int MOUSE_LAST = 507;
+
+ /** This event id indicates that the mouse was clicked. */
+ public static final int MOUSE_CLICKED = 500;
+
+ /** This event id indicates that the mouse was pressed. */
+ public static final int MOUSE_PRESSED = 501;
+
+ /** This event id indicates that the mouse was released. */
+ public static final int MOUSE_RELEASED = 502;
+
+ /** This event id indicates that the mouse was moved. */
+ public static final int MOUSE_MOVED = 503;
+
+ /** This event id indicates that the mouse entered a component. */
+ public static final int MOUSE_ENTERED = 504;
+
+ /** This event id indicates that the mouse exited a component. */
+ public static final int MOUSE_EXITED = 505;
+
+ /**
+ * This indicates that no button changed state.
+ *
+ * @see #getButton()
+ * @since 1.4
+ */
+ public static final int NOBUTTON = 0;
+
+ /**
+ * This indicates that button 1 changed state.
+ *
+ * @see #getButton()
+ * @since 1.4
+ */
+ public static final int BUTTON1 = 1;
+
+ /**
+ * This indicates that button 2 changed state.
+ *
+ * @see #getButton()
+ * @since 1.4
+ */
+ public static final int BUTTON2 = 2;
+
+ /**
+ * This indicates that button 3 changed state.
+ *
+ * @see #getButton()
+ * @since 1.4
+ */
+ public static final int BUTTON3 = 3;
+
+ /** This event id indicates that the mouse was dragged over a component. */
+ public static final int MOUSE_DRAGGED = 506;
+
+ /**
+ * This event id indicates that the mouse wheel was rotated.
+ *
+ * @since 1.4
+ */
+ public static final int MOUSE_WHEEL = 507;
+
+ /**
+ * The X coordinate of the mouse cursor at the time of the event.
+ *
+ * @see #getX()
+ * @serial the x coordinate
+ */
+ private int x;
+
+ /**
+ * The Y coordinate of the mouse cursor at the time of the event.
+ *
+ * @see #getY()
+ * @serial the y coordinate
+ */
+ private int y;
+
+ /**
+ * The number of clicks that took place. For MOUSE_CLICKED, MOUSE_PRESSED,
+ * and MOUSE_RELEASED, this will be at least 1; otherwise it is 0.
+ *
+ * see #getClickCount()
+ * @serial the number of clicks
+ */
+ private final int clickCount;
+
+ /**
+ * Indicates which mouse button changed state. Can only be one of
+ * {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or
+ * {@link #BUTTON3}.
+ *
+ * @see #getButton()
+ * @since 1.4
+ */
+ private int button;
+
+ /**
+ * Whether or not this event should trigger a popup menu.
+ *
+ * @see PopupMenu
+ * @see #isPopupTrigger()
+ * @serial true if this is a popup trigger
+ */
+ private final boolean popupTrigger;
+
+ /**
+ * Initializes a new instance of <code>MouseEvent</code> with the specified
+ * information. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @param when the timestamp of when the event occurred
+ * @param modifiers the modifier keys during the event, in old or new style
+ * @param x the X coordinate of the mouse point
+ * @param y the Y coordinate of the mouse point
+ * @param clickCount the number of mouse clicks for this event
+ * @param popupTrigger true if this event triggers a popup menu
+ * @param button the most recent mouse button to change state
+ * @throws IllegalArgumentException if source is null or button is invalid
+ * @since 1.4
+ */
+ public MouseEvent(Component source, int id, long when, int modifiers,
+ int x, int y, int clickCount, boolean popupTrigger,
+ int button)
+ {
+ super(source, id, when, modifiers);
+ this.x = x;
+ this.y = y;
+ this.clickCount = clickCount;
+ this.popupTrigger = popupTrigger;
+ this.button = button;
+ if (button < NOBUTTON || button > BUTTON3)
+ throw new IllegalArgumentException();
+ if ((modifiers & EventModifier.OLD_MASK) != 0)
+ {
+ if ((modifiers & BUTTON1_MASK) != 0)
+ this.button = BUTTON1;
+ else if ((modifiers & BUTTON2_MASK) != 0)
+ this.button = BUTTON2;
+ else if ((modifiers & BUTTON3_MASK) != 0)
+ this.button = BUTTON3;
+ }
+ }
+
+ /**
+ * Initializes a new instance of <code>MouseEvent</code> with the specified
+ * information. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @param when the timestamp of when the event occurred
+ * @param modifiers the modifier keys during the event, in old or new style
+ * @param x the X coordinate of the mouse point
+ * @param y the Y coordinate of the mouse point
+ * @param clickCount the number of mouse clicks for this event
+ * @param popupTrigger true if this event triggers a popup menu
+ * @throws IllegalArgumentException if source is null
+ */
+ public MouseEvent(Component source, int id, long when, int modifiers,
+ int x, int y, int clickCount, boolean popupTrigger)
+ {
+ this(source, id, when, modifiers, x, y, clickCount, popupTrigger,
+ NOBUTTON);
+ }
+
+ /**
+ * This method returns the X coordinate of the mouse position. This is
+ * relative to the source component.
+ *
+ * @return the x coordinate
+ */
+ public int getX()
+ {
+ return x;
+ }
+
+ /**
+ * This method returns the Y coordinate of the mouse position. This is
+ * relative to the source component.
+ *
+ * @return the y coordinate
+ */
+ public int getY()
+ {
+ return y;
+ }
+
+ /**
+ * This method returns a <code>Point</code> for the x,y position of
+ * the mouse pointer. This is relative to the source component.
+ *
+ * @return a <code>Point</code> for the event position
+ */
+ public Point getPoint()
+ {
+ return new Point(x, y);
+ }
+
+ /**
+ * Translates the event coordinates by the specified x and y offsets.
+ *
+ * @param dx the value to add to the X coordinate of this event
+ * @param dy the value to add to the Y coordiante of this event
+ */
+ public void translatePoint(int dx, int dy)
+ {
+ x += dx;
+ y += dy;
+ }
+
+ /**
+ * This method returns the number of mouse clicks associated with this
+ * event.
+ *
+ * @return the number of mouse clicks for this event
+ */
+ public int getClickCount()
+ {
+ return clickCount;
+ }
+
+ /**
+ * Returns which button, if any, was the most recent to change state. This
+ * will be one of {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or
+ * {@link #BUTTON3}.
+ *
+ * @return the button that changed state
+ * @since 1.4
+ */
+ public int getButton()
+ {
+ return button;
+ }
+
+ /**
+ * This method tests whether or not the event is a popup menu trigger. This
+ * should be checked in both MousePressed and MouseReleased to be
+ * cross-platform compatible, as different systems have different popup
+ * triggers.
+ *
+ * @return true if the event is a popup menu trigger
+ */
+ public boolean isPopupTrigger()
+ {
+ return popupTrigger;
+ }
+
+ /**
+ * Returns a string describing the modifiers, such as "Shift" or
+ * "Ctrl+Button1".
+ *
+ * XXX Sun claims this can be localized via the awt.properties file - how
+ * do we implement that?
+ *
+ * @param modifiers the old-style modifiers to convert to text
+ * @return a string representation of the modifiers in this bitmask
+ */
+ public static String getMouseModifiersText(int modifiers)
+ {
+ modifiers &= EventModifier.OLD_MASK;
+ if ((modifiers & BUTTON2_MASK) != 0)
+ modifiers |= BUTTON2_DOWN_MASK;
+ if ((modifiers & BUTTON3_MASK) != 0)
+ modifiers |= BUTTON3_DOWN_MASK;
+ return getModifiersExText(EventModifier.extend(modifiers));
+ }
+
+ /**
+ * Returns a string identifying this event. This is formatted as the field
+ * name of the id type, followed by the (x,y) point, the most recent button
+ * changed, modifiers (if any), extModifiers (if any), and clickCount.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ StringBuffer s = new StringBuffer();
+ switch (id)
+ {
+ case MOUSE_CLICKED:
+ s.append("MOUSE_CLICKED,(");
+ break;
+ case MOUSE_PRESSED:
+ s.append("MOUSE_PRESSED,(");
+ break;
+ case MOUSE_RELEASED:
+ s.append("MOUSE_RELEASED,(");
+ break;
+ case MOUSE_MOVED:
+ s.append("MOUSE_MOVED,(");
+ break;
+ case MOUSE_ENTERED:
+ s.append("MOUSE_ENTERED,(");
+ break;
+ case MOUSE_EXITED:
+ s.append("MOUSE_EXITED,(");
+ break;
+ case MOUSE_DRAGGED:
+ s.append("MOUSE_DRAGGED,(");
+ break;
+ case MOUSE_WHEEL:
+ s.append("MOUSE_WHEEL,(");
+ break;
+ default:
+ s.append("unknown type,(");
+ }
+ s.append(x).append(',').append(y).append("),button=").append(button);
+ if ((modifiers & EventModifier.NEW_MASK) != 0)
+ {
+ int mod = modifiers;
+ if ((mod & (ALT_DOWN_MASK | BUTTON2_DOWN_MASK)) != 0)
+ mod |= ALT_DOWN_MASK | BUTTON2_DOWN_MASK;
+ if ((mod & (META_DOWN_MASK | BUTTON3_DOWN_MASK)) != 0)
+ mod |= META_DOWN_MASK | BUTTON3_DOWN_MASK;
+ s.append(",modifiers=").append(getModifiersExText(mod));
+ }
+ if (modifiers != 0)
+ s.append(",extModifiers=").append(getModifiersExText(modifiers));
+ return s.append(",clickCount=").append(clickCount).toString();
+ }
+
+ /**
+ * Reads in the object from a serial stream.
+ *
+ * @param s the stream to read from
+ * @throws IOException if deserialization fails
+ * @throws ClassNotFoundException if deserialization fails
+ * @serialData default, except that the modifiers are converted to new style
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ if ((modifiers & EventModifier.OLD_MASK) != 0)
+ {
+ if ((modifiers & BUTTON1_MASK) != 0)
+ button = BUTTON1;
+ else if ((modifiers & BUTTON2_MASK) != 0)
+ button = BUTTON2;
+ else if ((modifiers & BUTTON3_MASK) != 0)
+ button = BUTTON3;
+ modifiers = EventModifier.extend(modifiers);
+ }
+ }
+} // class MouseEvent
diff --git a/libjava/classpath/java/awt/event/MouseListener.java b/libjava/classpath/java/awt/event/MouseListener.java
new file mode 100644
index 0000000..4508019
--- /dev/null
+++ b/libjava/classpath/java/awt/event/MouseListener.java
@@ -0,0 +1,94 @@
+/* MouseListener.java -- listen for mouse clicks and crossing component edges
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to receive mouse events other than
+ * simple motion events. This includes clicks (but not mouse wheel events),
+ * and crossing component boundaries without change in button status. To
+ * track moves and drags, use MouseMotionListener, and to track wheel events,
+ * use MouseWheelListener. To watch a subset of these events, use a
+ * MouseAdapter.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see MouseAdapter
+ * @see MouseEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface MouseListener extends EventListener
+{
+ /**
+ * This method is called when the mouse is clicked (pressed and released
+ * in short succession) on a component.
+ *
+ * @param event the <code>MouseEvent</code> indicating the click
+ */
+ void mouseClicked(MouseEvent event);
+
+ /**
+ * This method is called when the mouse is pressed over a component.
+ *
+ * @param event the <code>MouseEvent</code> for the press
+ */
+ void mousePressed(MouseEvent event);
+
+ /**
+ * This method is called when the mouse is released over a component.
+ *
+ * @param event the <code>MouseEvent</code> for the release
+ */
+ void mouseReleased(MouseEvent event);
+
+ /**
+ * This method is called when the mouse enters a component.
+ *
+ * @param event the <code>MouseEvent</code> for the entry
+ */
+ void mouseEntered(MouseEvent event);
+
+ /**
+ * This method is called when the mouse exits a component.
+ *
+ * @param event the <code>MouseEvent</code> for the exit
+ */
+ void mouseExited(MouseEvent event);
+} // interface MouseListener
diff --git a/libjava/classpath/java/awt/event/MouseMotionAdapter.java b/libjava/classpath/java/awt/event/MouseMotionAdapter.java
new file mode 100644
index 0000000..8a295f6
--- /dev/null
+++ b/libjava/classpath/java/awt/event/MouseMotionAdapter.java
@@ -0,0 +1,79 @@
+/* MouseMotionAdapter.java -- convenience class for mouse motion listeners
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+/**
+ * This class implements <code>MouseMotionListener</code> and implements all
+ * methods with empty bodies. This allows a listener interested in
+ * implementing only a subset of the <code>MouseMotionListener</code>
+ * interface to extend this class and override only the desired methods.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see MouseEvent
+ * @see MouseMotionListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class MouseMotionAdapter implements MouseMotionListener
+{
+ /**
+ * Do nothing default constructor for subclasses.
+ */
+ public MouseMotionAdapter()
+ {
+ }
+
+ /**
+ * Implement this method in the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void mouseDragged(MouseEvent event)
+ {
+ }
+
+ /**
+ * Implement this method in the interface with an empty body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void mouseMoved(MouseEvent event)
+ {
+ }
+} // class MouseMotionAdapter
diff --git a/libjava/classpath/java/awt/event/MouseMotionListener.java b/libjava/classpath/java/awt/event/MouseMotionListener.java
new file mode 100644
index 0000000..ba2c569
--- /dev/null
+++ b/libjava/classpath/java/awt/event/MouseMotionListener.java
@@ -0,0 +1,72 @@
+/* MouseMotionListener.java -- listen to mouse motion events
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to be notified of mouse movements.
+ * This includes moves and drags, but not crossing component boundaries. To
+ * track other mouse events, use MouseListener or MouseWheelListener. To
+ * watch a subset of these events, use a MouseMotionAdapter.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see MouseMotionAdapter
+ * @see MouseEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface MouseMotionListener extends EventListener
+{
+ /**
+ * This method is called when the mouse is moved over a component
+ * while a button has been pressed.
+ *
+ * @param event the <code>MouseEvent</code> indicating the motion
+ */
+ void mouseDragged(MouseEvent event);
+
+ /**
+ * This method is called when the mouse is moved over a component
+ * while no button is pressed.
+ *
+ * @param event the <code>MouseEvent</code> indicating the motion
+ */
+ void mouseMoved(MouseEvent event);
+} // interface MouseMotionListener
diff --git a/libjava/classpath/java/awt/event/MouseWheelEvent.java b/libjava/classpath/java/awt/event/MouseWheelEvent.java
new file mode 100644
index 0000000..bc603aa
--- /dev/null
+++ b/libjava/classpath/java/awt/event/MouseWheelEvent.java
@@ -0,0 +1,232 @@
+/* MouseWheelEvent.java -- a mouse wheel event
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.Adjustable;
+import java.awt.Component;
+import java.awt.Rectangle;
+import java.awt.ScrollPane;
+
+import javax.swing.JScrollPane;
+import javax.swing.Scrollable;
+
+/**
+ * This event is generated for a mouse wheel rotation. The wheel (the middle
+ * mouse button on most modern mice) can be rotated towards or away from the
+ * user, and is ofteh used for scrolling.
+ *
+ * <p>Because of the special use for scrolling components, MouseWheelEvents
+ * often affect a different component than the one located at the point of
+ * the event. If the component under the mouse cursor does not accept wheel
+ * events, the event is passed to the first ancestor container which does. This
+ * is often a ScrollPane, which knows how to scroll. If an AWT component is
+ * built from a native widget that knows how to use mouse wheel events, that
+ * component will consume the event.
+ *
+ * <p>The two most common scroll types are "units" (lines at a time) or
+ * "blocks" (pages at a time). The initial setting is taken from the platform,
+ * although the user can adjust the setting at any time.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see MouseWheelListener
+ * @see ScrollPane
+ * @see ScrollPane#setWheelScrollingEnabled(boolean)
+ * @see JScrollPane
+ * @see JScrollPane#setWheelScrollingEnabled(boolean)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public class MouseWheelEvent extends MouseEvent
+{
+ /**
+ * Compatible with JDK 1.4+.
+ */
+ private static final long serialVersionUID = 6459879390515399677L;
+
+ /**
+ * Indicates scrolling by units (lines).
+ *
+ * @see #getScrollType()
+ */
+ public static final int WHEEL_UNIT_SCROLL = 0;
+
+ /**
+ * Indicates scrolling by blocks (pages).
+ *
+ * @see #getScrollType()
+ */
+ public static final int WHEEL_BLOCK_SCROLL = 1;
+
+ /**
+ * Indicates what scroll type should take place. This should be limited
+ * to {@link #WHEEL_UNIT_SCROLL} and {@link #WHEEL_BLOCK_SCROLL}.
+ *
+ * @serial the scroll type
+ */
+ private final int scrollType;
+
+ /**
+ * Indicates the scroll amount. This is only meaningful if scrollType is
+ * WHEEL_UNIT_SCROLL.
+ *
+ * @serial the number of lines to scroll
+ */
+ private final int scrollAmount;
+
+ /**
+ * Indicates how far the mouse wheel was rotated.
+ *
+ * @serial the rotation amount
+ */
+ private final int wheelRotation;
+
+ /**
+ * Initializes a new instance of <code>MouseWheelEvent</code> with the
+ * specified information. Note that an invalid id leads to unspecified
+ * results.
+ *
+ * @param source the source of the event
+ * @param id the event id
+ * @param when the timestamp of when the event occurred
+ * @param modifiers any modifier bits for this event
+ * @param x the X coordinate of the mouse point
+ * @param y the Y coordinate of the mouse point
+ * @param clickCount the number of mouse clicks for this event
+ * @param popupTrigger true if this event triggers a popup menu
+ * @param scrollType one of {@link #WHEEL_UNIT_SCROLL},
+ * {@link #WHEEL_BLOCK_SCROLL}
+ * @param scrollAmount the number of units to scroll, ignored for block type
+ * @param wheelRotation the number of rotation "clicks"
+ * @throws IllegalArgumentException if source is null
+ * @see MouseEvent#MouseEvent(Component, int, long, int, int, int, int,
+ * boolean)
+ */
+ public MouseWheelEvent(Component source, int id, long when, int modifiers,
+ int x, int y, int clickCount, boolean popupTrigger,
+ int scrollType, int scrollAmount, int wheelRotation)
+ {
+ super(source, id, when, modifiers, x, y, clickCount, popupTrigger);
+ this.scrollType = scrollType;
+ this.scrollAmount = scrollAmount;
+ this.wheelRotation = wheelRotation;
+ }
+
+ /**
+ * This method returns the scrolling pattern this event requests. Legal
+ * values are {@link #WHEEL_UNIT_SCROLL} and {@link #WHEEL_BLOCK_SCROLL}.
+ *
+ * @return the scroll type
+ * @see Adjustable#getUnitIncrement()
+ * @see Adjustable#getBlockIncrement()
+ * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
+ * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
+ */
+ public int getScrollType()
+ {
+ return scrollType;
+ }
+
+ /**
+ * Returns the number of units to scroll in response to this event. This
+ * only makes sense when the scroll type is WHEEL_UNIT_SCROLL.
+ *
+ * @return the number of scroll units, if defined
+ * @see #getScrollType()
+ */
+ public int getScrollAmount()
+ {
+ return scrollAmount;
+ }
+
+ /**
+ * Gets the number of "clicks" the wheel was rotated. Negative values move
+ * up (away) from the user, positive values move down (towards) the user.
+ *
+ * @return the number of rotation clicks
+ */
+ public int getWheelRotation()
+ {
+ return wheelRotation;
+ }
+
+ /**
+ * This is a convenience method which aids in a common listener for scrolling
+ * a scrollpane (although this is already built into ScrollPane and
+ * JScrollPane). This method only makes sense when getScrollType() returns
+ * WHEEL_UNIT_SCROLL.
+ *
+ * <p>This accounts for direction of scroll and amount of wheel movement, as
+ * interpreted by the platform settings.
+ *
+ * @return the number of units to scroll
+ * @see #getScrollType()
+ * @see #getScrollAmount()
+ * @see MouseWheelListener
+ * @see Adjustable
+ * @see Adjustable#getUnitIncrement()
+ * @see Scrollable
+ * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
+ * @see ScrollPane
+ * @see ScrollPane#setWheelScrollingEnabled(boolean)
+ * @see JScrollPane
+ * @see JScrollPane#setWheelScrollingEnabled(boolean)
+ */
+ public int getUnitsToScroll()
+ {
+ return wheelRotation * scrollAmount;
+ }
+
+ /**
+ * Returns a string identifying this event. For mouse wheel events, this
+ * is <code>super.paramString() + ",scrollType=WHEEL_" +
+ * (getScrollType() == WHEEL_UNIT_SCROLL ? "UNIT" : "BLOCK")
+ * + "_SCROLL,scrollAmount=" + getScrollAmount() + ",wheelRotation="
+ * + getWheelRotation()</code>.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ return super.paramString() + ",scrollType="
+ + (scrollType == WHEEL_UNIT_SCROLL ? "WHEEL_UNIT_SCROLL"
+ : scrollType == WHEEL_BLOCK_SCROLL ? "WHEEL_BLOCK_SCROLL"
+ : "unknown scroll type")
+ + ",scrollAmount=" + scrollAmount + ",wheelRotation=" + wheelRotation;
+ }
+} // class MouseWheelEvent
diff --git a/libjava/classpath/java/awt/event/MouseWheelListener.java b/libjava/classpath/java/awt/event/MouseWheelListener.java
new file mode 100644
index 0000000..1125582
--- /dev/null
+++ b/libjava/classpath/java/awt/event/MouseWheelListener.java
@@ -0,0 +1,60 @@
+/* MouseWheelListener.java -- listen for mouse wheel events
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to receive mouse wheel events. For
+ * other events, use MouseListener or MouseMotionListener.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see MouseWheelEvent
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public interface MouseWheelListener extends EventListener
+{
+ /**
+ * This method is called when the mouse wheel is rotated.
+ *
+ * @param event the <code>MouseWheelEvent</code> indicating the rotation
+ */
+ void mouseWheelMoved(MouseWheelEvent event);
+} // interface MouseWheelListener
diff --git a/libjava/classpath/java/awt/event/PaintEvent.java b/libjava/classpath/java/awt/event/PaintEvent.java
new file mode 100644
index 0000000..bb89c37
--- /dev/null
+++ b/libjava/classpath/java/awt/event/PaintEvent.java
@@ -0,0 +1,127 @@
+/* PaintEvent.java -- an area of the screen needs to be repainted
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Rectangle;
+
+/**
+ * This event is generated when an area of the screen needs to be painted.
+ * This event is not meant for users, but exists to allow proper serialization
+ * behavior in the EventQueue with user-accessible events.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class PaintEvent extends ComponentEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 1267492026433337593L;
+
+ /** This is the first id in the range of event ids used by this class. */
+ public static final int PAINT_FIRST = 800;
+
+ /** This is the last id in the range of event ids used by this class. */
+ public static final int PAINT_LAST = 801;
+
+ /** This id is for paint event types. */
+ public static final int PAINT = 800;
+
+ /** This id is for update event types. */
+ public static final int UPDATE = 801;
+
+ /**
+ * This is the rectange to be painted or updated.
+ *
+ * @see #getUpdateRect()
+ * @see #setUpdateRect(Rectangle)
+ * @serial the non-null rectangle to be painted
+ */
+ private Rectangle updateRect;
+
+ /**
+ * Initializes a new instance of <code>PaintEvent</code> with the specified
+ * source, id, and update region. Note that an invalid id leads to
+ * unspecified results.
+ *
+ * @param source the event source
+ * @param id the event id
+ * @param updateRect the rectangle to repaint
+ * @throws IllegalArgumentException if source is null
+ */
+ public PaintEvent(Component source, int id, Rectangle updateRect)
+ {
+ super(source, id);
+ this.updateRect = updateRect;
+ }
+
+ /**
+ * Returns the rectange to be updated for this event.
+ *
+ * @return the rectangle to update
+ */
+ public Rectangle getUpdateRect()
+ {
+ return updateRect;
+ }
+
+ /**
+ * Sets the rectangle to be updated for this event.
+ *
+ * @param updateRect the new update rectangle for this event
+ */
+ public void setUpdateRect(Rectangle updateRect)
+ {
+ this.updateRect = updateRect;
+ }
+
+ /**
+ * Returns a string identifying this event.
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ return (id == PAINT ? "PAINT,updateRect=" : id == UPDATE
+ ? "UPDATE,updateRect=" : "unknown type,updateRect=") + updateRect;
+ }
+} // class PaintEvent
diff --git a/libjava/classpath/java/awt/event/TextEvent.java b/libjava/classpath/java/awt/event/TextEvent.java
new file mode 100644
index 0000000..0288abb
--- /dev/null
+++ b/libjava/classpath/java/awt/event/TextEvent.java
@@ -0,0 +1,93 @@
+/* TextEvent.java -- event for text changes
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.TextComponent;
+
+/**
+ * This event is generated when a text box changes contents. This is an
+ * abstraction that distills a large number of individual mouse or keyboard
+ * events into a simpler "text changed" event.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see TextComponent
+ * @see TextListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class TextEvent extends AWTEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 6269902291250941179L;
+
+ /** This is the first id in the range of event ids used by this class. */
+ public static final int TEXT_FIRST = 900;
+
+ /** This is the last id in the range of event ids used by this class. */
+ public static final int TEXT_LAST = 900;
+
+ /** This event id indicates that the text of an object has changed. */
+ public static final int TEXT_VALUE_CHANGED = 900;
+
+ /**
+ * Initializes a new instance of <code>TextEvent</code> with the specified
+ * source and id. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the (TextComponent) object that generated this event
+ * @param id the event id
+ * @throws IllegalArgumentException if source is null
+ */
+ public TextEvent(Object source, int id)
+ {
+ super(source, id);
+ }
+
+ /**
+ * Returns a string identifying this event. This is "TEXT_VALUE_CHANGED".
+ *
+ * @return a string identifying this event
+ */
+ public String paramString()
+ {
+ return id == TEXT_VALUE_CHANGED ? "TEXT_VALUE_CHANGED" : "unknown type";
+ }
+} // class TextEvent
diff --git a/libjava/classpath/java/awt/event/TextListener.java b/libjava/classpath/java/awt/event/TextListener.java
new file mode 100644
index 0000000..bcdd7fa
--- /dev/null
+++ b/libjava/classpath/java/awt/event/TextListener.java
@@ -0,0 +1,60 @@
+/* TextListener.java -- listen for text changes
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to be notified when text changes
+ * in a component.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see TextEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface TextListener extends EventListener
+{
+ /**
+ * This method is called when the text being monitored changes.
+ *
+ * @param event the <code>TextEvent</code> indicating the change
+ */
+ void textValueChanged(TextEvent event);
+} // interface TextListener
diff --git a/libjava/classpath/java/awt/event/WindowAdapter.java b/libjava/classpath/java/awt/event/WindowAdapter.java
new file mode 100644
index 0000000..708de58
--- /dev/null
+++ b/libjava/classpath/java/awt/event/WindowAdapter.java
@@ -0,0 +1,156 @@
+/* WindowAdapter.java -- convenience class for writing window listeners
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+/**
+ * This class implements <code>WindowListener</code>,
+ * <code>WindowStateListener</code>, and <code>WindowFocusListener</code>, and
+ * implements all methods with empty bodies. This allows a listener
+ * interested in listening to only a subset of any <code>WindowEvent</code>
+ * actions to extend this class and override only the desired methods.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see ComponentEvent
+ * @see ComponentListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class WindowAdapter
+ implements WindowListener, WindowStateListener, WindowFocusListener
+{
+ /**
+ * Do nothing default constructor for subclasses.
+ */
+ public WindowAdapter()
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void windowOpened(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void windowClosing(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void windowClosed(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void windowIconified(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void windowDeiconified(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void windowActivated(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ */
+ public void windowDeactivated(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ * @since 1.4
+ */
+ public void windowStateChanged(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ * @since 1.4
+ */
+ public void windowGainedFocus(WindowEvent event)
+ {
+ }
+
+ /**
+ * Implements this method from the interface with an empty method body.
+ *
+ * @param event the event, ignored in this implementation
+ * @since 1.4
+ */
+ public void windowLostFocus(WindowEvent event)
+ {
+ }
+} // class WindowAdapter
diff --git a/libjava/classpath/java/awt/event/WindowEvent.java b/libjava/classpath/java/awt/event/WindowEvent.java
new file mode 100644
index 0000000..2186889
--- /dev/null
+++ b/libjava/classpath/java/awt/event/WindowEvent.java
@@ -0,0 +1,312 @@
+/* WindowEvent.java -- window change event
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.Frame;
+import java.awt.Window;
+
+/**
+ * This event is generated when there is a change in a window. This includes
+ * creation, closing, iconification, activation, and focus changes. There
+ * are three listeners, for three types of events: WindowListeners deal with
+ * the lifecycle of a window, WindowStateListeners deal with window state
+ * like maximization, and WindowFocusListeners deal with focus switching to
+ * or from a window.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see WindowAdapter
+ * @see WindowListener
+ * @see WindowFocusListener
+ * @see WindowStateListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class WindowEvent extends ComponentEvent
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -1567959133147912127L;
+
+ /** This is the first id in the range of event ids used by this class. */
+ public static final int WINDOW_FIRST = 200;
+
+ /** This is the id for a window that is opened. */
+ public static final int WINDOW_OPENED = 200;
+
+ /** This is the id for a window that is about to close. */
+ public static final int WINDOW_CLOSING = 201;
+
+ /** This is the id for a window that finished closing. */
+ public static final int WINDOW_CLOSED = 202;
+
+ /** This is the id for a window that is iconified. */
+ public static final int WINDOW_ICONIFIED = 203;
+
+ /** This is the id for a window that is de-iconified. */
+ public static final int WINDOW_DEICONIFIED = 204;
+
+ /** This is the id for a window that is activated. */
+ public static final int WINDOW_ACTIVATED = 205;
+
+ /** This is the id for a window that is de-activated. */
+ public static final int WINDOW_DEACTIVATED = 206;
+
+ /**
+ * This is the id for a window becoming the focused window.
+ *
+ * @since 1.4
+ */
+ public static final int WINDOW_GAINED_FOCUS = 207;
+
+ /**
+ * This is the id for a window losing all focus.
+ *
+ * @since 1.4
+ */
+ public static final int WINDOW_LOST_FOCUS = 208;
+
+ /**
+ * This is the id for a window state change, such as maximization.
+ *
+ * @since 1.4
+ */
+ public static final int WINDOW_STATE_CHANGED = 209;
+
+ /** This is the last id in the range of event ids used by this class. */
+ public static final int WINDOW_LAST = 209;
+
+ /**
+ * The other Window involved in a focus or activation change. For
+ * WINDOW_ACTIVATED and WINDOW_GAINED_FOCUS events, this is the window that
+ * lost focus; for WINDOW_DEACTIVATED and WINDOW_LOST_FOCUS, this is the
+ * window that stole focus; and for other events (or when native
+ * implementation does not have the data available), this is null.
+ *
+ * @see #getOppositeWindow()
+ * @serial the opposite window, or null
+ * @since 1.4
+ */
+ private final Window opposite;
+
+ /**
+ * The former state of the window.
+ *
+ * @serial bitmask of the old window state
+ * @since 1.4
+ */
+ private final int oldState;
+
+ /**
+ * The present state of the window.
+ *
+ * @serial bitmask of the new window state
+ * @since 1.4
+ */
+ private final int newState;
+
+ /**
+ * Initializes a new instance of <code>WindowEvent</code> with the specified
+ * parameters. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the window that generated this event
+ * @param id the event id
+ * @param opposite the window that received the opposite event, or null
+ * @param oldState the previous state of this window
+ * @param newState the new state of this window
+ * @throws IllegalArgumentException if source is null
+ * @since 1.4
+ */
+ public WindowEvent(Window source, int id, Window opposite,
+ int oldState, int newState)
+ {
+ super(source, id);
+ this.opposite = opposite;
+ this.oldState = oldState;
+ this.newState = newState;
+ }
+
+ /**
+ * Initializes a new instance of <code>WindowEvent</code> with the specified
+ * parameters. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the window that generated this event
+ * @param id the event id
+ * @param opposite the window that received the opposite event, or null
+ * @throws IllegalArgumentException if source is null
+ * @since 1.4
+ */
+ public WindowEvent(Window source, int id, Window opposite)
+ {
+ this(source, id, opposite, 0, 0);
+ }
+
+ /**
+ * Initializes a new instance of <code>WindowEvent</code> with the specified
+ * parameters. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the window that generated this event
+ * @param id the event id
+ * @param oldState the previous state of this window
+ * @param newState the new state of this window
+ * @throws IllegalArgumentException if source is null
+ * @since 1.4
+ */
+ public WindowEvent(Window source, int id, int oldState, int newState)
+ {
+ this(source, id, null, oldState, newState);
+ }
+
+ /**
+ * Initializes a new instance of <code>WindowEvent</code> with the specified
+ * parameters. Note that an invalid id leads to unspecified results.
+ *
+ * @param source the window that generated this event
+ * @param id the event id
+ * @throws IllegalArgumentException if source is null
+ */
+ public WindowEvent(Window source, int id)
+ {
+ this(source, id, null, 0, 0);
+ }
+
+ /**
+ * Returns the event source as a <code>Window</code>. If the source has
+ * subsequently been modified to a non-Window, this returns null.
+ *
+ * @return the event source as a <code>Window</code>
+ */
+ public Window getWindow()
+ {
+ return source instanceof Window ? (Window) source : null;
+ }
+
+ /**
+ * Returns the opposite window if this window was involved in an activation
+ * or focus change. For WINDOW_ACTIVATED and WINDOW_GAINED_FOCUS events,
+ * this is the window that lost focus; for WINDOW_DEACTIVATED and
+ * WINDOW_LOST_FOCUS, this is the window that stole focus; and for other
+ * events (or when native implementation does not have the data available),
+ * this is null.
+ *
+ * @return the opposite window, or null
+ * @since 1.4
+ */
+ public Window getOppositeWindow()
+ {
+ return opposite;
+ }
+
+ /**
+ * Returns the state of this window before the event. This is the bitwise
+ * or of fields in Frame: NORMAL, ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT,
+ * and MAXIMIZED_BOTH.
+ *
+ * @return the former state
+ * @see Frame#getExtendedState()
+ * @since 1.4
+ */
+ public int getOldState()
+ {
+ return oldState;
+ }
+
+ /**
+ * Returns the state of this window after the event. This is the bitwise
+ * or of fields in Frame: NORMAL, ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT,
+ * and MAXIMIZED_BOTH.
+ *
+ * @return the updated state
+ * @see Frame#getExtendedState()
+ * @since 1.4
+ */
+ public int getNewState()
+ {
+ return newState;
+ }
+
+ /**
+ * Returns a string that identifies this event. This is formatted as the
+ * field name of the id, followed by the opposite window, old state, and
+ * new state.
+ *
+ * @return a string that identifies this event
+ */
+ public String paramString()
+ {
+ StringBuffer s = new StringBuffer();
+ switch (id)
+ {
+ case WINDOW_OPENED:
+ s.append("WINDOW_OPENED,opposite=");
+ break;
+ case WINDOW_CLOSING:
+ s.append("WINDOW_CLOSING,opposite=");
+ break;
+ case WINDOW_CLOSED:
+ s.append("WINDOW_CLOSED,opposite=");
+ break;
+ case WINDOW_ICONIFIED:
+ s.append("WINDOW_ICONIFIED,opposite=");
+ break;
+ case WINDOW_DEICONIFIED:
+ s.append("WINDOW_DEICONIFIED,opposite=");
+ break;
+ case WINDOW_ACTIVATED:
+ s.append("WINDOW_ACTIVATED,opposite=");
+ break;
+ case WINDOW_DEACTIVATED:
+ s.append("WINDOW_DEACTIVATED,opposite=");
+ break;
+ case WINDOW_GAINED_FOCUS:
+ s.append("WINDOW_GAINED_FOCUS,opposite=");
+ break;
+ case WINDOW_LOST_FOCUS:
+ s.append("WINDOW_LOST_FOCUS,opposite=");
+ break;
+ case WINDOW_STATE_CHANGED:
+ s.append("WINDOW_STATE_CHANGED,opposite=");
+ break;
+ default:
+ s.append("unknown type,opposite=");
+ }
+ return s.append(opposite).append(",oldState=").append(oldState)
+ .append(",newState=").append(newState).toString();
+ }
+} // class WindowEvent
diff --git a/libjava/classpath/java/awt/event/WindowFocusListener.java b/libjava/classpath/java/awt/event/WindowFocusListener.java
new file mode 100644
index 0000000..7384253
--- /dev/null
+++ b/libjava/classpath/java/awt/event/WindowFocusListener.java
@@ -0,0 +1,68 @@
+/* WindowFocusListener.java -- listens for window focus events
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to monitor events for window
+ * focus changes. To watch a subset of these events, use a WindowAdapter.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see WindowAdapter
+ * @see WindowEvent
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public interface WindowFocusListener extends EventListener
+{
+ /**
+ * This method is called when a window gains focus.
+ *
+ * @param event the <code>WindowEvent</code> indicating the focus change
+ */
+ void windowGainedFocus(WindowEvent event);
+
+ /**
+ * This method is called when a window loses focus.
+ *
+ * @param event the <code>WindowEvent</code> indicating the focus change
+ */
+ void windowLostFocus(WindowEvent event);
+} // interface WindowFocusListener
diff --git a/libjava/classpath/java/awt/event/WindowListener.java b/libjava/classpath/java/awt/event/WindowListener.java
new file mode 100644
index 0000000..52213eb
--- /dev/null
+++ b/libjava/classpath/java/awt/event/WindowListener.java
@@ -0,0 +1,109 @@
+/* WindowListener.java -- listens for window events
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.awt.Frame;
+import java.awt.Image;
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to monitor events for window
+ * changes. To watch a subset of these events, use a WindowAdapter.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @see WindowAdapter
+ * @see WindowEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface WindowListener extends EventListener
+{
+ /**
+ * This method is called when the window is made visible.
+ *
+ * @param event the <code>WindowEvent</code> indicating the change
+ */
+ void windowOpened(WindowEvent event);
+
+ /**
+ * This method is called when the user calls the system menu close
+ * function, giving the program a chance to cancel the close.
+ *
+ * @param event the <code>WindowEvent</code> indicating the close attempt
+ */
+ void windowClosing(WindowEvent event);
+
+ /**
+ * This method is called when the window is closed.
+ *
+ * @param event the <code>WindowEvent</code> indicating the dispose
+ */
+ void windowClosed(WindowEvent event);
+
+ /**
+ * This method is called when the window is iconified.
+ *
+ * @param event the <code>WindowEvent</code> indicating the iconification
+ * @see Frame#setIconImage(Image)
+ */
+ void windowIconified(WindowEvent event);
+
+ /**
+ * This method is called when the window is deiconified.
+ *
+ * @param event the <code>WindowEvent</code> indicating the deiconification
+ */
+ void windowDeiconified(WindowEvent event);
+
+ /**
+ * This method is called when a window is activated. Only Frames and Dialogs
+ * can be active, and the active window always contains the component with
+ * focus.
+ *
+ * @param event the <code>WindowEvent</code> indicating the activation
+ */
+ void windowActivated(WindowEvent event);
+
+ /**
+ * This method is called when the window is deactivated.
+ *
+ * @param event the <code>WindowEvent</code> indicating the deactivation
+ */
+ void windowDeactivated(WindowEvent event);
+} // interface WindowListener
diff --git a/libjava/classpath/java/awt/event/WindowStateListener.java b/libjava/classpath/java/awt/event/WindowStateListener.java
new file mode 100644
index 0000000..9bc6174
--- /dev/null
+++ b/libjava/classpath/java/awt/event/WindowStateListener.java
@@ -0,0 +1,62 @@
+/* WindowStateListener.java -- listens for window state changes
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This interface is for classes that wish to monitor events for window
+ * state changes.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see WindowAdapter
+ * @see WindowEvent
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public interface WindowStateListener extends EventListener
+{
+ /**
+ * This method is called when the window state is changed, because of
+ * iconification or maximization.
+ *
+ * @param event the <code>WindowEvent</code> indicating the change
+ */
+ void windowStateChanged(WindowEvent event);
+} // interface WindowStateListener
diff --git a/libjava/classpath/java/awt/event/package.html b/libjava/classpath/java/awt/event/package.html
new file mode 100644
index 0000000..77662a3
--- /dev/null
+++ b/libjava/classpath/java/awt/event/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.event package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.event</title></head>
+
+<body>
+<p>Listeners and adapters for different kinds of AWT events.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/font/FontRenderContext.java b/libjava/classpath/java/awt/font/FontRenderContext.java
new file mode 100644
index 0000000..78564a6
--- /dev/null
+++ b/libjava/classpath/java/awt/font/FontRenderContext.java
@@ -0,0 +1,126 @@
+/* FontRenderContext.java
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * @author Michael Koch
+ */
+public class FontRenderContext
+{
+ private AffineTransform affineTransform;
+ private boolean isAntiAliased;
+ private boolean usesFractionalMetrics;
+
+ /**
+ * Construct a new <code>FontRenderContext</code>.
+ */
+ protected FontRenderContext()
+ {
+ // Do nothing here.
+ }
+
+ /**
+ * Construct a new <code>FontRenderContext</code>.
+ */
+ public FontRenderContext (AffineTransform tx, boolean isAntiAliased,
+ boolean usesFractionalMetrics)
+ {
+ if (tx != null
+ && !tx.isIdentity ())
+ {
+ this.affineTransform = new AffineTransform (tx);
+ }
+
+ this.isAntiAliased = isAntiAliased;
+ this.usesFractionalMetrics = usesFractionalMetrics;
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof FontRenderContext))
+ return false;
+
+ return equals ((FontRenderContext) obj);
+ }
+
+ public boolean equals (FontRenderContext rhs)
+ {
+ return (affineTransform.equals (rhs.getTransform ())
+ && isAntiAliased == rhs.isAntiAliased ()
+ && usesFractionalMetrics == rhs.usesFractionalMetrics ());
+ }
+
+
+ /**
+ * Retrieves the affine transform for scaling typographical points
+ * to raster pixels.
+ *
+ * @return a clone of the transform object.
+ */
+ public AffineTransform getTransform ()
+ {
+ if (affineTransform == null)
+ return new AffineTransform ();
+ else
+ return new AffineTransform (affineTransform);
+ }
+
+
+ /**
+ * Returns the hash code of the font render context.
+ */
+ public int hashCode ()
+ {
+ // FIXME: check what SUN does here.
+ return affineTransform == null ? 0 : affineTransform.hashCode ();
+ }
+
+ public boolean isAntiAliased ()
+ {
+ return isAntiAliased;
+ }
+
+ public boolean usesFractionalMetrics ()
+ {
+ return usesFractionalMetrics;
+ }
+}
+
diff --git a/libjava/classpath/java/awt/font/GlyphJustificationInfo.java b/libjava/classpath/java/awt/font/GlyphJustificationInfo.java
new file mode 100644
index 0000000..5f45fd5
--- /dev/null
+++ b/libjava/classpath/java/awt/font/GlyphJustificationInfo.java
@@ -0,0 +1,77 @@
+/* GlyphJustificationInfo.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+/**
+ * @author Michael Koch
+ */
+public final class GlyphJustificationInfo
+{
+ public static final int PRIORITY_KASHIDA = 0;
+ public static final int PRIORITY_WHITESPACE = 1;
+ public static final int PRIORITY_INTERCHAR = 2;
+ public static final int PRIORITY_NONE = 3;
+
+ public final float weight;
+ public final int growPriority;
+ public final boolean growAbsorb;
+ public final float growLeftLimit;
+ public final float growRightLimit;
+ public final int shrinkPriority;
+ public final boolean shrinkAbsorb;
+ public final float shrinkLeftLimit;
+ public final float shrinkRightLimit;
+
+ public GlyphJustificationInfo (float weight, boolean growAbsorb,
+ int growPriority, float growLeftLimit,
+ float growRightLimit, boolean shrinkAbsorb,
+ int shrinkPriority, float shrinkLeftLimit,
+ float shrinkRightLimit)
+ {
+ this.weight = weight;
+ this.growAbsorb = growAbsorb;
+ this.growPriority = growPriority;
+ this.growLeftLimit = growLeftLimit;
+ this.growRightLimit = growRightLimit;
+ this.shrinkAbsorb = shrinkAbsorb;
+ this.shrinkPriority = shrinkPriority;
+ this.shrinkLeftLimit = shrinkLeftLimit;
+ this.shrinkRightLimit = shrinkRightLimit;
+ }
+}
diff --git a/libjava/classpath/java/awt/font/GlyphMetrics.java b/libjava/classpath/java/awt/font/GlyphMetrics.java
new file mode 100644
index 0000000..28b2088
--- /dev/null
+++ b/libjava/classpath/java/awt/font/GlyphMetrics.java
@@ -0,0 +1,134 @@
+/* GlyphMetrics.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * @author Michael Koch
+ */
+public final class GlyphMetrics
+{
+ public static final byte COMBINING = 2;
+ public static final byte COMPONENT = 3;
+ public static final byte LIGATURE = 1;
+ public static final byte STANDARD = 0;
+ public static final byte WHITESPACE = 4;
+
+ private boolean horizontal;
+ private float advanceX;
+ private float advanceY;
+ private Rectangle2D bounds;
+ private byte glyphType;
+
+ public GlyphMetrics (boolean horizontal, float advanceX, float advanceY,
+ Rectangle2D bounds, byte glyphType)
+ {
+ this.horizontal = horizontal;
+ this.advanceX = advanceX;
+ this.advanceY = advanceY;
+ this.bounds = bounds;
+ this.glyphType = glyphType;
+ }
+
+ public GlyphMetrics (float advance, Rectangle2D bounds, byte glyphType)
+ {
+ this (true, advance, advance, bounds, glyphType);
+ }
+
+ public float getAdvance ()
+ {
+ return horizontal ? advanceX : advanceY;
+ }
+
+ public float getAdvanceX ()
+ {
+ return advanceX;
+ }
+
+ public float getAdvanceY ()
+ {
+ return advanceY;
+ }
+
+ public Rectangle2D getBounds2D ()
+ {
+ return bounds;
+ }
+
+ public float getLSB ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public float getRSB ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int getType ()
+ {
+ return glyphType;
+ }
+
+ public boolean isCombining ()
+ {
+ return (glyphType == COMBINING);
+ }
+
+ public boolean isComponent ()
+ {
+ return (glyphType == COMPONENT);
+ }
+
+ public boolean isLigature()
+ {
+ return (glyphType == LIGATURE);
+ }
+
+ public boolean isStandard()
+ {
+ return (glyphType == STANDARD);
+ }
+
+ public boolean isWhitespace()
+ {
+ return (glyphType == WHITESPACE);
+ }
+}
diff --git a/libjava/classpath/java/awt/font/GlyphVector.java b/libjava/classpath/java/awt/font/GlyphVector.java
new file mode 100644
index 0000000..57e2581
--- /dev/null
+++ b/libjava/classpath/java/awt/font/GlyphVector.java
@@ -0,0 +1,145 @@
+/* GlyphVector.java
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * @author Michael Koch
+ */
+public abstract class GlyphVector implements Cloneable
+{
+ public static final int FLAG_COMPLEX_GLYPHS = 8;
+ public static final int FLAG_HAS_POSITION_ADJUSTMENTS = 2;
+ public static final int FLAG_HAS_TRANSFORMS = 1;
+ public static final int FLAG_MASK = 15;
+ public static final int FLAG_RUN_RTL = 4;
+
+ /**
+ * Constructs a <code>GlyphVector</code> object.
+ */
+ public GlyphVector ()
+ {
+ }
+
+ public abstract boolean equals (GlyphVector set);
+
+ public abstract Font getFont ();
+
+ public abstract FontRenderContext getFontRenderContext ();
+
+ public int getGlyphCharIndex (int glyphIndex)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int[] getGlyphCharIndices (int beginGlyphIndex, int numEntries,
+ int[] codeReturn)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public abstract int getGlyphCode (int glyphIndex);
+
+ public abstract int[] getGlyphCodes (int beginGlyphIndex, int numEntries,
+ int[] codeReturn);
+
+ public abstract GlyphJustificationInfo getGlyphJustificationInfo
+ (int glyphIndex);
+
+ public abstract Shape getGlyphLogicalBounds (int glyphIndex);
+
+ public abstract GlyphMetrics getGlyphMetrics (int glyphIndex);
+
+ public abstract Shape getGlyphOutline (int glyphIndex);
+
+ public Shape getGlyphOutline (int glyphIndex, float x, float y)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public Rectangle getGlyphPixelBounds (int index, FontRenderContext renderFRC,
+ float x, float y)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public abstract Point2D getGlyphPosition (int glyphIndex);
+
+ public abstract float[] getGlyphPositions (int beginGlyphIndex,
+ int numEntries,
+ float[] positionReturn);
+
+ public abstract AffineTransform getGlyphTransform (int glyphIndex);
+
+ public abstract Shape getGlyphVisualBounds (int glyphIndex);
+
+ public int getLayoutFlags ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public abstract Rectangle2D getLogicalBounds ();
+
+ public abstract int getNumGlyphs ();
+
+ public abstract Shape getOutline ();
+
+ public abstract Shape getOutline (float x, float y);
+
+ public Rectangle getPixelBounds (FontRenderContext renderFRC,
+ float x, float y)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public abstract Rectangle2D getVisualBounds ();
+
+ public abstract void performDefaultLayout ();
+
+ public abstract void setGlyphPosition (int glyphIndex, Point2D newPos);
+
+ public abstract void setGlyphTransform (int glyphIndex,
+ AffineTransform newTX);
+}
diff --git a/libjava/classpath/java/awt/font/GraphicAttribute.java b/libjava/classpath/java/awt/font/GraphicAttribute.java
new file mode 100644
index 0000000..79eae99
--- /dev/null
+++ b/libjava/classpath/java/awt/font/GraphicAttribute.java
@@ -0,0 +1,84 @@
+/* GraphicAttribute.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * @author Michael Koch
+ */
+public abstract class GraphicAttribute
+{
+ public static final int BOTTOM_ALIGNMENT = -2;
+ public static final int CENTER_BASELINE = 1;
+ public static final int HANGING_BASELINE = 2;
+ public static final int ROMAN_BASELINE = 0;
+ public static final int TOP_ALIGNMENT = -1;
+
+ private int alignment;
+
+ protected GraphicAttribute (int alignment)
+ {
+ this.alignment = alignment;
+ }
+
+ public abstract void draw (Graphics2D graphics, float x, float y);
+
+ public abstract float getAdvance ();
+
+ public final int getAlignment ()
+ {
+ return alignment;
+ }
+
+ public abstract float getAscent ();
+
+ public Rectangle2D getBounds ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public abstract float getDescent ();
+
+ public GlyphJustificationInfo getJustificationInfo ()
+ {
+ throw new Error ("not implemented");
+ }
+}
diff --git a/libjava/classpath/java/awt/font/ImageGraphicAttribute.java b/libjava/classpath/java/awt/font/ImageGraphicAttribute.java
new file mode 100644
index 0000000..77413f9
--- /dev/null
+++ b/libjava/classpath/java/awt/font/ImageGraphicAttribute.java
@@ -0,0 +1,109 @@
+/* ImageGraphicAttribute.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * @author Michael Koch
+ */
+public final class ImageGraphicAttribute extends GraphicAttribute
+{
+ private Image image;
+
+ public ImageGraphicAttribute (Image image, int alignment)
+ {
+ super (alignment);
+ this.image = image;
+ }
+
+ public ImageGraphicAttribute (Image image, int alignment, float originX,
+ float originY)
+ {
+ super (alignment);
+ this.image = image;
+
+ throw new Error ("not implemented");
+ }
+
+ public void draw (Graphics2D graphics, float x, float y)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof ImageGraphicAttribute))
+ return false;
+
+ return equals ((ImageGraphicAttribute) obj);
+ }
+
+ public boolean equals (ImageGraphicAttribute rhs)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public float getAdvance ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public float getAscent ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public Rectangle2D getBounds ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public float getDescent ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int hashCode ()
+ {
+ throw new Error ("not implemented");
+ }
+}
diff --git a/libjava/classpath/java/awt/font/LineBreakMeasurer.java b/libjava/classpath/java/awt/font/LineBreakMeasurer.java
new file mode 100644
index 0000000..0a6a969
--- /dev/null
+++ b/libjava/classpath/java/awt/font/LineBreakMeasurer.java
@@ -0,0 +1,113 @@
+/* LineBreakMeasurer.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.text.AttributedCharacterIterator;
+import java.text.BreakIterator;
+
+public final class LineBreakMeasurer
+{
+ private AttributedCharacterIterator ci;
+ private FontRenderContext frc;
+ private BreakIterator bi;
+
+ /**
+ * Constructs a <code>LineBreakMeasurer</code> object.
+ */
+ public LineBreakMeasurer (AttributedCharacterIterator text,
+ FontRenderContext frc)
+ {
+ this (text, null, frc);
+ }
+
+ /**
+ * Constructs a <code>LineBreakMeasurer</code> object.
+ */
+ public LineBreakMeasurer (AttributedCharacterIterator text,
+ BreakIterator breakIter, FontRenderContext frc)
+ {
+ this.ci = text;
+ this.bi = breakIter;
+ this.frc = frc;
+ }
+
+ public void deleteChar (AttributedCharacterIterator newParagraph,
+ int deletePos)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int getPosition ()
+ {
+ return ci.getIndex ();
+ }
+
+ public void insertChar (AttributedCharacterIterator newParagraph,
+ int insertPos)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public TextLayout nextLayout (float wrappingWidth)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public TextLayout nextLayout (float wrappingWidth, int offsetLimit,
+ boolean requireNextWord)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int nextOffset (float wrappingWidth)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int nextOffset (float wrappingWidth, int offsetLimit,
+ boolean requireNextWord)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public void setPosition (int newPosition)
+ {
+ ci.setIndex (newPosition);
+ }
+}
diff --git a/libjava/classpath/java/awt/font/LineMetrics.java b/libjava/classpath/java/awt/font/LineMetrics.java
new file mode 100644
index 0000000..3c45ad1
--- /dev/null
+++ b/libjava/classpath/java/awt/font/LineMetrics.java
@@ -0,0 +1,67 @@
+/* LineMetrics.java -- Information about about a line display characteristics
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+/**
+ * @author Michael Koch
+ */
+public abstract class LineMetrics
+{
+ public abstract float getAscent();
+
+ public abstract int getBaselineIndex();
+
+ public abstract float[] getBaselineOffsets();
+
+ public abstract float getDescent();
+
+ public abstract float getHeight();
+
+ public abstract float getLeading();
+
+ public abstract int getNumChars();
+
+ public abstract float getStrikethroughOffset();
+
+ public abstract float getStrikethroughThickness();
+
+ public abstract float getUnderlineOffset();
+
+ public abstract float getUnderlineThickness();
+}
diff --git a/libjava/classpath/java/awt/font/MultipleMaster.java b/libjava/classpath/java/awt/font/MultipleMaster.java
new file mode 100644
index 0000000..57417ea
--- /dev/null
+++ b/libjava/classpath/java/awt/font/MultipleMaster.java
@@ -0,0 +1,61 @@
+/* MultipleMaster.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.awt.Font;
+
+/**
+ * @author Michael Koch
+ */
+public interface MultipleMaster
+{
+ Font deriveMMFont (float[] axes);
+
+ Font deriveMMFont (float[] glyphWidths, float avgStemWidth,
+ float typicalCapHeight, float typicalXHeight,
+ float italicAngle);
+
+ float[] getDesignAxisDefaults();
+
+ String[] getDesignAxisNames();
+
+ float[] getDesignAxisRanges();
+
+ int getNumDesignAxes();
+}
diff --git a/libjava/classpath/java/awt/font/NumericShaper.java b/libjava/classpath/java/awt/font/NumericShaper.java
new file mode 100644
index 0000000..efbdcd4
--- /dev/null
+++ b/libjava/classpath/java/awt/font/NumericShaper.java
@@ -0,0 +1,137 @@
+/* NumericShaper.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.io.Serializable;
+
+/**
+ * @author Michael Koch
+ * @since 1.4
+ */
+public final class NumericShaper implements Serializable
+{
+ private static final long serialVersionUID = -8022764705923730308L;
+
+ public static final int ALL_RANGES = 524287;
+ public static final int ARABIC = 2;
+ public static final int BENGALI = 16;
+ public static final int DEVANAGARI = 8;
+ public static final int EASTERN_ARABIC = 4;
+ public static final int ETHIOPIC = 65536;
+ public static final int EUROPEAN = 1;
+ public static final int GUJARATI = 64;
+ public static final int GURMUKHI = 32;
+ public static final int KANNADA = 1024;
+ public static final int KHMER = 131072;
+ public static final int LAO = 8192;
+ public static final int MALAYALAM = 2048;
+ public static final int MONGOLIAN = 262144;
+ public static final int MYANMAR = 32768;
+ public static final int ORIYA = 128;
+ public static final int TAMIL = 256;
+ public static final int TELUGU = 512;
+ public static final int THAI = 4096;
+ public static final int TIBETAN = 16384;
+
+ private int ranges;
+ private int context;
+
+ private NumericShaper (int ranges, int context)
+ {
+ this.ranges = ranges;
+ this.context = context;
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof NumericShaper))
+ return false;
+
+ NumericShaper tmp = (NumericShaper) obj;
+
+ return (ranges == tmp.ranges
+ && context == tmp.context);
+ }
+
+ public static NumericShaper getContextualShaper (int ranges)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public static NumericShaper getContextualShaper (int ranges,
+ int defaultContext)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int getRanges ()
+ {
+ return ranges;
+ }
+
+ public static NumericShaper getShaper (int singleRange)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int hashCode ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public boolean isContextual ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public void shape (char[] text, int start, int count)
+ {
+ shape (text, start, count, context);
+ }
+
+ public void shape (char[] text, int start, int count, int context)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public String toString ()
+ {
+ throw new Error ("not implemented");
+ }
+}
diff --git a/libjava/classpath/java/awt/font/OpenType.java b/libjava/classpath/java/awt/font/OpenType.java
new file mode 100644
index 0000000..ece3279
--- /dev/null
+++ b/libjava/classpath/java/awt/font/OpenType.java
@@ -0,0 +1,111 @@
+/* OpenType.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+/**
+ * @author Michael Koch
+ */
+public interface OpenType
+{
+ int TAG_ACNT = 1633906292;
+ int TAG_AVAR = 1635148146;
+ int TAG_BASE = 1111577413;
+ int TAG_BDAT = 1650745716;
+ int TAG_BLOC = 1651273571;
+ int TAG_BSLN = 1651731566;
+ int TAG_CFF = 1128678944;
+ int TAG_CMAP = 1668112752;
+ int TAG_CVAR = 1668702578;
+ int TAG_CVT = 1668707360;
+ int TAG_DSIG = 1146308935;
+ int TAG_EBDT = 1161970772;
+ int TAG_EBLC = 1161972803;
+ int TAG_EBSC = 1161974595;
+ int TAG_FDSC = 1717859171;
+ int TAG_FEAT = 1717920116;
+ int TAG_FMTX = 1718449272;
+ int TAG_FPGM = 1718642541;
+ int TAG_FVAR = 1719034226;
+ int TAG_GASP = 1734439792;
+ int TAG_GDEF = 1195656518;
+ int TAG_GLYF = 1735162214;
+ int TAG_GPOS = 1196445523;
+ int TAG_GSUB = 1196643650;
+ int TAG_GVAR = 1735811442;
+ int TAG_HDMX = 1751412088;
+ int TAG_HEAD = 1751474532;
+ int TAG_HHEA = 1751672161;
+ int TAG_HMTX = 1752003704;
+ int TAG_JSTF = 1246975046;
+ int TAG_JUST = 1786082164;
+ int TAG_KERN = 1801810542;
+ int TAG_LCAR = 1818452338;
+ int TAG_LOCA = 1819239265;
+ int TAG_LTSH = 1280594760;
+ int TAG_MAXP = 1835104368;
+ int TAG_MMFX = 1296909912;
+ int TAG_MMSD = 1296913220;
+ int TAG_MORT = 1836020340;
+ int TAG_NAME = 1851878757;
+ int TAG_OPBD = 1836020340;
+ int TAG_OS2 = 1330851634;
+ int TAG_PCLT = 1346587732;
+ int TAG_POST = 1886352244;
+ int TAG_PREP = 1886545264;
+ int TAG_PROP = 1886547824;
+ int TAG_TRAK = 1953653099;
+ int TAG_TYP1 = 1954115633;
+ int TAG_VDMX = 1447316824;
+ int TAG_VHEA = 1986553185;
+ int TAG_VMTX = 1986884728;
+
+ byte[] getFontTable (int sfntTag);
+
+ byte[] getFontTable (int sfntTag, int offset, int count);
+
+ byte[] getFontTable (String strSfntTag);
+
+ byte[] getFontTable (String strSfntTag, int offset, int count);
+
+ int getFontTableSize (int sfntTag);
+
+ int getFontTableSize (String strSfntTag);
+
+ int getVersion ();
+}
diff --git a/libjava/classpath/java/awt/font/ShapeGraphicAttribute.java b/libjava/classpath/java/awt/font/ShapeGraphicAttribute.java
new file mode 100644
index 0000000..6d64dec
--- /dev/null
+++ b/libjava/classpath/java/awt/font/ShapeGraphicAttribute.java
@@ -0,0 +1,105 @@
+/* ShapeGraphicAttribute.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.Rectangle2D;
+
+public final class ShapeGraphicAttribute extends GraphicAttribute
+{
+ public static final boolean FILL = false;
+ public static final boolean STROKE = true;
+
+ private Shape shape;
+ private boolean stroke;
+
+ public ShapeGraphicAttribute (Shape shape, int alignment, boolean stroke)
+ {
+ super (alignment);
+ this.shape = shape;
+ this.stroke = stroke;
+ }
+
+ public void draw (Graphics2D graphics, float x, float y)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof ShapeGraphicAttribute))
+ return false;
+
+ return equals ((ShapeGraphicAttribute) obj);
+ }
+
+ public boolean equals (ShapeGraphicAttribute rhs)
+ {
+ return (shape.equals (rhs.shape)
+ && getAlignment () == rhs.getAlignment ()
+ && stroke == rhs.stroke);
+ }
+
+ public float getAdvance ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public float getAscent ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public Rectangle2D getBounds ()
+ {
+ return shape.getBounds2D ();
+ }
+
+ public float getDescent ()
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int hashCode ()
+ {
+ // FIXME: Check what SUN does here
+ return shape.hashCode ();
+ }
+}
diff --git a/libjava/classpath/java/awt/font/TextAttribute.java b/libjava/classpath/java/awt/font/TextAttribute.java
new file mode 100644
index 0000000..6f5ed59
--- /dev/null
+++ b/libjava/classpath/java/awt/font/TextAttribute.java
@@ -0,0 +1,309 @@
+/* TextAttribute.java --
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.io.InvalidObjectException;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * Attributes (and associated values) that can be used to define an
+ * {@link java.text.AttributedString}.
+ */
+public final class TextAttribute extends AttributedCharacterIterator.Attribute
+{
+ private static final long serialVersionUID = 7744112784117861702L;
+
+ /** A key for the background paint attribute. */
+ public static final TextAttribute BACKGROUND =
+ new TextAttribute("background");
+
+ /** A key for the BIDI_EMBEDDING attribute. */
+ public static final TextAttribute BIDI_EMBEDDING =
+ new TextAttribute("bidi_embedding");
+
+ /** A key for the CHAR_REPLACEMENT attribute. */
+ public static final TextAttribute CHAR_REPLACEMENT =
+ new TextAttribute("char_replacement");
+
+ /** A key for the FAMILY attribute. */
+ public static final TextAttribute FAMILY = new TextAttribute("family");
+
+ /** A key for the font attribute. */
+ public static final TextAttribute FONT = new TextAttribute("font");
+
+ /** A key for the foreground paint attribute. */
+ public static final TextAttribute FOREGROUND =
+ new TextAttribute("foreground");
+
+ /** A key for the INPUT_METHOD_HIGHLIGHT attribute. */
+ public static final TextAttribute INPUT_METHOD_HIGHLIGHT =
+ new TextAttribute("input method highlight");
+
+ /** A key for the INPUT_METHOD_UNDERLINE attribute. */
+ public static final TextAttribute INPUT_METHOD_UNDERLINE =
+ new TextAttribute("input method underline");
+
+ /** A key for the text justification attribute. */
+ public static final TextAttribute JUSTIFICATION =
+ new TextAttribute("justification");
+
+ /**
+ * A value that can be used with the {@link #JUSTIFICATION} attribute to
+ * indicate full justification of the text.
+ */
+ public static final Float JUSTIFICATION_FULL = new Float(1.0);
+
+ /**
+ * A value that can be used with the {@link #JUSTIFICATION} attribute to
+ * indicate no justification of the text.
+ */
+ public static final Float JUSTIFICATION_NONE = new Float(0.0);
+
+ /** A key for the NUMERIC_SHAPING attribute. */
+ public static final TextAttribute NUMERIC_SHAPING =
+ new TextAttribute("numeric_shaping");
+
+ /** A key for the POSTURE attribute. */
+ public static final TextAttribute POSTURE = new TextAttribute("posture");
+
+ /** A value that can be used with the {@link #POSTURE} attribute. */
+ public static final Float POSTURE_OBLIQUE = new Float(0.2);
+
+ /** A value that can be used with the {@link #POSTURE} attribute. */
+ public static final Float POSTURE_REGULAR = new Float(0.0);
+
+ /** A key for the RUN_DIRECTION attribute. */
+ public static final TextAttribute RUN_DIRECTION =
+ new TextAttribute("run_direction");
+
+ /** A value that can be used with the {@link #RUN_DIRECTION} attribute. */
+ public static final Boolean RUN_DIRECTION_LTR = Boolean.FALSE;
+
+ /** A value that can be used with the {@link #RUN_DIRECTION} attribute. */
+ public static final Boolean RUN_DIRECTION_RTL = Boolean.TRUE;
+
+ /** A key for the text size attribute. */
+ public static final TextAttribute SIZE = new TextAttribute("size");
+
+ /** A key for the STRIKETHROUGH attribute. */
+ public static final TextAttribute STRIKETHROUGH =
+ new TextAttribute("strikethrough");
+
+ /** A value that can be used with the {@link #STRIKETHROUGH} attribute. */
+ public static final Boolean STRIKETHROUGH_ON = Boolean.TRUE;
+
+ /** A key for the SUPERSCRIPT attribute. */
+ public static final TextAttribute SUPERSCRIPT =
+ new TextAttribute("superscript");
+
+ /** A value that can be used with the {@link #SUPERSCRIPT} attribute. */
+ public static final Integer SUPERSCRIPT_SUB = new Integer(-1);
+
+ /** A value that can be used with the {@link #SUPERSCRIPT} attribute. */
+ public static final Integer SUPERSCRIPT_SUPER = new Integer(1);
+
+ /** A key for the SWAP_COLORS attribute. */
+ public static final TextAttribute SWAP_COLORS =
+ new TextAttribute("swap_colors");
+
+ /** A value that can be used with the {@link #SWAP_COLORS} attribute. */
+ public static final Boolean SWAP_COLORS_ON = Boolean.TRUE;
+
+ /** A key for the TRANFORM attribute. */
+ public static final TextAttribute TRANSFORM = new TextAttribute("transform");
+
+ /** A key for the UNDERLINE attribute. */
+ public static final TextAttribute UNDERLINE = new TextAttribute("underline");
+
+ /** A value that can be used with the {@link #UNDERLINE} attribute. */
+ public static final Integer UNDERLINE_LOW_DASHED = new Integer(5);
+
+ /** A value that can be used with the {@link #UNDERLINE} attribute. */
+ public static final Integer UNDERLINE_LOW_DOTTED = new Integer(3);
+
+ /** A value that can be used with the {@link #UNDERLINE} attribute. */
+ public static final Integer UNDERLINE_LOW_GRAY = new Integer(4);
+
+ /** A value that can be used with the {@link #UNDERLINE} attribute. */
+ public static final Integer UNDERLINE_LOW_ONE_PIXEL = new Integer(1);
+
+ /** A value that can be used with the {@link #UNDERLINE} attribute. */
+ public static final Integer UNDERLINE_LOW_TWO_PIXEL = new Integer(2);
+
+ /** A value that can be used with the {@link #UNDERLINE} attribute. */
+ public static final Integer UNDERLINE_ON = new Integer(0);
+
+ /** A key for the WEIGHT attribute. */
+ public static final TextAttribute WEIGHT = new TextAttribute("weight");
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_BOLD = new Float(2.0);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_DEMIBOLD = new Float(1.75);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_DEMILIGHT = new Float(0.875);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_EXTRA_LIGHT = new Float(0.5);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_EXTRABOLD = new Float(2.5);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_HEAVY = new Float(2.25);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_LIGHT = new Float(0.75);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_MEDIUM = new Float(1.5);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_REGULAR = new Float(1.0);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_SEMIBOLD = new Float(1.25);
+
+ /** A value that can be used with the {@link #WEIGHT} attribute. */
+ public static final Float WEIGHT_ULTRABOLD = new Float(2.75);
+
+ /** A key for the WIDTH attribute. */
+ public static final TextAttribute WIDTH = new TextAttribute("width");
+
+ /** A value that can be used with the {@link #WIDTH} attribute. */
+ public static final Float WIDTH_CONDENSED = new Float(0.75);
+
+ /** A value that can be used with the {@link #WIDTH} attribute. */
+ public static final Float WIDTH_EXTENDED = new Float(1.5);
+
+ /** A value that can be used with the {@link #WIDTH} attribute. */
+ public static final Float WIDTH_REGULAR = new Float(1.0);
+
+ /** A value that can be used with the {@link #WIDTH} attribute. */
+ public static final Float WIDTH_SEMI_CONDENSED = new Float(0.875);
+
+ /** A value that can be used with the {@link #WIDTH} attribute. */
+ public static final Float WIDTH_SEMI_EXTENDED = new Float(1.25);
+
+ /**
+ * Creates a new attribute.
+ *
+ * @param name the name.
+ */
+ protected TextAttribute(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * After deserialization, this method ensures that only one instance of
+ * each attribute is used.
+ *
+ * @return The (single) attribute instance.
+ *
+ * @throws InvalidObjectException if the attribute is not recognised.
+ */
+ protected Object readResolve()
+ throws InvalidObjectException
+ {
+ if (this.getName().equals("background"))
+ return BACKGROUND;
+
+ if (this.getName().equals("bidi_embedding"))
+ return BIDI_EMBEDDING;
+
+ if (this.getName().equals("char_replacement"))
+ return CHAR_REPLACEMENT;
+
+ if (this.getName().equals("family"))
+ return FAMILY;
+
+ if (this.getName().equals("font"))
+ return FONT;
+
+ if (this.getName().equals("foreground"))
+ return FOREGROUND;
+
+ if (this.getName().equals("input method highlight"))
+ return INPUT_METHOD_HIGHLIGHT;
+
+ if (this.getName().equals("input method underline"))
+ return INPUT_METHOD_UNDERLINE;
+
+ if (this.getName().equals("justification"))
+ return JUSTIFICATION;
+
+ if (this.getName().equals("numeric_shaping"))
+ return NUMERIC_SHAPING;
+
+ if (this.getName().equals("posture"))
+ return POSTURE;
+
+ if (this.getName().equals("run_direction"))
+ return RUN_DIRECTION;
+
+ if (this.getName().equals("size"))
+ return SIZE;
+
+ if (this.getName().equals("strikethrough"))
+ return STRIKETHROUGH;
+
+ if (this.getName().equals("superscript"))
+ return SUPERSCRIPT;
+
+ if (this.getName().equals("swap_colors"))
+ return SWAP_COLORS;
+
+ if (this.getName().equals("transform"))
+ return TRANSFORM;
+
+ if (this.getName().equals("underline"))
+ return UNDERLINE;
+
+ if (this.getName().equals("weight"))
+ return WEIGHT;
+
+ if (this.getName().equals("width"))
+ return WIDTH;
+
+ throw new InvalidObjectException("Can't resolve Attribute: " + getName());
+ }
+}
diff --git a/libjava/classpath/java/awt/font/TextHitInfo.java b/libjava/classpath/java/awt/font/TextHitInfo.java
new file mode 100644
index 0000000..2b23e19
--- /dev/null
+++ b/libjava/classpath/java/awt/font/TextHitInfo.java
@@ -0,0 +1,125 @@
+/* TextHitInfo.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.font;
+
+/**
+ * @author John Leuner (jewel@debian.org)
+ */
+public final class TextHitInfo
+{
+ private int charIndex;
+ private boolean leadingEdge;
+
+ TextHitInfo (int charIndex, boolean leadingEdge)
+ {
+ this.charIndex = charIndex;
+ this.leadingEdge = leadingEdge;
+ }
+
+ public int getCharIndex()
+ {
+ return charIndex;
+ }
+
+ public boolean isLeadingEdge()
+ {
+ return leadingEdge;
+ }
+
+ public int getInsertionIndex()
+ {
+ return (leadingEdge ? charIndex : charIndex + 1);
+ }
+
+ public int hashCode()
+ {
+ return charIndex;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if(obj instanceof TextHitInfo)
+ return this.equals((TextHitInfo) obj);
+
+ return false;
+ }
+
+ public boolean equals(TextHitInfo hitInfo)
+ {
+ return (charIndex == hitInfo.getCharIndex ())
+ && (leadingEdge == hitInfo.isLeadingEdge ());
+ }
+
+ public static TextHitInfo leading(int charIndex)
+ {
+ return new TextHitInfo (charIndex, true);
+ }
+
+ public static TextHitInfo trailing(int charIndex)
+ {
+ return new TextHitInfo (charIndex, false);
+ }
+
+ public static TextHitInfo beforeOffset(int offset)
+ {
+ return new TextHitInfo (offset, false);
+ }
+
+ public static TextHitInfo afterOffset(int offset)
+ {
+ return new TextHitInfo (offset, true);
+ }
+
+ public TextHitInfo getOtherHit()
+ {
+ return (leadingEdge ? trailing (charIndex - 1) : leading (charIndex + 1));
+ }
+
+ public TextHitInfo getOffsetHit(int offset)
+ {
+ return new TextHitInfo (charIndex + offset, leadingEdge);
+ }
+
+ public String toString()
+ {
+ return "TextHitInfo["
+ + charIndex
+ + (leadingEdge ? "L" : "T" )
+ + "]";
+ }
+}
diff --git a/libjava/classpath/java/awt/font/TextLayout.java b/libjava/classpath/java/awt/font/TextLayout.java
new file mode 100644
index 0000000..bb64161
--- /dev/null
+++ b/libjava/classpath/java/awt/font/TextLayout.java
@@ -0,0 +1,332 @@
+/* TextLayout.java --
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import gnu.java.awt.ClasspathToolkit;
+import gnu.java.awt.peer.ClasspathTextLayoutPeer;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.Toolkit;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.util.Map;
+
+/**
+ * @author Michael Koch
+ */
+public final class TextLayout implements Cloneable
+{
+ public static final CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy ();
+ ClasspathTextLayoutPeer peer;
+
+ public static class CaretPolicy
+ {
+ public CaretPolicy ()
+ {
+ // Do nothing here.
+ }
+
+ public TextHitInfo getStrongCaret (TextHitInfo hit1, TextHitInfo hit2,
+ TextLayout layout)
+ {
+ return layout.peer.getStrongCaret(hit1, hit2);
+ }
+ }
+
+ public TextLayout (AttributedCharacterIterator text, FontRenderContext frc)
+ {
+ AttributedString as = new AttributedString (text);
+ ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ peer = tk.getClasspathTextLayoutPeer(as, frc);
+ }
+
+ public TextLayout (String string, Font font, FontRenderContext frc)
+ {
+ AttributedString as = new AttributedString (string);
+ as.addAttribute (TextAttribute.FONT, font);
+ ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ peer = tk.getClasspathTextLayoutPeer(as, frc);
+ }
+
+ public TextLayout (String string, Map attributes, FontRenderContext frc)
+ {
+ AttributedString as = new AttributedString (string, attributes);
+ ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ peer = tk.getClasspathTextLayoutPeer(as, frc);
+ }
+
+ protected Object clone ()
+ {
+ try
+ {
+ TextLayout tl = (TextLayout) super.clone ();
+ tl.peer = (ClasspathTextLayoutPeer) this.peer.clone();
+ return tl;
+ }
+ catch (CloneNotSupportedException e)
+ {
+ // This should never occur
+ throw new InternalError ();
+ }
+ }
+
+
+ public void draw (Graphics2D g2, float x, float y)
+ {
+ peer.draw(g2, x, y);
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof TextLayout))
+ return false;
+
+ return equals ((TextLayout) obj);
+ }
+
+ public boolean equals (TextLayout tl)
+ {
+ return this.peer.equals(tl.peer);
+ }
+
+ public float getAdvance ()
+ {
+ return peer.getAdvance();
+ }
+
+ public float getAscent ()
+ {
+ return peer.getAscent();
+ }
+
+ public byte getBaseline ()
+ {
+ return peer.getBaseline();
+ }
+
+ public float[] getBaselineOffsets ()
+ {
+ return peer.getBaselineOffsets();
+ }
+
+ public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint)
+ {
+ return peer.getBlackBoxBounds(firstEndpoint, secondEndpoint);
+ }
+
+ public Rectangle2D getBounds()
+ {
+ return peer.getBounds();
+ }
+
+ public float[] getCaretInfo (TextHitInfo hit)
+ {
+ return getCaretInfo(hit, getBounds());
+ }
+
+ public float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds)
+ {
+ return peer.getCaretInfo(hit, bounds);
+ }
+
+ public Shape getCaretShape (TextHitInfo hit)
+ {
+ return getCaretShape(hit, getBounds());
+ }
+
+ public Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds)
+ {
+ return peer.getCaretShape(hit, bounds);
+ }
+
+ public Shape[] getCaretShapes (int offset)
+ {
+ return getCaretShapes(offset, getBounds());
+ }
+
+ public Shape[] getCaretShapes (int offset, Rectangle2D bounds)
+ {
+ return getCaretShapes(offset, getBounds(), DEFAULT_CARET_POLICY);
+ }
+
+ public Shape[] getCaretShapes (int offset, Rectangle2D bounds,
+ TextLayout.CaretPolicy policy)
+ {
+ return peer.getCaretShapes(offset, bounds, policy);
+ }
+
+ public int getCharacterCount ()
+ {
+ return peer.getCharacterCount();
+ }
+
+ public byte getCharacterLevel (int index)
+ {
+ return peer.getCharacterLevel(index);
+ }
+
+ public float getDescent ()
+ {
+ return peer.getDescent();
+ }
+
+ public TextLayout getJustifiedLayout (float justificationWidth)
+ {
+ return peer.getJustifiedLayout(justificationWidth);
+ }
+
+ public float getLeading ()
+ {
+ return peer.getLeading();
+ }
+
+ public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint)
+ {
+ return getLogicalHighlightShape (firstEndpoint, secondEndpoint, getBounds());
+ }
+
+ public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint,
+ Rectangle2D bounds)
+ {
+ return peer.getLogicalHighlightShape(firstEndpoint, secondEndpoint, bounds);
+ }
+
+ public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint,
+ TextHitInfo secondEndpoint)
+ {
+ return peer.getLogicalRangesForVisualSelection(firstEndpoint, secondEndpoint);
+ }
+
+ public TextHitInfo getNextLeftHit (int offset)
+ {
+ return getNextLeftHit(offset, DEFAULT_CARET_POLICY);
+ }
+
+ public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy)
+ {
+ return peer.getNextLeftHit(offset, policy);
+ }
+
+ public TextHitInfo getNextLeftHit (TextHitInfo hit)
+ {
+ return getNextLeftHit(hit.getCharIndex());
+ }
+
+ public TextHitInfo getNextRightHit (int offset)
+ {
+ return getNextRightHit(offset, DEFAULT_CARET_POLICY);
+ }
+
+ public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy)
+ {
+ return peer.getNextRightHit(offset, policy);
+ }
+
+ public TextHitInfo getNextRightHit (TextHitInfo hit)
+ {
+ return getNextRightHit(hit.getCharIndex());
+ }
+
+ public Shape getOutline (AffineTransform tx)
+ {
+ return peer.getOutline(tx);
+ }
+
+ public float getVisibleAdvance ()
+ {
+ return peer.getVisibleAdvance();
+ }
+
+ public Shape getVisualHighlightShape (TextHitInfo firstEndpoint,
+ TextHitInfo secondEndpoint)
+ {
+ return getVisualHighlightShape(firstEndpoint, secondEndpoint, getBounds());
+ }
+
+ public Shape getVisualHighlightShape (TextHitInfo firstEndpoint,
+ TextHitInfo secondEndpoint,
+ Rectangle2D bounds)
+ {
+ return peer.getVisualHighlightShape(firstEndpoint, secondEndpoint, bounds);
+ }
+
+ public TextHitInfo getVisualOtherHit (TextHitInfo hit)
+ {
+ return peer.getVisualOtherHit(hit);
+ }
+
+ protected void handleJustify (float justificationWidth)
+ {
+ peer.handleJustify(justificationWidth);
+ }
+
+ public int hashCode ()
+ {
+ return peer.hashCode();
+ }
+
+ public TextHitInfo hitTestChar (float x, float y)
+ {
+ return hitTestChar(x, y, getBounds());
+ }
+
+ public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds)
+ {
+ return peer.hitTestChar(x, y, bounds);
+ }
+
+ public boolean isLeftToRight ()
+ {
+ return peer.isLeftToRight();
+ }
+
+ public boolean isVertical ()
+ {
+ return peer.isVertical();
+ }
+
+ public String toString ()
+ {
+ return peer.toString();
+ }
+}
diff --git a/libjava/classpath/java/awt/font/TextMeasurer.java b/libjava/classpath/java/awt/font/TextMeasurer.java
new file mode 100644
index 0000000..7fcdc87
--- /dev/null
+++ b/libjava/classpath/java/awt/font/TextMeasurer.java
@@ -0,0 +1,97 @@
+/* TextMeasurer.java
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.text.AttributedCharacterIterator;
+
+/**
+ * @author Michael Koch
+ * @since 1.3
+ */
+public final class TextMeasurer implements Cloneable
+{
+ private AttributedCharacterIterator ci;
+ private FontRenderContext frc;
+
+ public TextMeasurer (AttributedCharacterIterator text, FontRenderContext frc)
+ {
+ this.ci = text;
+ this.frc = frc;
+ }
+
+ protected Object clone ()
+ {
+ try
+ {
+ return super.clone ();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ // This may never occur
+ throw new InternalError ();
+ }
+ }
+
+ public void deleteChar (AttributedCharacterIterator newParagraph,
+ int deletePos)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public float getAdvanceBetween (int start, int limit)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public TextLayout getLayout (int start, int limit)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public int getLineBreakIndex (int start, float maxAdvance)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public void insertChar (AttributedCharacterIterator newParagraph,
+ int insertPos)
+ {
+ throw new Error ("not implemented");
+ }
+}
diff --git a/libjava/classpath/java/awt/font/TransformAttribute.java b/libjava/classpath/java/awt/font/TransformAttribute.java
new file mode 100644
index 0000000..977cafa
--- /dev/null
+++ b/libjava/classpath/java/awt/font/TransformAttribute.java
@@ -0,0 +1,100 @@
+/* TransformAttribute.java --
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
+
+/**
+ * This class provides a mechanism for using an {@link AffineTransform} as
+ * an <i>immutable</i> attribute (for example, in the
+ * {@link java.text.AttributedString} class). Any transform passed to
+ * this class is copied before being stored, and any transform handed out
+ * by this class is a copy of the stored transform. In this way, it is
+ * not possible to modify the stored transform.
+ *
+ * @author Michael Koch
+ */
+public final class TransformAttribute implements Serializable
+{
+ private static final long serialVersionUID = 3356247357827709530L;
+
+ private AffineTransform affineTransform;
+
+ /**
+ * Creates a new attribute that contains a copy of the given transform.
+ *
+ * @param transform the transform (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>transform</code> is
+ * <code>null</code>.
+ */
+ public TransformAttribute (AffineTransform transform)
+ {
+ if (transform == null)
+ {
+ throw new IllegalArgumentException("Null 'transform' not permitted.");
+ }
+ this.affineTransform = new AffineTransform (transform);
+ }
+
+ /**
+ * Returns a copy of the transform contained by this attribute.
+ *
+ * @return A copy of the transform.
+ */
+ public AffineTransform getTransform ()
+ {
+ return (AffineTransform) affineTransform.clone();
+ }
+
+ /**
+ * Returns <code>true</code> if the transform contained by this attribute is
+ * an identity transform, and <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the transform contained by this attribute is
+ * an identity transform, and <code>false</code> otherwise.
+ *
+ * @since 1.4
+ */
+ public boolean isIdentity ()
+ {
+ return (affineTransform == null ? false : affineTransform.isIdentity ());
+ }
+}
diff --git a/libjava/classpath/java/awt/font/package.html b/libjava/classpath/java/awt/font/package.html
new file mode 100644
index 0000000..8c3c61a
--- /dev/null
+++ b/libjava/classpath/java/awt/font/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.font package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.font</title></head>
+
+<body>
+<p>Representations of different kind of characters and fonts.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/geom/AffineTransform.java b/libjava/classpath/java/awt/geom/AffineTransform.java
new file mode 100644
index 0000000..4d1a4d6
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/AffineTransform.java
@@ -0,0 +1,1487 @@
+/* AffineTransform.java -- transform coordinates between two 2-D spaces
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.geom;
+
+import java.awt.Shape;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+/**
+ * This class represents an affine transformation between two coordinate
+ * spaces in 2 dimensions. Such a transform preserves the "straightness"
+ * and "parallelness" of lines. The transform is built from a sequence of
+ * translations, scales, flips, rotations, and shears.
+ *
+ * <p>The transformation can be represented using matrix math on a 3x3 array.
+ * Given (x,y), the transformation (x',y') can be found by:
+ * <pre>
+ * [ x'] [ m00 m01 m02 ] [ x ] [ m00*x + m01*y + m02 ]
+ * [ y'] = [ m10 m11 m12 ] [ y ] = [ m10*x + m11*y + m12 ]
+ * [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
+ * </pre>
+ * The bottom row of the matrix is constant, so a transform can be uniquely
+ * represented (as in {@link #toString()}) by
+ * "[[m00, m01, m02], [m10, m11, m12]]".
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status partially updated to 1.4, still has some problems
+ */
+public class AffineTransform implements Cloneable, Serializable
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 1330973210523860834L;
+
+ /**
+ * The transformation is the identity (x' = x, y' = y). All other transforms
+ * have either a combination of the appropriate transform flag bits for
+ * their type, or the type GENERAL_TRANSFORM.
+ *
+ * @see #TYPE_TRANSLATION
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_GENERAL_SCALE
+ * @see #TYPE_FLIP
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_ROTATION
+ * @see #TYPE_GENERAL_TRANSFORM
+ * @see #getType()
+ */
+ public static final int TYPE_IDENTITY = 0;
+
+ /**
+ * The transformation includes a translation - shifting in the x or y
+ * direction without changing length or angles.
+ *
+ * @see #TYPE_IDENTITY
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_GENERAL_SCALE
+ * @see #TYPE_FLIP
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_ROTATION
+ * @see #TYPE_GENERAL_TRANSFORM
+ * @see #getType()
+ */
+ public static final int TYPE_TRANSLATION = 1;
+
+ /**
+ * The transformation includes a uniform scale - length is scaled in both
+ * the x and y directions by the same amount, without affecting angles.
+ * This is mutually exclusive with TYPE_GENERAL_SCALE.
+ *
+ * @see #TYPE_IDENTITY
+ * @see #TYPE_TRANSLATION
+ * @see #TYPE_GENERAL_SCALE
+ * @see #TYPE_FLIP
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_ROTATION
+ * @see #TYPE_GENERAL_TRANSFORM
+ * @see #TYPE_MASK_SCALE
+ * @see #getType()
+ */
+ public static final int TYPE_UNIFORM_SCALE = 2;
+
+ /**
+ * The transformation includes a general scale - length is scaled in either
+ * or both the x and y directions, but by different amounts; without
+ * affecting angles. This is mutually exclusive with TYPE_UNIFORM_SCALE.
+ *
+ * @see #TYPE_IDENTITY
+ * @see #TYPE_TRANSLATION
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_FLIP
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_ROTATION
+ * @see #TYPE_GENERAL_TRANSFORM
+ * @see #TYPE_MASK_SCALE
+ * @see #getType()
+ */
+ public static final int TYPE_GENERAL_SCALE = 4;
+
+ /**
+ * This constant checks if either variety of scale transform is performed.
+ *
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_GENERAL_SCALE
+ */
+ public static final int TYPE_MASK_SCALE = 6;
+
+ /**
+ * The transformation includes a flip about an axis, swapping between
+ * right-handed and left-handed coordinate systems. In a right-handed
+ * system, the positive x-axis rotates counter-clockwise to the positive
+ * y-axis; in a left-handed system it rotates clockwise.
+ *
+ * @see #TYPE_IDENTITY
+ * @see #TYPE_TRANSLATION
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_GENERAL_SCALE
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_ROTATION
+ * @see #TYPE_GENERAL_TRANSFORM
+ * @see #getType()
+ */
+ public static final int TYPE_FLIP = 64;
+
+ /**
+ * The transformation includes a rotation of a multiple of 90 degrees (PI/2
+ * radians). Angles are rotated, but length is preserved. This is mutually
+ * exclusive with TYPE_GENERAL_ROTATION.
+ *
+ * @see #TYPE_IDENTITY
+ * @see #TYPE_TRANSLATION
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_GENERAL_SCALE
+ * @see #TYPE_FLIP
+ * @see #TYPE_GENERAL_ROTATION
+ * @see #TYPE_GENERAL_TRANSFORM
+ * @see #TYPE_MASK_ROTATION
+ * @see #getType()
+ */
+ public static final int TYPE_QUADRANT_ROTATION = 8;
+
+ /**
+ * The transformation includes a rotation by an arbitrary angle. Angles are
+ * rotated, but length is preserved. This is mutually exclusive with
+ * TYPE_QUADRANT_ROTATION.
+ *
+ * @see #TYPE_IDENTITY
+ * @see #TYPE_TRANSLATION
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_GENERAL_SCALE
+ * @see #TYPE_FLIP
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_TRANSFORM
+ * @see #TYPE_MASK_ROTATION
+ * @see #getType()
+ */
+ public static final int TYPE_GENERAL_ROTATION = 16;
+
+ /**
+ * This constant checks if either variety of rotation is performed.
+ *
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_ROTATION
+ */
+ public static final int TYPE_MASK_ROTATION = 24;
+
+ /**
+ * The transformation is an arbitrary conversion of coordinates which
+ * could not be decomposed into the other TYPEs.
+ *
+ * @see #TYPE_IDENTITY
+ * @see #TYPE_TRANSLATION
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_GENERAL_SCALE
+ * @see #TYPE_FLIP
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_ROTATION
+ * @see #getType()
+ */
+ public static final int TYPE_GENERAL_TRANSFORM = 32;
+
+ /**
+ * The X coordinate scaling element of the transform matrix.
+ *
+ * @serial matrix[0,0]
+ */
+ private double m00;
+
+ /**
+ * The Y coordinate shearing element of the transform matrix.
+ *
+ * @serial matrix[1,0]
+ */
+ private double m10;
+
+ /**
+ * The X coordinate shearing element of the transform matrix.
+ *
+ * @serial matrix[0,1]
+ */
+ private double m01;
+
+ /**
+ * The Y coordinate scaling element of the transform matrix.
+ *
+ * @serial matrix[1,1]
+ */
+ private double m11;
+
+ /**
+ * The X coordinate translation element of the transform matrix.
+ *
+ * @serial matrix[0,2]
+ */
+ private double m02;
+
+ /**
+ * The Y coordinate translation element of the transform matrix.
+ *
+ * @serial matrix[1,2]
+ */
+ private double m12;
+
+ /** The type of this transform. */
+ private transient int type;
+
+ /**
+ * Construct a new identity transform:
+ * <pre>
+ * [ 1 0 0 ]
+ * [ 0 1 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ */
+ public AffineTransform()
+ {
+ m00 = m11 = 1;
+ }
+
+ /**
+ * Create a new transform which copies the given one.
+ *
+ * @param tx the transform to copy
+ * @throws NullPointerException if tx is null
+ */
+ public AffineTransform(AffineTransform tx)
+ {
+ setTransform(tx);
+ }
+
+ /**
+ * Construct a transform with the given matrix entries:
+ * <pre>
+ * [ m00 m01 m02 ]
+ * [ m10 m11 m12 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param m00 the x scaling component
+ * @param m10 the y shearing component
+ * @param m01 the x shearing component
+ * @param m11 the y scaling component
+ * @param m02 the x translation component
+ * @param m12 the y translation component
+ */
+ public AffineTransform(float m00, float m10,
+ float m01, float m11,
+ float m02, float m12)
+ {
+ this.m00 = m00;
+ this.m10 = m10;
+ this.m01 = m01;
+ this.m11 = m11;
+ this.m02 = m02;
+ this.m12 = m12;
+ updateType();
+ }
+
+ /**
+ * Construct a transform from a sequence of float entries. The array must
+ * have at least 4 entries, which has a translation factor of 0; or 6
+ * entries, for specifying all parameters:
+ * <pre>
+ * [ f[0] f[2] (f[4]) ]
+ * [ f[1] f[3] (f[5]) ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param f the matrix to copy from, with at least 4 (6) entries
+ * @throws NullPointerException if f is null
+ * @throws ArrayIndexOutOfBoundsException if f is too small
+ */
+ public AffineTransform(float[] f)
+ {
+ m00 = f[0];
+ m10 = f[1];
+ m01 = f[2];
+ m11 = f[3];
+ if (f.length >= 6)
+ {
+ m02 = f[4];
+ m12 = f[5];
+ }
+ updateType();
+ }
+
+ /**
+ * Construct a transform with the given matrix entries:
+ * <pre>
+ * [ m00 m01 m02 ]
+ * [ m10 m11 m12 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param m00 the x scaling component
+ * @param m10 the y shearing component
+ * @param m01 the x shearing component
+ * @param m11 the y scaling component
+ * @param m02 the x translation component
+ * @param m12 the y translation component
+ */
+ public AffineTransform(double m00, double m10, double m01,
+ double m11, double m02, double m12)
+ {
+ this.m00 = m00;
+ this.m10 = m10;
+ this.m01 = m01;
+ this.m11 = m11;
+ this.m02 = m02;
+ this.m12 = m12;
+ updateType();
+ }
+
+ /**
+ * Construct a transform from a sequence of double entries. The array must
+ * have at least 4 entries, which has a translation factor of 0; or 6
+ * entries, for specifying all parameters:
+ * <pre>
+ * [ d[0] d[2] (d[4]) ]
+ * [ d[1] d[3] (d[5]) ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param d the matrix to copy from, with at least 4 (6) entries
+ * @throws NullPointerException if d is null
+ * @throws ArrayIndexOutOfBoundsException if d is too small
+ */
+ public AffineTransform(double[] d)
+ {
+ m00 = d[0];
+ m10 = d[1];
+ m01 = d[2];
+ m11 = d[3];
+ if (d.length >= 6)
+ {
+ m02 = d[4];
+ m12 = d[5];
+ }
+ updateType();
+ }
+
+ /**
+ * Returns a translation transform:
+ * <pre>
+ * [ 1 0 tx ]
+ * [ 0 1 ty ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param tx the x translation distance
+ * @param ty the y translation distance
+ * @return the translating transform
+ */
+ public static AffineTransform getTranslateInstance(double tx, double ty)
+ {
+ AffineTransform t = new AffineTransform();
+ t.setToTranslation(tx, ty);
+ return t;
+ }
+
+ /**
+ * Returns a rotation transform. A positive angle (in radians) rotates
+ * the positive x-axis to the positive y-axis:
+ * <pre>
+ * [ cos(theta) -sin(theta) 0 ]
+ * [ sin(theta) cos(theta) 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param theta the rotation angle
+ * @return the rotating transform
+ */
+ public static AffineTransform getRotateInstance(double theta)
+ {
+ AffineTransform t = new AffineTransform();
+ t.setToRotation(theta);
+ return t;
+ }
+
+ /**
+ * Returns a rotation transform about a point. A positive angle (in radians)
+ * rotates the positive x-axis to the positive y-axis. This is the same
+ * as calling:
+ * <pre>
+ * AffineTransform tx = new AffineTransform();
+ * tx.setToTranslation(x, y);
+ * tx.rotate(theta);
+ * tx.translate(-x, -y);
+ * </pre>
+ *
+ * <p>The resulting matrix is:
+ * <pre>
+ * [ cos(theta) -sin(theta) x-x*cos+y*sin ]
+ * [ sin(theta) cos(theta) y-x*sin-y*cos ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param theta the rotation angle
+ * @param x the x coordinate of the pivot point
+ * @param y the y coordinate of the pivot point
+ * @return the rotating transform
+ */
+ public static AffineTransform getRotateInstance(double theta,
+ double x, double y)
+ {
+ AffineTransform t = new AffineTransform();
+ t.setToTranslation(x, y);
+ t.rotate(theta);
+ t.translate(-x, -y);
+ return t;
+ }
+
+ /**
+ * Returns a scaling transform:
+ * <pre>
+ * [ sx 0 0 ]
+ * [ 0 sy 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param sx the x scaling factor
+ * @param sy the y scaling factor
+ * @return the scaling transform
+ */
+ public static AffineTransform getScaleInstance(double sx, double sy)
+ {
+ AffineTransform t = new AffineTransform();
+ t.setToScale(sx, sy);
+ return t;
+ }
+
+ /**
+ * Returns a shearing transform (points are shifted in the x direction based
+ * on a factor of their y coordinate, and in the y direction as a factor of
+ * their x coordinate):
+ * <pre>
+ * [ 1 shx 0 ]
+ * [ shy 1 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param shx the x shearing factor
+ * @param shy the y shearing factor
+ * @return the shearing transform
+ */
+ public static AffineTransform getShearInstance(double shx, double shy)
+ {
+ AffineTransform t = new AffineTransform();
+ t.setToShear(shx, shy);
+ return t;
+ }
+
+ /**
+ * Returns the type of this transform. The result is always valid, although
+ * it may not be the simplest interpretation (in other words, there are
+ * sequences of transforms which reduce to something simpler, which this
+ * does not always detect). The result is either TYPE_GENERAL_TRANSFORM,
+ * or a bit-wise combination of TYPE_TRANSLATION, the mutually exclusive
+ * TYPE_*_ROTATIONs, and the mutually exclusive TYPE_*_SCALEs.
+ *
+ * @return The type.
+ *
+ * @see #TYPE_IDENTITY
+ * @see #TYPE_TRANSLATION
+ * @see #TYPE_UNIFORM_SCALE
+ * @see #TYPE_GENERAL_SCALE
+ * @see #TYPE_QUADRANT_ROTATION
+ * @see #TYPE_GENERAL_ROTATION
+ * @see #TYPE_GENERAL_TRANSFORM
+ */
+ public int getType()
+ {
+ return type;
+ }
+
+ /**
+ * Return the determinant of this transform matrix. If the determinant is
+ * non-zero, the transform is invertible; otherwise operations which require
+ * an inverse throw a NoninvertibleTransformException. A result very near
+ * zero, due to rounding errors, may indicate that inversion results do not
+ * carry enough precision to be meaningful.
+ *
+ * <p>If this is a uniform scale transformation, the determinant also
+ * represents the squared value of the scale. Otherwise, it carries little
+ * additional meaning. The determinant is calculated as:
+ * <pre>
+ * | m00 m01 m02 |
+ * | m10 m11 m12 | = m00 * m11 - m01 * m10
+ * | 0 0 1 |
+ * </pre>
+ *
+ * @return the determinant
+ * @see #createInverse()
+ */
+ public double getDeterminant()
+ {
+ return m00 * m11 - m01 * m10;
+ }
+
+ /**
+ * Return the matrix of values used in this transform. If the matrix has
+ * fewer than 6 entries, only the scale and shear factors are returned;
+ * otherwise the translation factors are copied as well. The resulting
+ * values are:
+ * <pre>
+ * [ d[0] d[2] (d[4]) ]
+ * [ d[1] d[3] (d[5]) ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param d the matrix to store the results into; with 4 (6) entries
+ * @throws NullPointerException if d is null
+ * @throws ArrayIndexOutOfBoundsException if d is too small
+ */
+ public void getMatrix(double[] d)
+ {
+ d[0] = m00;
+ d[1] = m10;
+ d[2] = m01;
+ d[3] = m11;
+ if (d.length >= 6)
+ {
+ d[4] = m02;
+ d[5] = m12;
+ }
+ }
+
+ /**
+ * Returns the X coordinate scaling factor of the matrix.
+ *
+ * @return m00
+ * @see #getMatrix(double[])
+ */
+ public double getScaleX()
+ {
+ return m00;
+ }
+
+ /**
+ * Returns the Y coordinate scaling factor of the matrix.
+ *
+ * @return m11
+ * @see #getMatrix(double[])
+ */
+ public double getScaleY()
+ {
+ return m11;
+ }
+
+ /**
+ * Returns the X coordinate shearing factor of the matrix.
+ *
+ * @return m01
+ * @see #getMatrix(double[])
+ */
+ public double getShearX()
+ {
+ return m01;
+ }
+
+ /**
+ * Returns the Y coordinate shearing factor of the matrix.
+ *
+ * @return m10
+ * @see #getMatrix(double[])
+ */
+ public double getShearY()
+ {
+ return m10;
+ }
+
+ /**
+ * Returns the X coordinate translation factor of the matrix.
+ *
+ * @return m02
+ * @see #getMatrix(double[])
+ */
+ public double getTranslateX()
+ {
+ return m02;
+ }
+
+ /**
+ * Returns the Y coordinate translation factor of the matrix.
+ *
+ * @return m12
+ * @see #getMatrix(double[])
+ */
+ public double getTranslateY()
+ {
+ return m12;
+ }
+
+ /**
+ * Concatenate a translation onto this transform. This is equivalent, but
+ * more efficient than
+ * <code>concatenate(AffineTransform.getTranslateInstance(tx, ty))</code>.
+ *
+ * @param tx the x translation distance
+ * @param ty the y translation distance
+ * @see #getTranslateInstance(double, double)
+ * @see #concatenate(AffineTransform)
+ */
+ public void translate(double tx, double ty)
+ {
+ m02 += tx * m00 + ty * m01;
+ m12 += tx * m10 + ty * m11;
+ updateType();
+ }
+
+ /**
+ * Concatenate a rotation onto this transform. This is equivalent, but
+ * more efficient than
+ * <code>concatenate(AffineTransform.getRotateInstance(theta))</code>.
+ *
+ * @param theta the rotation angle
+ * @see #getRotateInstance(double)
+ * @see #concatenate(AffineTransform)
+ */
+ public void rotate(double theta)
+ {
+ double c = Math.cos(theta);
+ double s = Math.sin(theta);
+ double n00 = m00 * c + m01 * s;
+ double n01 = m00 * -s + m01 * c;
+ double n10 = m10 * c + m11 * s;
+ double n11 = m10 * -s + m11 * c;
+ m00 = n00;
+ m01 = n01;
+ m10 = n10;
+ m11 = n11;
+ updateType();
+ }
+
+ /**
+ * Concatenate a rotation about a point onto this transform. This is
+ * equivalent, but more efficient than
+ * <code>concatenate(AffineTransform.getRotateInstance(theta, x, y))</code>.
+ *
+ * @param theta the rotation angle
+ * @param x the x coordinate of the pivot point
+ * @param y the y coordinate of the pivot point
+ * @see #getRotateInstance(double, double, double)
+ * @see #concatenate(AffineTransform)
+ */
+ public void rotate(double theta, double x, double y)
+ {
+ translate(x, y);
+ rotate(theta);
+ translate(-x, -y);
+ }
+
+ /**
+ * Concatenate a scale onto this transform. This is equivalent, but more
+ * efficient than
+ * <code>concatenate(AffineTransform.getScaleInstance(sx, sy))</code>.
+ *
+ * @param sx the x scaling factor
+ * @param sy the y scaling factor
+ * @see #getScaleInstance(double, double)
+ * @see #concatenate(AffineTransform)
+ */
+ public void scale(double sx, double sy)
+ {
+ m00 *= sx;
+ m01 *= sy;
+ m10 *= sx;
+ m11 *= sy;
+ updateType();
+ }
+
+ /**
+ * Concatenate a shearing onto this transform. This is equivalent, but more
+ * efficient than
+ * <code>concatenate(AffineTransform.getShearInstance(sx, sy))</code>.
+ *
+ * @param shx the x shearing factor
+ * @param shy the y shearing factor
+ * @see #getShearInstance(double, double)
+ * @see #concatenate(AffineTransform)
+ */
+ public void shear(double shx, double shy)
+ {
+ double n00 = m00 + (shy * m01);
+ double n01 = m01 + (shx * m00);
+ double n10 = m10 + (shy * m11);
+ double n11 = m11 + (shx * m10);
+ m00 = n00;
+ m01 = n01;
+ m10 = n10;
+ m11 = n11;
+ updateType();
+ }
+
+ /**
+ * Reset this transform to the identity (no transformation):
+ * <pre>
+ * [ 1 0 0 ]
+ * [ 0 1 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ */
+ public void setToIdentity()
+ {
+ m00 = m11 = 1;
+ m01 = m02 = m10 = m12 = 0;
+ type = TYPE_IDENTITY;
+ }
+
+ /**
+ * Set this transform to a translation:
+ * <pre>
+ * [ 1 0 tx ]
+ * [ 0 1 ty ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param tx the x translation distance
+ * @param ty the y translation distance
+ */
+ public void setToTranslation(double tx, double ty)
+ {
+ m00 = m11 = 1;
+ m01 = m10 = 0;
+ m02 = tx;
+ m12 = ty;
+ type = (tx == 0 && ty == 0) ? TYPE_UNIFORM_SCALE : TYPE_TRANSLATION;
+ }
+
+ /**
+ * Set this transform to a rotation. A positive angle (in radians) rotates
+ * the positive x-axis to the positive y-axis:
+ * <pre>
+ * [ cos(theta) -sin(theta) 0 ]
+ * [ sin(theta) cos(theta) 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param theta the rotation angle
+ */
+ public void setToRotation(double theta)
+ {
+ double c = Math.cos(theta);
+ double s = Math.sin(theta);
+ m00 = c;
+ m01 = -s;
+ m02 = 0;
+ m10 = s;
+ m11 = c;
+ m12 = 0;
+ type = (c == 1 ? TYPE_IDENTITY
+ : c == 0 || c == -1 ? TYPE_QUADRANT_ROTATION
+ : TYPE_GENERAL_ROTATION);
+ }
+
+ /**
+ * Set this transform to a rotation about a point. A positive angle (in
+ * radians) rotates the positive x-axis to the positive y-axis. This is the
+ * same as calling:
+ * <pre>
+ * tx.setToTranslation(x, y);
+ * tx.rotate(theta);
+ * tx.translate(-x, -y);
+ * </pre>
+ *
+ * <p>The resulting matrix is:
+ * <pre>
+ * [ cos(theta) -sin(theta) x-x*cos+y*sin ]
+ * [ sin(theta) cos(theta) y-x*sin-y*cos ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param theta the rotation angle
+ * @param x the x coordinate of the pivot point
+ * @param y the y coordinate of the pivot point
+ */
+ public void setToRotation(double theta, double x, double y)
+ {
+ double c = Math.cos(theta);
+ double s = Math.sin(theta);
+ m00 = c;
+ m01 = -s;
+ m02 = x - x * c + y * s;
+ m10 = s;
+ m11 = c;
+ m12 = y - x * s - y * c;
+ updateType();
+ }
+
+ /**
+ * Set this transform to a scale:
+ * <pre>
+ * [ sx 0 0 ]
+ * [ 0 sy 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param sx the x scaling factor
+ * @param sy the y scaling factor
+ */
+ public void setToScale(double sx, double sy)
+ {
+ m00 = sx;
+ m01 = m02 = m10 = m12 = 0;
+ m11 = sy;
+ type = (sx != sy ? TYPE_GENERAL_SCALE
+ : sx == 1 ? TYPE_IDENTITY : TYPE_UNIFORM_SCALE);
+ }
+
+ /**
+ * Set this transform to a shear (points are shifted in the x direction based
+ * on a factor of their y coordinate, and in the y direction as a factor of
+ * their x coordinate):
+ * <pre>
+ * [ 1 shx 0 ]
+ * [ shy 1 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param shx the x shearing factor
+ * @param shy the y shearing factor
+ */
+ public void setToShear(double shx, double shy)
+ {
+ m00 = m11 = 1;
+ m01 = shx;
+ m10 = shy;
+ m02 = m12 = 0;
+ updateType();
+ }
+
+ /**
+ * Set this transform to a copy of the given one.
+ *
+ * @param tx the transform to copy
+ * @throws NullPointerException if tx is null
+ */
+ public void setTransform(AffineTransform tx)
+ {
+ m00 = tx.m00;
+ m01 = tx.m01;
+ m02 = tx.m02;
+ m10 = tx.m10;
+ m11 = tx.m11;
+ m12 = tx.m12;
+ type = tx.type;
+ }
+
+ /**
+ * Set this transform to the given values:
+ * <pre>
+ * [ m00 m01 m02 ]
+ * [ m10 m11 m12 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @param m00 the x scaling component
+ * @param m10 the y shearing component
+ * @param m01 the x shearing component
+ * @param m11 the y scaling component
+ * @param m02 the x translation component
+ * @param m12 the y translation component
+ */
+ public void setTransform(double m00, double m10, double m01,
+ double m11, double m02, double m12)
+ {
+ this.m00 = m00;
+ this.m10 = m10;
+ this.m01 = m01;
+ this.m11 = m11;
+ this.m02 = m02;
+ this.m12 = m12;
+ updateType();
+ }
+
+ /**
+ * Set this transform to the result of performing the original version of
+ * this followed by tx. This is commonly used when chaining transformations
+ * from one space to another. In matrix form:
+ * <pre>
+ * [ this ] = [ this ] x [ tx ]
+ * </pre>
+ *
+ * @param tx the transform to concatenate
+ * @throws NullPointerException if tx is null
+ * @see #preConcatenate(AffineTransform)
+ */
+ public void concatenate(AffineTransform tx)
+ {
+ double n00 = m00 * tx.m00 + m01 * tx.m10;
+ double n01 = m00 * tx.m01 + m01 * tx.m11;
+ double n02 = m00 * tx.m02 + m01 * tx.m12 + m02;
+ double n10 = m10 * tx.m00 + m11 * tx.m10;
+ double n11 = m10 * tx.m01 + m11 * tx.m11;
+ double n12 = m10 * tx.m02 + m11 * tx.m12 + m12;
+ m00 = n00;
+ m01 = n01;
+ m02 = n02;
+ m10 = n10;
+ m11 = n11;
+ m12 = n12;
+ updateType();
+ }
+
+ /**
+ * Set this transform to the result of performing tx followed by the
+ * original version of this. This is less common than normal concatenation,
+ * but can still be used to chain transformations from one space to another.
+ * In matrix form:
+ * <pre>
+ * [ this ] = [ tx ] x [ this ]
+ * </pre>
+ *
+ * @param tx the transform to concatenate
+ * @throws NullPointerException if tx is null
+ * @see #concatenate(AffineTransform)
+ */
+ public void preConcatenate(AffineTransform tx)
+ {
+ double n00 = tx.m00 * m00 + tx.m01 * m10;
+ double n01 = tx.m00 * m01 + tx.m01 * m11;
+ double n02 = tx.m00 * m02 + tx.m01 * m12 + tx.m02;
+ double n10 = tx.m10 * m00 + tx.m11 * m10;
+ double n11 = tx.m10 * m01 + tx.m11 * m11;
+ double n12 = tx.m10 * m02 + tx.m11 * m12 + tx.m12;
+ m00 = n00;
+ m01 = n01;
+ m02 = n02;
+ m10 = n10;
+ m11 = n11;
+ m12 = n12;
+ updateType();
+ }
+
+ /**
+ * Returns a transform, which if concatenated to this one, will result in
+ * the identity transform. This is useful for undoing transformations, but
+ * is only possible if the original transform has an inverse (ie. does not
+ * map multiple points to the same line or point). A transform exists only
+ * if getDeterminant() has a non-zero value.
+ *
+ * The inverse is calculated as:
+ *
+ * <pre>
+ *
+ * Let A be the matrix for which we want to find the inverse:
+ *
+ * A = [ m00 m01 m02 ]
+ * [ m10 m11 m12 ]
+ * [ 0 0 1 ]
+ *
+ *
+ * 1
+ * inverse (A) = --- x adjoint(A)
+ * det
+ *
+ *
+ *
+ * = 1 [ m11 -m01 m01*m12-m02*m11 ]
+ * --- x [ -m10 m00 -m00*m12+m10*m02 ]
+ * det [ 0 0 m00*m11-m10*m01 ]
+ *
+ *
+ *
+ * = [ m11/det -m01/det m01*m12-m02*m11/det ]
+ * [ -m10/det m00/det -m00*m12+m10*m02/det ]
+ * [ 0 0 1 ]
+ *
+ *
+ * </pre>
+ *
+ *
+ *
+ * @return a new inverse transform
+ * @throws NoninvertibleTransformException if inversion is not possible
+ * @see #getDeterminant()
+ */
+ public AffineTransform createInverse()
+ throws NoninvertibleTransformException
+ {
+ double det = getDeterminant();
+ if (det == 0)
+ throw new NoninvertibleTransformException("can't invert transform");
+
+ double im00 = m11 / det;
+ double im10 = -m10 / det;
+ double im01 = -m01 / det;
+ double im11 = m00 / det;
+ double im02 = (m01 * m12 - m02 * m11) / det;
+ double im12 = (-m00 * m12 + m10 * m02) / det;
+
+ return new AffineTransform (im00, im10, im01, im11, im02, im12);
+ }
+
+ /**
+ * Perform this transformation on the given source point, and store the
+ * result in the destination (creating it if necessary). It is safe for
+ * src and dst to be the same.
+ *
+ * @param src the source point
+ * @param dst the destination, or null
+ * @return the transformation of src, in dst if it was non-null
+ * @throws NullPointerException if src is null
+ */
+ public Point2D transform(Point2D src, Point2D dst)
+ {
+ if (dst == null)
+ dst = new Point2D.Double();
+ double x = src.getX();
+ double y = src.getY();
+ double nx = m00 * x + m01 * y + m02;
+ double ny = m10 * x + m11 * y + m12;
+ dst.setLocation(nx, ny);
+ return dst;
+ }
+
+ /**
+ * Perform this transformation on an array of points, storing the results
+ * in another (possibly same) array. This will not create a destination
+ * array, but will create points for the null entries of the destination.
+ * The transformation is done sequentially. While having a single source
+ * and destination point be the same is safe, you should be aware that
+ * duplicate references to the same point in the source, and having the
+ * source overlap the destination, may result in your source points changing
+ * from a previous transform before it is their turn to be evaluated.
+ *
+ * @param src the array of source points
+ * @param srcOff the starting offset into src
+ * @param dst the array of destination points (may have null entries)
+ * @param dstOff the starting offset into dst
+ * @param num the number of points to transform
+ * @throws NullPointerException if src or dst is null, or src has null
+ * entries
+ * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
+ * @throws ArrayStoreException if new points are incompatible with dst
+ */
+ public void transform(Point2D[] src, int srcOff,
+ Point2D[] dst, int dstOff, int num)
+ {
+ while (--num >= 0)
+ dst[dstOff] = transform(src[srcOff++], dst[dstOff++]);
+ }
+
+ /**
+ * Perform this transformation on an array of points, in (x,y) pairs,
+ * storing the results in another (possibly same) array. This will not
+ * create a destination array. All sources are copied before the
+ * transformation, so that no result will overwrite a point that has not yet
+ * been evaluated.
+ *
+ * @param srcPts the array of source points
+ * @param srcOff the starting offset into src
+ * @param dstPts the array of destination points
+ * @param dstOff the starting offset into dst
+ * @param num the number of points to transform
+ * @throws NullPointerException if src or dst is null
+ * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
+ */
+ public void transform(float[] srcPts, int srcOff,
+ float[] dstPts, int dstOff, int num)
+ {
+ if (srcPts == dstPts && dstOff > srcOff
+ && num > 1 && srcOff + 2 * num > dstOff)
+ {
+ float[] f = new float[2 * num];
+ System.arraycopy(srcPts, srcOff, f, 0, 2 * num);
+ srcPts = f;
+ }
+ while (--num >= 0)
+ {
+ float x = srcPts[srcOff++];
+ float y = srcPts[srcOff++];
+ dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02);
+ dstPts[dstOff++] = (float) (m10 * x + m11 * y + m12);
+ }
+ }
+
+ /**
+ * Perform this transformation on an array of points, in (x,y) pairs,
+ * storing the results in another (possibly same) array. This will not
+ * create a destination array. All sources are copied before the
+ * transformation, so that no result will overwrite a point that has not yet
+ * been evaluated.
+ *
+ * @param srcPts the array of source points
+ * @param srcOff the starting offset into src
+ * @param dstPts the array of destination points
+ * @param dstOff the starting offset into dst
+ * @param num the number of points to transform
+ * @throws NullPointerException if src or dst is null
+ * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
+ */
+ public void transform(double[] srcPts, int srcOff,
+ double[] dstPts, int dstOff, int num)
+ {
+ if (srcPts == dstPts && dstOff > srcOff
+ && num > 1 && srcOff + 2 * num > dstOff)
+ {
+ double[] d = new double[2 * num];
+ System.arraycopy(srcPts, srcOff, d, 0, 2 * num);
+ srcPts = d;
+ }
+ while (--num >= 0)
+ {
+ double x = srcPts[srcOff++];
+ double y = srcPts[srcOff++];
+ dstPts[dstOff++] = m00 * x + m01 * y + m02;
+ dstPts[dstOff++] = m10 * x + m11 * y + m12;
+ }
+ }
+
+ /**
+ * Perform this transformation on an array of points, in (x,y) pairs,
+ * storing the results in another array. This will not create a destination
+ * array.
+ *
+ * @param srcPts the array of source points
+ * @param srcOff the starting offset into src
+ * @param dstPts the array of destination points
+ * @param dstOff the starting offset into dst
+ * @param num the number of points to transform
+ * @throws NullPointerException if src or dst is null
+ * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
+ */
+ public void transform(float[] srcPts, int srcOff,
+ double[] dstPts, int dstOff, int num)
+ {
+ while (--num >= 0)
+ {
+ float x = srcPts[srcOff++];
+ float y = srcPts[srcOff++];
+ dstPts[dstOff++] = m00 * x + m01 * y + m02;
+ dstPts[dstOff++] = m10 * x + m11 * y + m12;
+ }
+ }
+
+ /**
+ * Perform this transformation on an array of points, in (x,y) pairs,
+ * storing the results in another array. This will not create a destination
+ * array.
+ *
+ * @param srcPts the array of source points
+ * @param srcOff the starting offset into src
+ * @param dstPts the array of destination points
+ * @param dstOff the starting offset into dst
+ * @param num the number of points to transform
+ * @throws NullPointerException if src or dst is null
+ * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
+ */
+ public void transform(double[] srcPts, int srcOff,
+ float[] dstPts, int dstOff, int num)
+ {
+ while (--num >= 0)
+ {
+ double x = srcPts[srcOff++];
+ double y = srcPts[srcOff++];
+ dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02);
+ dstPts[dstOff++] = (float) (m10 * x + m11 * y + m12);
+ }
+ }
+
+ /**
+ * Perform the inverse of this transformation on the given source point,
+ * and store the result in the destination (creating it if necessary). It
+ * is safe for src and dst to be the same.
+ *
+ * @param src the source point
+ * @param dst the destination, or null
+ * @return the inverse transformation of src, in dst if it was non-null
+ * @throws NullPointerException if src is null
+ * @throws NoninvertibleTransformException if the inverse does not exist
+ * @see #getDeterminant()
+ */
+ public Point2D inverseTransform(Point2D src, Point2D dst)
+ throws NoninvertibleTransformException
+ {
+ return createInverse().transform(src, dst);
+ }
+
+ /**
+ * Perform the inverse of this transformation on an array of points, in
+ * (x,y) pairs, storing the results in another (possibly same) array. This
+ * will not create a destination array. All sources are copied before the
+ * transformation, so that no result will overwrite a point that has not yet
+ * been evaluated.
+ *
+ * @param srcPts the array of source points
+ * @param srcOff the starting offset into src
+ * @param dstPts the array of destination points
+ * @param dstOff the starting offset into dst
+ * @param num the number of points to transform
+ * @throws NullPointerException if src or dst is null
+ * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
+ * @throws NoninvertibleTransformException if the inverse does not exist
+ * @see #getDeterminant()
+ */
+ public void inverseTransform(double[] srcPts, int srcOff,
+ double[] dstPts, int dstOff, int num)
+ throws NoninvertibleTransformException
+ {
+ createInverse().transform(srcPts, srcOff, dstPts, dstOff, num);
+ }
+
+ /**
+ * Perform this transformation, less any translation, on the given source
+ * point, and store the result in the destination (creating it if
+ * necessary). It is safe for src and dst to be the same. The reduced
+ * transform is equivalent to:
+ * <pre>
+ * [ x' ] = [ m00 m01 ] [ x ] = [ m00 * x + m01 * y ]
+ * [ y' ] [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ]
+ * </pre>
+ *
+ * @param src the source point
+ * @param dst the destination, or null
+ * @return the delta transformation of src, in dst if it was non-null
+ * @throws NullPointerException if src is null
+ */
+ public Point2D deltaTransform(Point2D src, Point2D dst)
+ {
+ if (dst == null)
+ dst = new Point2D.Double();
+ double x = src.getX();
+ double y = src.getY();
+ double nx = m00 * x + m01 * y;
+ double ny = m10 * x + m11 * y;
+ dst.setLocation(nx, ny);
+ return dst;
+ }
+
+ /**
+ * Perform this transformation, less any translation, on an array of points,
+ * in (x,y) pairs, storing the results in another (possibly same) array.
+ * This will not create a destination array. All sources are copied before
+ * the transformation, so that no result will overwrite a point that has
+ * not yet been evaluated. The reduced transform is equivalent to:
+ * <pre>
+ * [ x' ] = [ m00 m01 ] [ x ] = [ m00 * x + m01 * y ]
+ * [ y' ] [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ]
+ * </pre>
+ *
+ * @param srcPts the array of source points
+ * @param srcOff the starting offset into src
+ * @param dstPts the array of destination points
+ * @param dstOff the starting offset into dst
+ * @param num the number of points to transform
+ * @throws NullPointerException if src or dst is null
+ * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
+ */
+ public void deltaTransform(double[] srcPts, int srcOff,
+ double[] dstPts, int dstOff,
+ int num)
+ {
+ if (srcPts == dstPts && dstOff > srcOff
+ && num > 1 && srcOff + 2 * num > dstOff)
+ {
+ double[] d = new double[2 * num];
+ System.arraycopy(srcPts, srcOff, d, 0, 2 * num);
+ srcPts = d;
+ }
+ while (--num >= 0)
+ {
+ double x = srcPts[srcOff++];
+ double y = srcPts[srcOff++];
+ dstPts[dstOff++] = m00 * x + m01 * y;
+ dstPts[dstOff++] = m10 * x + m11 * y;
+ }
+ }
+
+ /**
+ * Return a new Shape, based on the given one, where the path of the shape
+ * has been transformed by this transform. Notice that this uses GeneralPath,
+ * which only stores points in float precision.
+ *
+ * @param src the shape source to transform
+ * @return the shape, transformed by this, <code>null</code> if src is
+ * <code>null</code>.
+ * @see GeneralPath#transform(AffineTransform)
+ */
+ public Shape createTransformedShape(Shape src)
+ {
+ if(src == null)
+ return null;
+ GeneralPath p = new GeneralPath(src);
+ p.transform(this);
+ return p;
+ }
+
+ /**
+ * Returns a string representation of the transform, in the format:
+ * <code>"AffineTransform[[" + m00 + ", " + m01 + ", " + m02 + "], ["
+ * + m10 + ", " + m11 + ", " + m12 + "]]"</code>.
+ *
+ * @return the string representation
+ */
+ public String toString()
+ {
+ return "AffineTransform[[" + m00 + ", " + m01 + ", " + m02 + "], ["
+ + m10 + ", " + m11 + ", " + m12 + "]]";
+ }
+
+ /**
+ * Tests if this transformation is the identity:
+ * <pre>
+ * [ 1 0 0 ]
+ * [ 0 1 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ *
+ * @return true if this is the identity transform
+ */
+ public boolean isIdentity()
+ {
+ // Rather than rely on type, check explicitly.
+ return (m00 == 1 && m01 == 0 && m02 == 0
+ && m10 == 0 && m11 == 1 && m12 == 0);
+ }
+
+ /**
+ * Create a new transform of the same run-time type, with the same
+ * transforming properties as this one.
+ *
+ * @return the clone
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+
+ /**
+ * Return the hashcode for this transformation. The formula is not
+ * documented, but appears to be the same as:
+ * <pre>
+ * long l = Double.doubleToLongBits(getScaleX());
+ * l = l * 31 + Double.doubleToLongBits(getShearY());
+ * l = l * 31 + Double.doubleToLongBits(getShearX());
+ * l = l * 31 + Double.doubleToLongBits(getScaleY());
+ * l = l * 31 + Double.doubleToLongBits(getTranslateX());
+ * l = l * 31 + Double.doubleToLongBits(getTranslateY());
+ * return (int) ((l >> 32) ^ l);
+ * </pre>
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ long l = Double.doubleToLongBits(m00);
+ l = l * 31 + Double.doubleToLongBits(m10);
+ l = l * 31 + Double.doubleToLongBits(m01);
+ l = l * 31 + Double.doubleToLongBits(m11);
+ l = l * 31 + Double.doubleToLongBits(m02);
+ l = l * 31 + Double.doubleToLongBits(m12);
+ return (int) ((l >> 32) ^ l);
+ }
+
+ /**
+ * Compares two transforms for equality. This returns true if they have the
+ * same matrix values.
+ *
+ * @param obj the transform to compare
+ * @return true if it is equal
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof AffineTransform))
+ return false;
+ AffineTransform t = (AffineTransform) obj;
+ return (m00 == t.m00 && m01 == t.m01 && m02 == t.m02
+ && m10 == t.m10 && m11 == t.m11 && m12 == t.m12);
+ }
+
+ /**
+ * Helper to decode the type from the matrix. This is not guaranteed
+ * to find the optimal type, but at least it will be valid.
+ */
+ private void updateType()
+ {
+ double det = getDeterminant();
+ if (det == 0)
+ {
+ type = TYPE_GENERAL_TRANSFORM;
+ return;
+ }
+ // Scale (includes rotation by PI) or translation.
+ if (m01 == 0 && m10 == 0)
+ {
+ if (m00 == m11)
+ type = m00 == 1 ? TYPE_IDENTITY : TYPE_UNIFORM_SCALE;
+ else
+ type = TYPE_GENERAL_SCALE;
+ if (m02 != 0 || m12 != 0)
+ type |= TYPE_TRANSLATION;
+ }
+ // Rotation.
+ else if (m00 == m11 && m01 == -m10)
+ {
+ type = m00 == 0 ? TYPE_QUADRANT_ROTATION : TYPE_GENERAL_ROTATION;
+ if (det != 1)
+ type |= TYPE_UNIFORM_SCALE;
+ if (m02 != 0 || m12 != 0)
+ type |= TYPE_TRANSLATION;
+ }
+ else
+ type = TYPE_GENERAL_TRANSFORM;
+ }
+
+ /**
+ * Reads a transform from an object stream.
+ *
+ * @param s the stream to read from
+ * @throws ClassNotFoundException if there is a problem deserializing
+ * @throws IOException if there is a problem deserializing
+ */
+ private void readObject(ObjectInputStream s)
+ throws ClassNotFoundException, IOException
+ {
+ s.defaultReadObject();
+ updateType();
+ }
+} // class AffineTransform
diff --git a/libjava/classpath/java/awt/geom/Arc2D.java b/libjava/classpath/java/awt/geom/Arc2D.java
new file mode 100644
index 0000000..eff34a0
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/Arc2D.java
@@ -0,0 +1,1399 @@
+/* Arc2D.java -- represents an arc in 2-D space
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+
+/**
+ * This class represents all arcs (segments of an ellipse in 2-D space). The
+ * arcs are defined by starting angle and extent (arc length) in degrees, as
+ * opposed to radians (like the rest of Java), and can be open, chorded, or
+ * wedge shaped. The angles are skewed according to the ellipse, so that 45
+ * degrees always points to the upper right corner (positive x, negative y)
+ * of the bounding rectangle. A positive extent draws a counterclockwise arc,
+ * and while the angle can be any value, the path iterator only traverses the
+ * first 360 degrees. Storage is up to the subclasses.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Sven de Marothy (sven@physto.se)
+ * @since 1.2
+ */
+public abstract class Arc2D extends RectangularShape
+{
+ /**
+ * An open arc, with no segment connecting the endpoints. This type of
+ * arc still contains the same points as a chorded version.
+ */
+ public static final int OPEN = 0;
+
+ /**
+ * A closed arc with a single segment connecting the endpoints (a chord).
+ */
+ public static final int CHORD = 1;
+
+ /**
+ * A closed arc with two segments, one from each endpoint, meeting at the
+ * center of the ellipse.
+ */
+ public static final int PIE = 2;
+
+ /** The closure type of this arc. This is package-private to avoid an
+ * accessor method. */
+ int type;
+
+ /**
+ * Create a new arc, with the specified closure type.
+ *
+ * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
+ * @throws IllegalArgumentException if type is invalid
+ */
+ protected Arc2D(int type)
+ {
+ if (type < OPEN || type > PIE)
+ throw new IllegalArgumentException();
+ this.type = type;
+ }
+
+ /**
+ * Get the starting angle of the arc in degrees.
+ *
+ * @return the starting angle
+ * @see #setAngleStart(double)
+ */
+ public abstract double getAngleStart();
+
+ /**
+ * Get the extent angle of the arc in degrees.
+ *
+ * @return the extent angle
+ * @see #setAngleExtent(double)
+ */
+ public abstract double getAngleExtent();
+
+ /**
+ * Return the closure type of the arc.
+ *
+ * @return the closure type
+ * @see #OPEN
+ * @see #CHORD
+ * @see #PIE
+ * @see #setArcType(int)
+ */
+ public int getArcType()
+ {
+ return type;
+ }
+
+ /**
+ * Returns the starting point of the arc.
+ *
+ * @return the start point
+ */
+ public Point2D getStartPoint()
+ {
+ double angle = Math.toRadians(getAngleStart());
+ double rx = getWidth() / 2;
+ double ry = getHeight() / 2;
+ double x = getX() + rx + rx * Math.cos(angle);
+ double y = getY() + ry - ry * Math.sin(angle);
+ return new Point2D.Double(x, y);
+ }
+
+ /**
+ * Returns the ending point of the arc.
+ *
+ * @return the end point
+ */
+ public Point2D getEndPoint()
+ {
+ double angle = Math.toRadians(getAngleStart() + getAngleExtent());
+ double rx = getWidth() / 2;
+ double ry = getHeight() / 2;
+ double x = getX() + rx + rx * Math.cos(angle);
+ double y = getY() + ry - ry * Math.sin(angle);
+ return new Point2D.Double(x, y);
+ }
+
+ /**
+ * Set the parameters of the arc. The angles are in degrees, and a positive
+ * extent sweeps counterclockwise (from the positive x-axis to the negative
+ * y-axis).
+ *
+ * @param x the new x coordinate of the upper left of the bounding box
+ * @param y the new y coordinate of the upper left of the bounding box
+ * @param w the new width of the bounding box
+ * @param h the new height of the bounding box
+ * @param start the start angle, in degrees
+ * @param extent the arc extent, in degrees
+ * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ */
+ public abstract void setArc(double x, double y, double w, double h,
+ double start, double extent, int type);
+
+ /**
+ * Set the parameters of the arc. The angles are in degrees, and a positive
+ * extent sweeps counterclockwise (from the positive x-axis to the negative
+ * y-axis).
+ *
+ * @param p the upper left point of the bounding box
+ * @param d the dimensions of the bounding box
+ * @param start the start angle, in degrees
+ * @param extent the arc extent, in degrees
+ * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ * @throws NullPointerException if p or d is null
+ */
+ public void setArc(Point2D p, Dimension2D d, double start, double extent,
+ int type)
+ {
+ setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(), start, extent, type);
+ }
+
+ /**
+ * Set the parameters of the arc. The angles are in degrees, and a positive
+ * extent sweeps counterclockwise (from the positive x-axis to the negative
+ * y-axis).
+ *
+ * @param r the new bounding box
+ * @param start the start angle, in degrees
+ * @param extent the arc extent, in degrees
+ * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ * @throws NullPointerException if r is null
+ */
+ public void setArc(Rectangle2D r, double start, double extent, int type)
+ {
+ setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(), start, extent, type);
+ }
+
+ /**
+ * Set the parameters of the arc from the given one.
+ *
+ * @param a the arc to copy
+ * @throws NullPointerException if a is null
+ */
+ public void setArc(Arc2D a)
+ {
+ setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(), a.getAngleStart(),
+ a.getAngleExtent(), a.getArcType());
+ }
+
+ /**
+ * Set the parameters of the arc. The angles are in degrees, and a positive
+ * extent sweeps counterclockwise (from the positive x-axis to the negative
+ * y-axis). This controls the center point and radius, so the arc will be
+ * circular.
+ *
+ * @param x the x coordinate of the center of the circle
+ * @param y the y coordinate of the center of the circle
+ * @param r the radius of the circle
+ * @param start the start angle, in degrees
+ * @param extent the arc extent, in degrees
+ * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ */
+ public void setArcByCenter(double x, double y, double r, double start,
+ double extent, int type)
+ {
+ setArc(x - r, y - r, r + r, r + r, start, extent, type);
+ }
+
+ /**
+ * Sets the parameters of the arc by finding the tangents of two lines, and
+ * using the specified radius. The arc will be circular, will begin on the
+ * tangent point of the line extending from p1 to p2, and will end on the
+ * tangent point of the line extending from p2 to p3.
+ *
+ * XXX What happens if the points are colinear, or the radius negative?
+ *
+ * @param p1 the first point
+ * @param p2 the tangent line intersection point
+ * @param p3 the third point
+ * @param r the radius of the arc
+ * @throws NullPointerException if any point is null
+ */
+ public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double r)
+ {
+ if ((p2.getX() - p1.getX()) * (p3.getY() - p1.getY())
+ - (p3.getX() - p1.getX()) * (p2.getY() - p1.getY()) > 0)
+ {
+ Point2D p = p3;
+ p3 = p1;
+ p1 = p;
+ }
+
+ // normalized tangent vectors
+ double dx1 = (p1.getX() - p2.getX()) / p1.distance(p2);
+ double dy1 = (p1.getY() - p2.getY()) / p1.distance(p2);
+ double dx2 = (p2.getX() - p3.getX()) / p3.distance(p2);
+ double dy2 = (p2.getY() - p3.getY()) / p3.distance(p2);
+ double theta1 = Math.atan2(dx1, dy1);
+ double theta2 = Math.atan2(dx2, dy2);
+
+ double dx = r * Math.cos(theta2) - r * Math.cos(theta1);
+ double dy = -r * Math.sin(theta2) + r * Math.sin(theta1);
+
+ if (theta1 < 0)
+ theta1 += 2 * Math.PI;
+ if (theta2 < 0)
+ theta2 += 2 * Math.PI;
+ if (theta2 < theta1)
+ theta2 += 2 * Math.PI;
+
+ // Vectors of the lines, not normalized, note we change
+ // the direction of line 2.
+ dx1 = p1.getX() - p2.getX();
+ dy1 = p1.getY() - p2.getY();
+ dx2 = p3.getX() - p2.getX();
+ dy2 = p3.getY() - p2.getY();
+
+ // Calculate the tangent point to the second line
+ double t2 = -(dx1 * dy - dy1 * dx) / (dx2 * dy1 - dx1 * dy2);
+ double x2 = t2 * (p3.getX() - p2.getX()) + p2.getX();
+ double y2 = t2 * (p3.getY() - p2.getY()) + p2.getY();
+
+ // calculate the center point
+ double x = x2 - r * Math.cos(theta2);
+ double y = y2 + r * Math.sin(theta2);
+
+ setArc(x - r, y - r, 2 * r, 2 * r, Math.toDegrees(theta1),
+ Math.toDegrees(theta2 - theta1), getArcType());
+ }
+
+ /**
+ * Set the start, in degrees.
+ *
+ * @param start the new start angle
+ * @see #getAngleStart()
+ */
+ public abstract void setAngleStart(double start);
+
+ /**
+ * Set the extent, in degrees.
+ *
+ * @param extent the new extent angle
+ * @see #getAngleExtent()
+ */
+ public abstract void setAngleExtent(double extent);
+
+ /**
+ * Sets the starting angle to the angle of the given point relative to
+ * the center of the arc. The extent remains constant; in other words,
+ * this rotates the arc.
+ *
+ * @param p the new start point
+ * @throws NullPointerException if p is null
+ * @see #getStartPoint()
+ * @see #getAngleStart()
+ */
+ public void setAngleStart(Point2D p)
+ {
+ // Normalize.
+ double x = p.getX() - (getX() + getWidth() / 2);
+ double y = p.getY() - (getY() + getHeight() / 2);
+ setAngleStart(Math.toDegrees(Math.atan2(-y, x)));
+ }
+
+ /**
+ * Sets the starting and extent angles to those of the given points
+ * relative to the center of the arc. The arc will be non-empty, and will
+ * extend counterclockwise.
+ *
+ * @param x1 the first x coordinate
+ * @param y1 the first y coordinate
+ * @param x2 the second x coordinate
+ * @param y2 the second y coordinate
+ * @see #setAngleStart(Point2D)
+ */
+ public void setAngles(double x1, double y1, double x2, double y2)
+ {
+ // Normalize the points.
+ double mx = getX();
+ double my = getY();
+ double mw = getWidth();
+ double mh = getHeight();
+ x1 = x1 - (mx + mw / 2);
+ y1 = y1 - (my + mh / 2);
+ x2 = x2 - (mx + mw / 2);
+ y2 = y2 - (my + mh / 2);
+ double start = Math.toDegrees(Math.atan2(-y1, x1));
+ double extent = Math.toDegrees(Math.atan2(-y2, x2)) - start;
+ if (extent < 0)
+ extent += 360;
+ setAngleStart(start);
+ setAngleExtent(extent);
+ }
+
+ /**
+ * Sets the starting and extent angles to those of the given points
+ * relative to the center of the arc. The arc will be non-empty, and will
+ * extend counterclockwise.
+ *
+ * @param p1 the first point
+ * @param p2 the second point
+ * @throws NullPointerException if either point is null
+ * @see #setAngleStart(Point2D)
+ */
+ public void setAngles(Point2D p1, Point2D p2)
+ {
+ setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+ }
+
+ /**
+ * Set the closure type of this arc.
+ *
+ * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ * @see #getArcType()
+ */
+ public void setArcType(int type)
+ {
+ if (type < OPEN || type > PIE)
+ throw new IllegalArgumentException();
+ this.type = type;
+ }
+
+ /**
+ * Sets the location and bounds of the ellipse of which this arc is a part.
+ *
+ * @param x the new x coordinate
+ * @param y the new y coordinate
+ * @param w the new width
+ * @param h the new height
+ * @see #getFrame()
+ */
+ public void setFrame(double x, double y, double w, double h)
+ {
+ setArc(x, y, w, h, getAngleStart(), getAngleExtent(), type);
+ }
+
+ /**
+ * Gets the bounds of the arc. This is much tighter than
+ * <code>getBounds</code>, as it takes into consideration the start and
+ * end angles, and the center point of a pie wedge, rather than just the
+ * overall ellipse.
+ *
+ * @return the bounds of the arc
+ * @see #getBounds()
+ */
+ public Rectangle2D getBounds2D()
+ {
+ double extent = getAngleExtent();
+ if (Math.abs(extent) >= 360)
+ return makeBounds(getX(), getY(), getWidth(), getHeight());
+
+ // Find the minimal bounding box. This determined by its extrema,
+ // which are the center, the endpoints of the arc, and any local
+ // maximum contained by the arc.
+ double rX = getWidth() / 2;
+ double rY = getHeight() / 2;
+ double centerX = getX() + rX;
+ double centerY = getY() + rY;
+
+ Point2D p1 = getStartPoint();
+ Rectangle2D result = makeBounds(p1.getX(), p1.getY(), 0, 0);
+ result.add(getEndPoint());
+
+ if (type == PIE)
+ result.add(centerX, centerY);
+ if (containsAngle(0))
+ result.add(centerX + rX, centerY);
+ if (containsAngle(90))
+ result.add(centerX, centerY - rY);
+ if (containsAngle(180))
+ result.add(centerX - rX, centerY);
+ if (containsAngle(270))
+ result.add(centerX, centerY + rY);
+
+ return result;
+ }
+
+ /**
+ * Construct a bounding box in a precision appropriate for the subclass.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ * @return the rectangle for use in getBounds2D
+ */
+ protected abstract Rectangle2D makeBounds(double x, double y, double w,
+ double h);
+
+ /**
+ * Tests if the given angle, in degrees, is included in the arc.
+ * All angles are normalized to be between 0 and 360 degrees.
+ *
+ * @param a the angle to test
+ * @return true if it is contained
+ */
+ public boolean containsAngle(double a)
+ {
+ double start = getAngleStart();
+ double extent = getAngleExtent();
+ double end = start + extent;
+
+ if (extent == 0)
+ return false;
+
+ if (extent >= 360 || extent <= -360)
+ return true;
+
+ if (extent < 0)
+ {
+ end = start;
+ start += extent;
+ }
+
+ start %= 360;
+ while (start < 0)
+ start += 360;
+
+ end %= 360;
+ while (end < start)
+ end += 360;
+
+ a %= 360;
+ while (a < start)
+ a += 360;
+
+ return a >= start && a < end; // starting angle included, ending angle not
+ }
+
+ /**
+ * Determines if the arc contains the given point. If the bounding box
+ * is empty, then this will return false.
+ *
+ * The area considered 'inside' an arc of type OPEN is the same as the
+ * area inside an equivalent filled CHORD-type arc. The area considered
+ * 'inside' a CHORD-type arc is the same as the filled area.
+ *
+ * @param x the x coordinate to test
+ * @param y the y coordinate to test
+ * @return true if the point is inside the arc
+ */
+ public boolean contains(double x, double y)
+ {
+ double w = getWidth();
+ double h = getHeight();
+ double extent = getAngleExtent();
+ if (w <= 0 || h <= 0 || extent == 0)
+ return false;
+
+ double mx = getX() + w / 2;
+ double my = getY() + h / 2;
+ double dx = (x - mx) * 2 / w;
+ double dy = (y - my) * 2 / h;
+ if ((dx * dx + dy * dy) >= 1.0)
+ return false;
+
+ double angle = Math.toDegrees(Math.atan2(-dy, dx));
+ if (getArcType() == PIE)
+ return containsAngle(angle);
+
+ double a1 = Math.toRadians(getAngleStart());
+ double a2 = Math.toRadians(getAngleStart() + extent);
+ double x1 = mx + getWidth() * Math.cos(a1) / 2;
+ double y1 = my - getHeight() * Math.sin(a1) / 2;
+ double x2 = mx + getWidth() * Math.cos(a2) / 2;
+ double y2 = my - getHeight() * Math.sin(a2) / 2;
+ double sgn = ((x2 - x1) * (my - y1) - (mx - x1) * (y2 - y1)) * ((x2 - x1) * (y
+ - y1) - (x - x1) * (y2 - y1));
+
+ if (Math.abs(extent) > 180)
+ {
+ if (containsAngle(angle))
+ return true;
+ return sgn > 0;
+ }
+ else
+ {
+ if (! containsAngle(angle))
+ return false;
+ return sgn < 0;
+ }
+ }
+
+ /**
+ * Tests if a given rectangle intersects the area of the arc.
+ *
+ * For a definition of the 'inside' area, see the contains() method.
+ * @see #contains(double, double)
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @return true if the two shapes share common points
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ double extent = getAngleExtent();
+ if (extent == 0)
+ return false;
+
+ if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
+ || contains(x + w, y + h))
+ return true;
+
+ Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
+
+ double a = getWidth() / 2.0;
+ double b = getHeight() / 2.0;
+
+ double mx = getX() + a;
+ double my = getY() + b;
+ double x1 = mx + a * Math.cos(Math.toRadians(getAngleStart()));
+ double y1 = my - b * Math.sin(Math.toRadians(getAngleStart()));
+ double x2 = mx + a * Math.cos(Math.toRadians(getAngleStart() + extent));
+ double y2 = my - b * Math.sin(Math.toRadians(getAngleStart() + extent));
+
+ if (getArcType() != CHORD)
+ {
+ // check intersections against the pie radii
+ if (rect.intersectsLine(mx, my, x1, y1))
+ return true;
+ if (rect.intersectsLine(mx, my, x2, y2))
+ return true;
+ }
+ else// check the chord
+ if (rect.intersectsLine(x1, y1, x2, y2))
+ return true;
+
+ // Check the Arc segment against the four edges
+ double dx;
+
+ // Check the Arc segment against the four edges
+ double dy;
+ dy = y - my;
+ dx = a * Math.sqrt(1 - ((dy * dy) / (b * b)));
+ if (! java.lang.Double.isNaN(dx))
+ {
+ if (mx + dx >= x && mx + dx <= x + w
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
+ return true;
+ if (mx - dx >= x && mx - dx <= x + w
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, -dx))))
+ return true;
+ }
+ dy = (y + h) - my;
+ dx = a * Math.sqrt(1 - ((dy * dy) / (b * b)));
+ if (! java.lang.Double.isNaN(dx))
+ {
+ if (mx + dx >= x && mx + dx <= x + w
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
+ return true;
+ if (mx - dx >= x && mx - dx <= x + w
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, -dx))))
+ return true;
+ }
+ dx = x - mx;
+ dy = b * Math.sqrt(1 - ((dx * dx) / (a * a)));
+ if (! java.lang.Double.isNaN(dy))
+ {
+ if (my + dy >= y && my + dy <= y + h
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
+ return true;
+ if (my - dy >= y && my - dy <= y + h
+ && containsAngle(Math.toDegrees(Math.atan2(dy, dx))))
+ return true;
+ }
+
+ dx = (x + w) - mx;
+ dy = b * Math.sqrt(1 - ((dx * dx) / (a * a)));
+ if (! java.lang.Double.isNaN(dy))
+ {
+ if (my + dy >= y && my + dy <= y + h
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
+ return true;
+ if (my - dy >= y && my - dy <= y + h
+ && containsAngle(Math.toDegrees(Math.atan2(dy, dx))))
+ return true;
+ }
+
+ // Check whether the arc is contained within the box
+ if (rect.contains(mx, my))
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Tests if a given rectangle is contained in the area of the arc.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @return true if the arc contains the rectangle
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ double extent = getAngleExtent();
+ if (extent == 0)
+ return false;
+
+ if (! (contains(x, y) && contains(x, y + h) && contains(x + w, y)
+ && contains(x + w, y + h)))
+ return false;
+
+ Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
+
+ double a = getWidth() / 2.0;
+ double b = getHeight() / 2.0;
+
+ double mx = getX() + a;
+ double my = getY() + b;
+ double x1 = mx + a * Math.cos(Math.toRadians(getAngleStart()));
+ double y1 = my - b * Math.sin(Math.toRadians(getAngleStart()));
+ double x2 = mx + a * Math.cos(Math.toRadians(getAngleStart() + extent));
+ double y2 = my - b * Math.sin(Math.toRadians(getAngleStart() + extent));
+ if (getArcType() != CHORD)
+ {
+ // check intersections against the pie radii
+ if (rect.intersectsLine(mx, my, x1, y1))
+ return false;
+
+ if (rect.intersectsLine(mx, my, x2, y2))
+ return false;
+ }
+ else if (rect.intersectsLine(x1, y1, x2, y2))
+ return false;
+ return true;
+ }
+
+ /**
+ * Tests if a given rectangle is contained in the area of the arc.
+ *
+ * @param r the rectangle
+ * @return true if the arc contains the rectangle
+ */
+ public boolean contains(Rectangle2D r)
+ {
+ return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Returns an iterator over this arc, with an optional transformation.
+ * This iterator is threadsafe, so future modifications to the arc do not
+ * affect the iteration.
+ *
+ * @param at the transformation, or null
+ * @return a path iterator
+ */
+ public PathIterator getPathIterator(AffineTransform at)
+ {
+ return new ArcIterator(this, at);
+ }
+
+ /**
+ * This class is used to iterate over an arc. Since ellipses are a subclass
+ * of arcs, this is used by Ellipse2D as well.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+ static final class ArcIterator implements PathIterator
+ {
+ /** The current iteration. */
+ private int current;
+
+ /** The last iteration. */
+ private final int limit;
+
+ /** The optional transformation. */
+ private final AffineTransform xform;
+
+ /** The x coordinate of the bounding box. */
+ private final double x;
+
+ /** The y coordinate of the bounding box. */
+ private final double y;
+
+ /** The width of the bounding box. */
+ private final double w;
+
+ /** The height of the bounding box. */
+ private final double h;
+
+ /** The start angle, in radians (not degrees). */
+ private final double start;
+
+ /** The extent angle, in radians (not degrees). */
+ private final double extent;
+
+ /** The arc closure type. */
+ private final int type;
+
+ /**
+ * Construct a new iterator over an arc.
+ *
+ * @param a the arc
+ * @param xform the transform
+ */
+ public ArcIterator(Arc2D a, AffineTransform xform)
+ {
+ this.xform = xform;
+ x = a.getX();
+ y = a.getY();
+ w = a.getWidth();
+ h = a.getHeight();
+ double start = a.getAngleStart() * (Math.PI / 180);
+ double extent = a.getAngleExtent() * (Math.PI / 180);
+
+ if (extent < 0)
+ {
+ extent = -extent;
+ start = 2 * Math.PI - extent + start;
+ }
+ this.start = start;
+ this.extent = extent;
+
+ type = a.type;
+ if (w < 0 || h < 0)
+ limit = -1;
+ else if (extent == 0)
+ limit = type;
+ else if (extent <= Math.PI / 2.0)
+ limit = type + 1;
+ else if (extent <= Math.PI)
+ limit = type + 2;
+ else if (extent <= 3.0 * (Math.PI / 2.0))
+ limit = type + 3;
+ else
+ limit = type + 4;
+ }
+
+ /**
+ * Construct a new iterator over an ellipse.
+ *
+ * @param e the ellipse
+ * @param xform the transform
+ */
+ public ArcIterator(Ellipse2D e, AffineTransform xform)
+ {
+ this.xform = xform;
+ x = e.getX();
+ y = e.getY();
+ w = e.getWidth();
+ h = e.getHeight();
+ start = 0;
+ extent = 2 * Math.PI;
+ type = CHORD;
+ limit = (w < 0 || h < 0) ? -1 : 5;
+ }
+
+ /**
+ * Return the winding rule.
+ *
+ * @return {@link PathIterator#WIND_NON_ZERO}
+ */
+ public int getWindingRule()
+ {
+ return WIND_NON_ZERO;
+ }
+
+ /**
+ * Test if the iteration is complete.
+ *
+ * @return true if more segments exist
+ */
+ public boolean isDone()
+ {
+ return current > limit;
+ }
+
+ /**
+ * Advance the iterator.
+ */
+ public void next()
+ {
+ current++;
+ }
+
+ /**
+ * Put the current segment into the array, and return the segment type.
+ *
+ * @param coords an array of 6 elements
+ * @return the segment type
+ * @throws NullPointerException if coords is null
+ * @throws ArrayIndexOutOfBoundsException if coords is too small
+ */
+ public int currentSegment(float[] coords)
+ {
+ double[] double_coords = new double[6];
+ int code = currentSegment(double_coords);
+ for (int i = 0; i < 6; ++i)
+ coords[i] = (float) double_coords[i];
+ return code;
+ }
+
+ /**
+ * Put the current segment into the array, and return the segment type.
+ *
+ * @param coords an array of 6 elements
+ * @return the segment type
+ * @throws NullPointerException if coords is null
+ * @throws ArrayIndexOutOfBoundsException if coords is too small
+ */
+ public int currentSegment(double[] coords)
+ {
+ double rx = w / 2;
+ double ry = h / 2;
+ double xmid = x + rx;
+ double ymid = y + ry;
+
+ if (current > limit)
+ throw new NoSuchElementException("arc iterator out of bounds");
+
+ if (current == 0)
+ {
+ coords[0] = xmid + rx * Math.cos(start);
+ coords[1] = ymid - ry * Math.sin(start);
+ if (xform != null)
+ xform.transform(coords, 0, coords, 0, 1);
+ return SEG_MOVETO;
+ }
+
+ if (type != OPEN && current == limit)
+ return SEG_CLOSE;
+
+ if ((current == limit - 1) && (type == PIE))
+ {
+ coords[0] = xmid;
+ coords[1] = ymid;
+ if (xform != null)
+ xform.transform(coords, 0, coords, 0, 1);
+ return SEG_LINETO;
+ }
+
+ // note that this produces a cubic approximation of the arc segment,
+ // not a true ellipsoid. there's no ellipsoid path segment code,
+ // unfortunately. the cubic approximation looks about right, though.
+ double kappa = (Math.sqrt(2.0) - 1.0) * (4.0 / 3.0);
+ double quad = (Math.PI / 2.0);
+
+ double curr_begin = start + (current - 1) * quad;
+ double curr_extent = Math.min((start + extent) - curr_begin, quad);
+ double portion_of_a_quadrant = curr_extent / quad;
+
+ double x0 = xmid + rx * Math.cos(curr_begin);
+ double y0 = ymid - ry * Math.sin(curr_begin);
+
+ double x1 = xmid + rx * Math.cos(curr_begin + curr_extent);
+ double y1 = ymid - ry * Math.sin(curr_begin + curr_extent);
+
+ AffineTransform trans = new AffineTransform();
+ double[] cvec = new double[2];
+ double len = kappa * portion_of_a_quadrant;
+ double angle = curr_begin;
+
+ // in a hypothetical "first quadrant" setting, our first control
+ // vector would be sticking up, from [1,0] to [1,kappa].
+ //
+ // let us recall however that in java2d, y coords are upside down
+ // from what one would consider "normal" first quadrant rules, so we
+ // will *subtract* the y value of this control vector from our first
+ // point.
+ cvec[0] = 0;
+ cvec[1] = len;
+ trans.scale(rx, ry);
+ trans.rotate(angle);
+ trans.transform(cvec, 0, cvec, 0, 1);
+ coords[0] = x0 + cvec[0];
+ coords[1] = y0 - cvec[1];
+
+ // control vector #2 would, ideally, be sticking out and to the
+ // right, in a first quadrant arc segment. again, subtraction of y.
+ cvec[0] = 0;
+ cvec[1] = -len;
+ trans.rotate(curr_extent);
+ trans.transform(cvec, 0, cvec, 0, 1);
+ coords[2] = x1 + cvec[0];
+ coords[3] = y1 - cvec[1];
+
+ // end point
+ coords[4] = x1;
+ coords[5] = y1;
+
+ if (xform != null)
+ xform.transform(coords, 0, coords, 0, 3);
+
+ return SEG_CUBICTO;
+ }
+ } // class ArcIterator
+
+ /**
+ * This class implements an arc in double precision.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ */
+ public static class Double extends Arc2D
+ {
+ /** The x coordinate of the box bounding the ellipse of this arc. */
+ public double x;
+
+ /** The y coordinate of the box bounding the ellipse of this arc. */
+ public double y;
+
+ /** The width of the box bounding the ellipse of this arc. */
+ public double width;
+
+ /** The height of the box bounding the ellipse of this arc. */
+ public double height;
+
+ /** The start angle of this arc, in degrees. */
+ public double start;
+
+ /** The extent angle of this arc, in degrees. */
+ public double extent;
+
+ /**
+ * Create a new, open arc at (0,0) with 0 extent.
+ */
+ public Double()
+ {
+ super(OPEN);
+ }
+
+ /**
+ * Create a new arc of the given type at (0,0) with 0 extent.
+ *
+ * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ */
+ public Double(int type)
+ {
+ super(type);
+ }
+
+ /**
+ * Create a new arc with the given dimensions.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ * @param start the start angle, in degrees
+ * @param extent the extent, in degrees
+ * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ */
+ public Double(double x, double y, double w, double h, double start,
+ double extent, int type)
+ {
+ super(type);
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ this.start = start;
+ this.extent = extent;
+ }
+
+ /**
+ * Create a new arc with the given dimensions.
+ *
+ * @param r the bounding box
+ * @param start the start angle, in degrees
+ * @param extent the extent, in degrees
+ * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ * @throws NullPointerException if r is null
+ */
+ public Double(Rectangle2D r, double start, double extent, int type)
+ {
+ super(type);
+ x = r.getX();
+ y = r.getY();
+ width = r.getWidth();
+ height = r.getHeight();
+ this.start = start;
+ this.extent = extent;
+ }
+
+ /**
+ * Return the x coordinate of the bounding box.
+ *
+ * @return the value of x
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Return the y coordinate of the bounding box.
+ *
+ * @return the value of y
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Return the width of the bounding box.
+ *
+ * @return the value of width
+ */
+ public double getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Return the height of the bounding box.
+ *
+ * @return the value of height
+ */
+ public double getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Return the start angle of the arc, in degrees.
+ *
+ * @return the value of start
+ */
+ public double getAngleStart()
+ {
+ return start;
+ }
+
+ /**
+ * Return the extent of the arc, in degrees.
+ *
+ * @return the value of extent
+ */
+ public double getAngleExtent()
+ {
+ return extent;
+ }
+
+ /**
+ * Tests if the arc contains points.
+ *
+ * @return true if the arc has no interior
+ */
+ public boolean isEmpty()
+ {
+ return width <= 0 || height <= 0;
+ }
+
+ /**
+ * Sets the arc to the given dimensions.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ * @param start the start angle, in degrees
+ * @param extent the extent, in degrees
+ * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ */
+ public void setArc(double x, double y, double w, double h, double start,
+ double extent, int type)
+ {
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ this.start = start;
+ this.extent = extent;
+ setArcType(type);
+ }
+
+ /**
+ * Sets the start angle of the arc.
+ *
+ * @param start the new start angle
+ */
+ public void setAngleStart(double start)
+ {
+ this.start = start;
+ }
+
+ /**
+ * Sets the extent angle of the arc.
+ *
+ * @param extent the new extent angle
+ */
+ public void setAngleExtent(double extent)
+ {
+ this.extent = extent;
+ }
+
+ /**
+ * Creates a tight bounding box given dimensions that more precise than
+ * the bounding box of the ellipse.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ protected Rectangle2D makeBounds(double x, double y, double w, double h)
+ {
+ return new Rectangle2D.Double(x, y, w, h);
+ }
+ } // class Double
+
+ /**
+ * This class implements an arc in float precision.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ */
+ public static class Float extends Arc2D
+ {
+ /** The x coordinate of the box bounding the ellipse of this arc. */
+ public float x;
+
+ /** The y coordinate of the box bounding the ellipse of this arc. */
+ public float y;
+
+ /** The width of the box bounding the ellipse of this arc. */
+ public float width;
+
+ /** The height of the box bounding the ellipse of this arc. */
+ public float height;
+
+ /** The start angle of this arc, in degrees. */
+ public float start;
+
+ /** The extent angle of this arc, in degrees. */
+ public float extent;
+
+ /**
+ * Create a new, open arc at (0,0) with 0 extent.
+ */
+ public Float()
+ {
+ super(OPEN);
+ }
+
+ /**
+ * Create a new arc of the given type at (0,0) with 0 extent.
+ *
+ * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ */
+ public Float(int type)
+ {
+ super(type);
+ }
+
+ /**
+ * Create a new arc with the given dimensions.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ * @param start the start angle, in degrees
+ * @param extent the extent, in degrees
+ * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ */
+ public Float(float x, float y, float w, float h, float start,
+ float extent, int type)
+ {
+ super(type);
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ this.start = start;
+ this.extent = extent;
+ }
+
+ /**
+ * Create a new arc with the given dimensions.
+ *
+ * @param r the bounding box
+ * @param start the start angle, in degrees
+ * @param extent the extent, in degrees
+ * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ * @throws NullPointerException if r is null
+ */
+ public Float(Rectangle2D r, float start, float extent, int type)
+ {
+ super(type);
+ x = (float) r.getX();
+ y = (float) r.getY();
+ width = (float) r.getWidth();
+ height = (float) r.getHeight();
+ this.start = start;
+ this.extent = (float) extent;
+ }
+
+ /**
+ * Return the x coordinate of the bounding box.
+ *
+ * @return the value of x
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Return the y coordinate of the bounding box.
+ *
+ * @return the value of y
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Return the width of the bounding box.
+ *
+ * @return the value of width
+ */
+ public double getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Return the height of the bounding box.
+ *
+ * @return the value of height
+ */
+ public double getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Return the start angle of the arc, in degrees.
+ *
+ * @return the value of start
+ */
+ public double getAngleStart()
+ {
+ return start;
+ }
+
+ /**
+ * Return the extent of the arc, in degrees.
+ *
+ * @return the value of extent
+ */
+ public double getAngleExtent()
+ {
+ return extent;
+ }
+
+ /**
+ * Tests if the arc contains points.
+ *
+ * @return true if the arc has no interior
+ */
+ public boolean isEmpty()
+ {
+ return width <= 0 || height <= 0;
+ }
+
+ /**
+ * Sets the arc to the given dimensions.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ * @param start the start angle, in degrees
+ * @param extent the extent, in degrees
+ * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
+ * @throws IllegalArgumentException if type is invalid
+ */
+ public void setArc(double x, double y, double w, double h, double start,
+ double extent, int type)
+ {
+ this.x = (float) x;
+ this.y = (float) y;
+ width = (float) w;
+ height = (float) h;
+ this.start = (float) start;
+ this.extent = (float) extent;
+ setArcType(type);
+ }
+
+ /**
+ * Sets the start angle of the arc.
+ *
+ * @param start the new start angle
+ */
+ public void setAngleStart(double start)
+ {
+ this.start = (float) start;
+ }
+
+ /**
+ * Sets the extent angle of the arc.
+ *
+ * @param extent the new extent angle
+ */
+ public void setAngleExtent(double extent)
+ {
+ this.extent = (float) extent;
+ }
+
+ /**
+ * Creates a tight bounding box given dimensions that more precise than
+ * the bounding box of the ellipse.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ protected Rectangle2D makeBounds(double x, double y, double w, double h)
+ {
+ return new Rectangle2D.Float((float) x, (float) y, (float) w, (float) h);
+ }
+ } // class Float
+} // class Arc2D
diff --git a/libjava/classpath/java/awt/geom/Area.java b/libjava/classpath/java/awt/geom/Area.java
new file mode 100644
index 0000000..7a0fac4
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/Area.java
@@ -0,0 +1,3312 @@
+/* Area.java -- represents a shape built by constructive area geometry
+ Copyright (C) 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.Vector;
+
+
+/**
+ * The Area class represents any area for the purpose of
+ * Constructive Area Geometry (CAG) manipulations. CAG manipulations
+ * work as an area-wise form of boolean logic, where the basic operations are:
+ * <P><li>Add (in boolean algebra: A <B>or</B> B)<BR>
+ * <li>Subtract (in boolean algebra: A <B>and</B> (<B>not</B> B) )<BR>
+ * <li>Intersect (in boolean algebra: A <B>and</B> B)<BR>
+ * <li>Exclusive Or <BR>
+ * <img src="doc-files/Area-1.png" width="342" height="302"
+ * alt="Illustration of CAG operations" /><BR>
+ * Above is an illustration of the CAG operations on two ring shapes.<P>
+ *
+ * The contains and intersects() methods are also more accurate than the
+ * specification of #Shape requires.<P>
+ *
+ * Please note that constructing an Area can be slow
+ * (Self-intersection resolving is proportional to the square of
+ * the number of segments).<P>
+ * @see #add(Area)
+ * @see #subtract(Area)
+ * @see #intersect(Area)
+ * @see #exclusiveOr(Area)
+ *
+ * @author Sven de Marothy (sven@physto.se)
+ *
+ * @since 1.2
+ * @status Works, but could be faster and more reliable.
+ */
+public class Area implements Shape, Cloneable
+{
+ /**
+ * General numerical precision
+ */
+ private static final double EPSILON = 1E-11;
+
+ /**
+ * recursive subdivision epsilon - (see getRecursionDepth)
+ */
+ private static final double RS_EPSILON = 1E-13;
+
+ /**
+ * Snap distance - points within this distance are considered equal
+ */
+ private static final double PE_EPSILON = 1E-11;
+
+ /**
+ * Segment vectors containing solid areas and holes
+ * This is package-private to avoid an accessor method.
+ */
+ Vector solids;
+
+ /**
+ * Segment vectors containing solid areas and holes
+ * This is package-private to avoid an accessor method.
+ */
+ Vector holes;
+
+ /**
+ * Vector (temporary) storing curve-curve intersections
+ */
+ private Vector cc_intersections;
+
+ /**
+ * Winding rule WIND_NON_ZERO used, after construction,
+ * this is irrelevant.
+ */
+ private int windingRule;
+
+ /**
+ * Constructs an empty Area
+ */
+ public Area()
+ {
+ solids = new Vector();
+ holes = new Vector();
+ }
+
+ /**
+ * Constructs an Area from any given Shape. <P>
+ *
+ * If the Shape is self-intersecting, the created Area will consist
+ * of non-self-intersecting subpaths, and any inner paths which
+ * are found redundant in accordance with the Shape's winding rule
+ * will not be included.
+ *
+ * @param s the shape (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>s</code> is <code>null</code>.
+ */
+ public Area(Shape s)
+ {
+ this();
+
+ Vector p = makeSegment(s);
+
+ // empty path
+ if (p == null)
+ return;
+
+ // delete empty paths
+ for (int i = 0; i < p.size(); i++)
+ if (((Segment) p.elementAt(i)).getSignedArea() == 0.0)
+ p.remove(i--);
+
+ /*
+ * Resolve self intersecting paths into non-intersecting
+ * solids and holes.
+ * Algorithm is as follows:
+ * 1: Create nodes at all self intersections
+ * 2: Put all segments into a list
+ * 3: Grab a segment, follow it, change direction at each node,
+ * removing segments from the list in the process
+ * 4: Repeat (3) until no segments remain in the list
+ * 5: Remove redundant paths and sort into solids and holes
+ */
+ Vector paths = new Vector();
+ Segment v;
+
+ for (int i = 0; i < p.size(); i++)
+ {
+ Segment path = (Segment) p.elementAt(i);
+ createNodesSelf(path);
+ }
+
+ if (p.size() > 1)
+ {
+ for (int i = 0; i < p.size() - 1; i++)
+ for (int j = i + 1; j < p.size(); j++)
+ {
+ Segment path1 = (Segment) p.elementAt(i);
+ Segment path2 = (Segment) p.elementAt(j);
+ createNodes(path1, path2);
+ }
+ }
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ for (int i = 0; i < p.size(); i++)
+ {
+ Segment path = v = (Segment) p.elementAt(i);
+ do
+ {
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
+ }
+
+ /**
+ * Performs an add (union) operation on this area with another Area.<BR>
+ * @param area - the area to be unioned with this one
+ */
+ public void add(Area area)
+ {
+ if (equals(area))
+ return;
+ if (area.isEmpty())
+ return;
+
+ Area B = (Area) area.clone();
+
+ Vector pathA = new Vector();
+ Vector pathB = new Vector();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+ pathB.addAll(B.solids);
+ pathB.addAll(B.holes);
+
+ int nNodes = 0;
+
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment a = (Segment) pathA.elementAt(i);
+ for (int j = 0; j < pathB.size(); j++)
+ {
+ Segment b = (Segment) pathB.elementAt(j);
+ nNodes += createNodes(a, b);
+ }
+ }
+
+ Vector paths = new Vector();
+ Segment v;
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ // In a union operation, we keep all
+ // segments of A oustide B and all B outside A
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ v = (Segment) pathA.elementAt(i);
+ Segment path = v;
+ do
+ {
+ if (v.isSegmentOutside(area))
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ for (int i = 0; i < pathB.size(); i++)
+ {
+ v = (Segment) pathB.elementAt(i);
+ Segment path = v;
+ do
+ {
+ if (v.isSegmentOutside(this))
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
+ }
+
+ /**
+ * Performs a subtraction operation on this Area.<BR>
+ * @param area the area to be subtracted from this area.
+ * @throws NullPointerException if <code>area</code> is <code>null</code>.
+ */
+ public void subtract(Area area)
+ {
+ if (isEmpty() || area.isEmpty())
+ return;
+
+ if (equals(area))
+ {
+ reset();
+ return;
+ }
+
+ Vector pathA = new Vector();
+ Area B = (Area) area.clone();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+
+ // reverse the directions of B paths.
+ setDirection(B.holes, true);
+ setDirection(B.solids, false);
+
+ Vector pathB = new Vector();
+ pathB.addAll(B.solids);
+ pathB.addAll(B.holes);
+
+ int nNodes = 0;
+
+ // create nodes
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment a = (Segment) pathA.elementAt(i);
+ for (int j = 0; j < pathB.size(); j++)
+ {
+ Segment b = (Segment) pathB.elementAt(j);
+ nNodes += createNodes(a, b);
+ }
+ }
+
+ Vector paths = new Vector();
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ // In a subtraction operation, we keep all
+ // segments of A oustide B and all B within A
+ // We outsideness-test only one segment in each path
+ // and the segments before and after any node
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment v = (Segment) pathA.elementAt(i);
+ Segment path = v;
+ if (v.isSegmentOutside(area) && v.node == null)
+ segments.add(v);
+ boolean node = false;
+ do
+ {
+ if ((v.node != null || node))
+ {
+ node = (v.node != null);
+ if (v.isSegmentOutside(area))
+ segments.add(v);
+ }
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ for (int i = 0; i < pathB.size(); i++)
+ {
+ Segment v = (Segment) pathB.elementAt(i);
+ Segment path = v;
+ if (! v.isSegmentOutside(this) && v.node == null)
+ segments.add(v);
+ v = v.next;
+ boolean node = false;
+ do
+ {
+ if ((v.node != null || node))
+ {
+ node = (v.node != null);
+ if (! v.isSegmentOutside(this))
+ segments.add(v);
+ }
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
+ }
+
+ /**
+ * Performs an intersection operation on this Area.<BR>
+ * @param area - the area to be intersected with this area.
+ * @throws NullPointerException if <code>area</code> is <code>null</code>.
+ */
+ public void intersect(Area area)
+ {
+ if (isEmpty() || area.isEmpty())
+ {
+ reset();
+ return;
+ }
+ if (equals(area))
+ return;
+
+ Vector pathA = new Vector();
+ Area B = (Area) area.clone();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+
+ Vector pathB = new Vector();
+ pathB.addAll(B.solids);
+ pathB.addAll(B.holes);
+
+ int nNodes = 0;
+
+ // create nodes
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment a = (Segment) pathA.elementAt(i);
+ for (int j = 0; j < pathB.size(); j++)
+ {
+ Segment b = (Segment) pathB.elementAt(j);
+ nNodes += createNodes(a, b);
+ }
+ }
+
+ Vector paths = new Vector();
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ // In an intersection operation, we keep all
+ // segments of A within B and all B within A
+ // (The rest must be redundant)
+ // We outsideness-test only one segment in each path
+ // and the segments before and after any node
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment v = (Segment) pathA.elementAt(i);
+ Segment path = v;
+ if (! v.isSegmentOutside(area) && v.node == null)
+ segments.add(v);
+ boolean node = false;
+ do
+ {
+ if ((v.node != null || node))
+ {
+ node = (v.node != null);
+ if (! v.isSegmentOutside(area))
+ segments.add(v);
+ }
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ for (int i = 0; i < pathB.size(); i++)
+ {
+ Segment v = (Segment) pathB.elementAt(i);
+ Segment path = v;
+ if (! v.isSegmentOutside(this) && v.node == null)
+ segments.add(v);
+ v = v.next;
+ boolean node = false;
+ do
+ {
+ if ((v.node != null || node))
+ {
+ node = (v.node != null);
+ if (! v.isSegmentOutside(this))
+ segments.add(v);
+ }
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
+ }
+
+ /**
+ * Performs an exclusive-or operation on this Area.<BR>
+ * @param area - the area to be XORed with this area.
+ * @throws NullPointerException if <code>area</code> is <code>null</code>.
+ */
+ public void exclusiveOr(Area area)
+ {
+ if (area.isEmpty())
+ return;
+
+ if (isEmpty())
+ {
+ Area B = (Area) area.clone();
+ solids = B.solids;
+ holes = B.holes;
+ return;
+ }
+ if (equals(area))
+ {
+ reset();
+ return;
+ }
+
+ Vector pathA = new Vector();
+
+ Area B = (Area) area.clone();
+ Vector pathB = new Vector();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+
+ // reverse the directions of B paths.
+ setDirection(B.holes, true);
+ setDirection(B.solids, false);
+ pathB.addAll(B.solids);
+ pathB.addAll(B.holes);
+
+ int nNodes = 0;
+
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment a = (Segment) pathA.elementAt(i);
+ for (int j = 0; j < pathB.size(); j++)
+ {
+ Segment b = (Segment) pathB.elementAt(j);
+ nNodes += createNodes(a, b);
+ }
+ }
+
+ Vector paths = new Vector();
+ Segment v;
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ // In an XOR operation, we operate on all segments
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ v = (Segment) pathA.elementAt(i);
+ Segment path = v;
+ do
+ {
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ for (int i = 0; i < pathB.size(); i++)
+ {
+ v = (Segment) pathB.elementAt(i);
+ Segment path = v;
+ do
+ {
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
+ }
+
+ /**
+ * Clears the Area object, creating an empty area.
+ */
+ public void reset()
+ {
+ solids = new Vector();
+ holes = new Vector();
+ }
+
+ /**
+ * Returns whether this area encloses any area.
+ * @return true if the object encloses any area.
+ */
+ public boolean isEmpty()
+ {
+ if (solids.size() == 0)
+ return true;
+
+ double totalArea = 0;
+ for (int i = 0; i < solids.size(); i++)
+ totalArea += Math.abs(((Segment) solids.elementAt(i)).getSignedArea());
+ for (int i = 0; i < holes.size(); i++)
+ totalArea -= Math.abs(((Segment) holes.elementAt(i)).getSignedArea());
+ if (totalArea <= EPSILON)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Determines whether the Area consists entirely of line segments
+ * @return true if the Area lines-only, false otherwise
+ */
+ public boolean isPolygonal()
+ {
+ for (int i = 0; i < holes.size(); i++)
+ if (! ((Segment) holes.elementAt(i)).isPolygonal())
+ return false;
+ for (int i = 0; i < solids.size(); i++)
+ if (! ((Segment) solids.elementAt(i)).isPolygonal())
+ return false;
+ return true;
+ }
+
+ /**
+ * Determines if the Area is rectangular.<P>
+ *
+ * This is strictly qualified. An area is considered rectangular if:<BR>
+ * <li>It consists of a single polygonal path.<BR>
+ * <li>It is oriented parallel/perpendicular to the xy axis<BR>
+ * <li>It must be exactly rectangular, i.e. small errors induced by
+ * transformations may cause a false result, although the area is
+ * visibly rectangular.<P>
+ * @return true if the above criteria are met, false otherwise
+ */
+ public boolean isRectangular()
+ {
+ if (isEmpty())
+ return true;
+
+ if (holes.size() != 0 || solids.size() != 1)
+ return false;
+
+ Segment path = (Segment) solids.elementAt(0);
+ if (! path.isPolygonal())
+ return false;
+
+ int nCorners = 0;
+ Segment s = path;
+ do
+ {
+ Segment s2 = s.next;
+ double d1 = (s.P2.getX() - s.P1.getX())*(s2.P2.getX() - s2.P1.getX())/
+ ((s.P1.distance(s.P2)) * (s2.P1.distance(s2.P2)));
+ double d2 = (s.P2.getY() - s.P1.getY())*(s2.P2.getY() - s2.P1.getY())/
+ ((s.P1.distance(s.P2)) * (s2.P1.distance(s2.P2)));
+ double dotproduct = d1 + d2;
+
+ // For some reason, only rectangles on the XY axis count.
+ if (d1 != 0 && d2 != 0)
+ return false;
+
+ if (Math.abs(dotproduct) == 0) // 90 degree angle
+ nCorners++;
+ else if ((Math.abs(1.0 - dotproduct) > 0)) // 0 degree angle?
+ return false; // if not, return false
+
+ s = s.next;
+ }
+ while (s != path);
+
+ return nCorners == 4;
+ }
+
+ /**
+ * Returns whether the Area consists of more than one simple
+ * (non self-intersecting) subpath.
+ *
+ * @return true if the Area consists of none or one simple subpath,
+ * false otherwise.
+ */
+ public boolean isSingular()
+ {
+ return (holes.size() == 0 && solids.size() <= 1);
+ }
+
+ /**
+ * Returns the bounding box of the Area.<P> Unlike the CubicCurve2D and
+ * QuadraticCurve2D classes, this method will return the tightest possible
+ * bounding box, evaluating the extreme points of each curved segment.<P>
+ * @return the bounding box
+ */
+ public Rectangle2D getBounds2D()
+ {
+ if (solids.size() == 0)
+ return new Rectangle2D.Double(0.0, 0.0, 0.0, 0.0);
+
+ double xmin;
+ double xmax;
+ double ymin;
+ double ymax;
+ xmin = xmax = ((Segment) solids.elementAt(0)).P1.getX();
+ ymin = ymax = ((Segment) solids.elementAt(0)).P1.getY();
+
+ for (int path = 0; path < solids.size(); path++)
+ {
+ Rectangle2D r = ((Segment) solids.elementAt(path)).getPathBounds();
+ xmin = Math.min(r.getMinX(), xmin);
+ ymin = Math.min(r.getMinY(), ymin);
+ xmax = Math.max(r.getMaxX(), xmax);
+ ymax = Math.max(r.getMaxY(), ymax);
+ }
+
+ return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
+ }
+
+ /**
+ * Returns the bounds of this object in Rectangle format.
+ * Please note that this may lead to loss of precision.
+ *
+ * @return The bounds.
+ * @see #getBounds2D()
+ */
+ public Rectangle getBounds()
+ {
+ return getBounds2D().getBounds();
+ }
+
+ /**
+ * Create a new area of the same run-time type with the same contents as
+ * this one.
+ *
+ * @return the clone
+ */
+ public Object clone()
+ {
+ try
+ {
+ Area clone = new Area();
+ for (int i = 0; i < solids.size(); i++)
+ clone.solids.add(((Segment) solids.elementAt(i)).cloneSegmentList());
+ for (int i = 0; i < holes.size(); i++)
+ clone.holes.add(((Segment) holes.elementAt(i)).cloneSegmentList());
+ return clone;
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+
+ /**
+ * Compares two Areas.
+ *
+ * @param area the area to compare against this area (<code>null</code>
+ * permitted).
+ * @return <code>true</code> if the areas are equal, and <code>false</code>
+ * otherwise.
+ */
+ public boolean equals(Area area)
+ {
+ if (area == null)
+ return false;
+
+ if (! getBounds2D().equals(area.getBounds2D()))
+ return false;
+
+ if (solids.size() != area.solids.size()
+ || holes.size() != area.holes.size())
+ return false;
+
+ Vector pathA = new Vector();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+ Vector pathB = new Vector();
+ pathB.addAll(area.solids);
+ pathB.addAll(area.holes);
+
+ int nPaths = pathA.size();
+ boolean[][] match = new boolean[2][nPaths];
+
+ for (int i = 0; i < nPaths; i++)
+ {
+ for (int j = 0; j < nPaths; j++)
+ {
+ Segment p1 = (Segment) pathA.elementAt(i);
+ Segment p2 = (Segment) pathB.elementAt(j);
+ if (! match[0][i] && ! match[1][j])
+ if (p1.pathEquals(p2))
+ match[0][i] = match[1][j] = true;
+ }
+ }
+
+ boolean result = true;
+ for (int i = 0; i < nPaths; i++)
+ result = result && match[0][i] && match[1][i];
+ return result;
+ }
+
+ /**
+ * Transforms this area by the AffineTransform at.
+ *
+ * @param at the transform.
+ */
+ public void transform(AffineTransform at)
+ {
+ for (int i = 0; i < solids.size(); i++)
+ ((Segment) solids.elementAt(i)).transformSegmentList(at);
+ for (int i = 0; i < holes.size(); i++)
+ ((Segment) holes.elementAt(i)).transformSegmentList(at);
+
+ // Note that the orientation is not invariant under inversion
+ if ((at.getType() & AffineTransform.TYPE_FLIP) != 0)
+ {
+ setDirection(holes, false);
+ setDirection(solids, true);
+ }
+ }
+
+ /**
+ * Returns a new Area equal to this one, transformed
+ * by the AffineTransform at.
+ * @param at the transform.
+ * @return the transformed area
+ * @throws NullPointerException if <code>at</code> is <code>null</code>.
+ */
+ public Area createTransformedArea(AffineTransform at)
+ {
+ Area a = (Area) clone();
+ a.transform(at);
+ return a;
+ }
+
+ /**
+ * Determines if the point (x,y) is contained within this Area.
+ *
+ * @param x the x-coordinate of the point.
+ * @param y the y-coordinate of the point.
+ * @return true if the point is contained, false otherwise.
+ */
+ public boolean contains(double x, double y)
+ {
+ int n = 0;
+ for (int i = 0; i < solids.size(); i++)
+ if (((Segment) solids.elementAt(i)).contains(x, y))
+ n++;
+
+ for (int i = 0; i < holes.size(); i++)
+ if (((Segment) holes.elementAt(i)).contains(x, y))
+ n--;
+
+ return (n != 0);
+ }
+
+ /**
+ * Determines if the Point2D p is contained within this Area.
+ *
+ * @param p the point.
+ * @return <code>true</code> if the point is contained, <code>false</code>
+ * otherwise.
+ * @throws NullPointerException if <code>p</code> is <code>null</code>.
+ */
+ public boolean contains(Point2D p)
+ {
+ return contains(p.getX(), p.getY());
+ }
+
+ /**
+ * Determines if the rectangle specified by (x,y) as the upper-left
+ * and with width w and height h is completely contained within this Area,
+ * returns false otherwise.<P>
+ *
+ * This method should always produce the correct results, unlike for other
+ * classes in geom.
+ *
+ * @param x the x-coordinate of the rectangle.
+ * @param y the y-coordinate of the rectangle.
+ * @param w the width of the the rectangle.
+ * @param h the height of the rectangle.
+ * @return <code>true</code> if the rectangle is considered contained
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ LineSegment[] l = new LineSegment[4];
+ l[0] = new LineSegment(x, y, x + w, y);
+ l[1] = new LineSegment(x, y + h, x + w, y + h);
+ l[2] = new LineSegment(x, y, x, y + h);
+ l[3] = new LineSegment(x + w, y, x + w, y + h);
+
+ // Since every segment in the area must a contour
+ // between inside/outside segments, ANY intersection
+ // will mean the rectangle is not entirely contained.
+ for (int i = 0; i < 4; i++)
+ {
+ for (int path = 0; path < solids.size(); path++)
+ {
+ Segment v;
+ Segment start;
+ start = v = (Segment) solids.elementAt(path);
+ do
+ {
+ if (l[i].hasIntersections(v))
+ return false;
+ v = v.next;
+ }
+ while (v != start);
+ }
+ for (int path = 0; path < holes.size(); path++)
+ {
+ Segment v;
+ Segment start;
+ start = v = (Segment) holes.elementAt(path);
+ do
+ {
+ if (l[i].hasIntersections(v))
+ return false;
+ v = v.next;
+ }
+ while (v != start);
+ }
+ }
+
+ // Is any point inside?
+ if (! contains(x, y))
+ return false;
+
+ // Final hoop: Is the rectangle non-intersecting and inside,
+ // but encloses a hole?
+ Rectangle2D r = new Rectangle2D.Double(x, y, w, h);
+ for (int path = 0; path < holes.size(); path++)
+ if (! ((Segment) holes.elementAt(path)).isSegmentOutside(r))
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Determines if the Rectangle2D specified by r is completely contained
+ * within this Area, returns false otherwise.<P>
+ *
+ * This method should always produce the correct results, unlike for other
+ * classes in geom.
+ *
+ * @param r the rectangle.
+ * @return <code>true</code> if the rectangle is considered contained
+ *
+ * @throws NullPointerException if <code>r</code> is <code>null</code>.
+ */
+ public boolean contains(Rectangle2D r)
+ {
+ return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Determines if the rectangle specified by (x,y) as the upper-left
+ * and with width w and height h intersects any part of this Area.
+ *
+ * @param x the x-coordinate for the rectangle.
+ * @param y the y-coordinate for the rectangle.
+ * @param w the width of the rectangle.
+ * @param h the height of the rectangle.
+ * @return <code>true</code> if the rectangle intersects the area,
+ * <code>false</code> otherwise.
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ if (solids.size() == 0)
+ return false;
+
+ LineSegment[] l = new LineSegment[4];
+ l[0] = new LineSegment(x, y, x + w, y);
+ l[1] = new LineSegment(x, y + h, x + w, y + h);
+ l[2] = new LineSegment(x, y, x, y + h);
+ l[3] = new LineSegment(x + w, y, x + w, y + h);
+
+ // Return true on any intersection
+ for (int i = 0; i < 4; i++)
+ {
+ for (int path = 0; path < solids.size(); path++)
+ {
+ Segment v;
+ Segment start;
+ start = v = (Segment) solids.elementAt(path);
+ do
+ {
+ if (l[i].hasIntersections(v))
+ return true;
+ v = v.next;
+ }
+ while (v != start);
+ }
+ for (int path = 0; path < holes.size(); path++)
+ {
+ Segment v;
+ Segment start;
+ start = v = (Segment) holes.elementAt(path);
+ do
+ {
+ if (l[i].hasIntersections(v))
+ return true;
+ v = v.next;
+ }
+ while (v != start);
+ }
+ }
+
+ // Non-intersecting, Is any point inside?
+ if (contains(x + w * 0.5, y + h * 0.5))
+ return true;
+
+ // What if the rectangle encloses the whole shape?
+ Point2D p = ((Segment) solids.elementAt(0)).getMidPoint();
+ if ((new Rectangle2D.Double(x, y, w, h)).contains(p))
+ return true;
+ return false;
+ }
+
+ /**
+ * Determines if the Rectangle2D specified by r intersects any
+ * part of this Area.
+ * @param r the rectangle to test intersection with (<code>null</code>
+ * not permitted).
+ * @return <code>true</code> if the rectangle intersects the area,
+ * <code>false</code> otherwise.
+ * @throws NullPointerException if <code>r</code> is <code>null</code>.
+ */
+ public boolean intersects(Rectangle2D r)
+ {
+ return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Returns a PathIterator object defining the contour of this Area,
+ * transformed by at.
+ *
+ * @param at the transform.
+ * @return A path iterator.
+ */
+ public PathIterator getPathIterator(AffineTransform at)
+ {
+ return (new AreaIterator(at));
+ }
+
+ /**
+ * Returns a flattened PathIterator object defining the contour of this
+ * Area, transformed by at and with a defined flatness.
+ *
+ * @param at the transform.
+ * @param flatness the flatness.
+ * @return A path iterator.
+ */
+ public PathIterator getPathIterator(AffineTransform at, double flatness)
+ {
+ return new FlatteningPathIterator(getPathIterator(at), flatness);
+ }
+
+ //---------------------------------------------------------------------
+ // Non-public methods and classes
+
+ /**
+ * Private pathiterator object.
+ */
+ private class AreaIterator implements PathIterator
+ {
+ private Vector segments;
+ private int index;
+ private AffineTransform at;
+
+ // Simple compound type for segments
+ class IteratorSegment
+ {
+ int type;
+ double[] coords;
+
+ IteratorSegment()
+ {
+ coords = new double[6];
+ }
+ }
+
+ /**
+ * The contructor here does most of the work,
+ * creates a vector of IteratorSegments, which can
+ * readily be returned
+ */
+ public AreaIterator(AffineTransform at)
+ {
+ this.at = at;
+ index = 0;
+ segments = new Vector();
+ Vector allpaths = new Vector();
+ allpaths.addAll(solids);
+ allpaths.addAll(holes);
+
+ for (int i = 0; i < allpaths.size(); i++)
+ {
+ Segment v = (Segment) allpaths.elementAt(i);
+ Segment start = v;
+
+ IteratorSegment is = new IteratorSegment();
+ is.type = SEG_MOVETO;
+ is.coords[0] = start.P1.getX();
+ is.coords[1] = start.P1.getY();
+ segments.add(is);
+
+ do
+ {
+ is = new IteratorSegment();
+ is.type = v.pathIteratorFormat(is.coords);
+ segments.add(is);
+ v = v.next;
+ }
+ while (v != start);
+
+ is = new IteratorSegment();
+ is.type = SEG_CLOSE;
+ segments.add(is);
+ }
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ IteratorSegment s = (IteratorSegment) segments.elementAt(index);
+ if (at != null)
+ at.transform(s.coords, 0, coords, 0, 3);
+ else
+ for (int i = 0; i < 6; i++)
+ coords[i] = s.coords[i];
+ return (s.type);
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ IteratorSegment s = (IteratorSegment) segments.elementAt(index);
+ double[] d = new double[6];
+ if (at != null)
+ {
+ at.transform(s.coords, 0, d, 0, 3);
+ for (int i = 0; i < 6; i++)
+ coords[i] = (float) d[i];
+ }
+ else
+ for (int i = 0; i < 6; i++)
+ coords[i] = (float) s.coords[i];
+ return (s.type);
+ }
+
+ // Note that the winding rule should not matter here,
+ // EVEN_ODD is chosen because it renders faster.
+ public int getWindingRule()
+ {
+ return (PathIterator.WIND_EVEN_ODD);
+ }
+
+ public boolean isDone()
+ {
+ return (index >= segments.size());
+ }
+
+ public void next()
+ {
+ index++;
+ }
+ }
+
+ /**
+ * Performs the fundamental task of the Weiler-Atherton algorithm,
+ * traverse a list of segments, for each segment:
+ * Follow it, removing segments from the list and switching paths
+ * at each node. Do so until the starting segment is reached.
+ *
+ * Returns a Vector of the resulting paths.
+ */
+ private Vector weilerAtherton(Vector segments)
+ {
+ Vector paths = new Vector();
+ while (segments.size() > 0)
+ {
+ // Iterate over the path
+ Segment start = (Segment) segments.elementAt(0);
+ Segment s = start;
+ do
+ {
+ segments.remove(s);
+ if (s.node != null)
+ { // switch over
+ s.next = s.node;
+ s.node = null;
+ }
+ s = s.next; // continue
+ }
+ while (s != start);
+
+ paths.add(start);
+ }
+ return paths;
+ }
+
+ /**
+ * A small wrapper class to store intersection points
+ */
+ private class Intersection
+ {
+ Point2D p; // the 2D point of intersection
+ double ta; // the parametric value on a
+ double tb; // the parametric value on b
+ Segment seg; // segment placeholder for node setting
+
+ public Intersection(Point2D p, double ta, double tb)
+ {
+ this.p = p;
+ this.ta = ta;
+ this.tb = tb;
+ }
+ }
+
+ /**
+ * Returns the recursion depth necessary to approximate the
+ * curve by line segments within the error RS_EPSILON.
+ *
+ * This is done with Wang's formula:
+ * L0 = max{0<=i<=N-2}(|xi - 2xi+1 + xi+2|,|yi - 2yi+1 + yi+2|)
+ * r0 = log4(sqrt(2)*N*(N-1)*L0/8e)
+ * Where e is the maximum distance error (RS_EPSILON)
+ */
+ private int getRecursionDepth(CubicSegment curve)
+ {
+ double x0 = curve.P1.getX();
+ double y0 = curve.P1.getY();
+
+ double x1 = curve.cp1.getX();
+ double y1 = curve.cp1.getY();
+
+ double x2 = curve.cp2.getX();
+ double y2 = curve.cp2.getY();
+
+ double x3 = curve.P2.getX();
+ double y3 = curve.P2.getY();
+
+ double L0 = Math.max(Math.max(Math.abs(x0 - 2 * x1 + x2),
+ Math.abs(x1 - 2 * x2 + x3)),
+ Math.max(Math.abs(y0 - 2 * y1 + y2),
+ Math.abs(y1 - 2 * y2 + y3)));
+
+ double f = Math.sqrt(2) * 6.0 * L0 / (8.0 * RS_EPSILON);
+
+ int r0 = (int) Math.ceil(Math.log(f) / Math.log(4.0));
+ return (r0);
+ }
+
+ /**
+ * Performs recursive subdivision:
+ * @param c1 - curve 1
+ * @param c2 - curve 2
+ * @param depth1 - recursion depth of curve 1
+ * @param depth2 - recursion depth of curve 2
+ * @param t1 - global parametric value of the first curve's starting point
+ * @param t2 - global parametric value of the second curve's starting point
+ * @param w1 - global parametric length of curve 1
+ * @param c1 - global parametric length of curve 2
+ *
+ * The final four parameters are for keeping track of the parametric
+ * value of the curve. For a full curve t = 0, w = 1, w is halved with
+ * each subdivision.
+ */
+ private void recursiveSubdivide(CubicCurve2D c1, CubicCurve2D c2,
+ int depth1, int depth2, double t1,
+ double t2, double w1, double w2)
+ {
+ boolean flat1 = depth1 <= 0;
+ boolean flat2 = depth2 <= 0;
+
+ if (flat1 && flat2)
+ {
+ double xlk = c1.getP2().getX() - c1.getP1().getX();
+ double ylk = c1.getP2().getY() - c1.getP1().getY();
+
+ double xnm = c2.getP2().getX() - c2.getP1().getX();
+ double ynm = c2.getP2().getY() - c2.getP1().getY();
+
+ double xmk = c2.getP1().getX() - c1.getP1().getX();
+ double ymk = c2.getP1().getY() - c1.getP1().getY();
+ double det = xnm * ylk - ynm * xlk;
+
+ if (det + 1.0 == 1.0)
+ return;
+
+ double detinv = 1.0 / det;
+ double s = (xnm * ymk - ynm * xmk) * detinv;
+ double t = (xlk * ymk - ylk * xmk) * detinv;
+ if ((s < 0.0) || (s > 1.0) || (t < 0.0) || (t > 1.0))
+ return;
+
+ double[] temp = new double[2];
+ temp[0] = t1 + s * w1;
+ temp[1] = t2 + t * w1;
+ cc_intersections.add(temp);
+ return;
+ }
+
+ CubicCurve2D.Double c11 = new CubicCurve2D.Double();
+ CubicCurve2D.Double c12 = new CubicCurve2D.Double();
+ CubicCurve2D.Double c21 = new CubicCurve2D.Double();
+ CubicCurve2D.Double c22 = new CubicCurve2D.Double();
+
+ if (! flat1 && ! flat2)
+ {
+ depth1--;
+ depth2--;
+ w1 = w1 * 0.5;
+ w2 = w2 * 0.5;
+ c1.subdivide(c11, c12);
+ c2.subdivide(c21, c22);
+ if (c11.getBounds2D().intersects(c21.getBounds2D()))
+ recursiveSubdivide(c11, c21, depth1, depth2, t1, t2, w1, w2);
+ if (c11.getBounds2D().intersects(c22.getBounds2D()))
+ recursiveSubdivide(c11, c22, depth1, depth2, t1, t2 + w2, w1, w2);
+ if (c12.getBounds2D().intersects(c21.getBounds2D()))
+ recursiveSubdivide(c12, c21, depth1, depth2, t1 + w1, t2, w1, w2);
+ if (c12.getBounds2D().intersects(c22.getBounds2D()))
+ recursiveSubdivide(c12, c22, depth1, depth2, t1 + w1, t2 + w2, w1, w2);
+ return;
+ }
+
+ if (! flat1)
+ {
+ depth1--;
+ c1.subdivide(c11, c12);
+ w1 = w1 * 0.5;
+ if (c11.getBounds2D().intersects(c2.getBounds2D()))
+ recursiveSubdivide(c11, c2, depth1, depth2, t1, t2, w1, w2);
+ if (c12.getBounds2D().intersects(c2.getBounds2D()))
+ recursiveSubdivide(c12, c2, depth1, depth2, t1 + w1, t2, w1, w2);
+ return;
+ }
+
+ depth2--;
+ c2.subdivide(c21, c22);
+ w2 = w2 * 0.5;
+ if (c1.getBounds2D().intersects(c21.getBounds2D()))
+ recursiveSubdivide(c1, c21, depth1, depth2, t1, t2, w1, w2);
+ if (c1.getBounds2D().intersects(c22.getBounds2D()))
+ recursiveSubdivide(c1, c22, depth1, depth2, t1, t2 + w2, w1, w2);
+ }
+
+ /**
+ * Returns a set of interesections between two Cubic segments
+ * Or null if no intersections were found.
+ *
+ * The method used to find the intersection is recursive midpoint
+ * subdivision. Outline description:
+ *
+ * 1) Check if the bounding boxes of the curves intersect,
+ * 2) If so, divide the curves in the middle and test the bounding
+ * boxes again,
+ * 3) Repeat until a maximum recursion depth has been reached, where
+ * the intersecting curves can be approximated by line segments.
+ *
+ * This is a reasonably accurate method, although the recursion depth
+ * is typically around 20, the bounding-box tests allow for significant
+ * pruning of the subdivision tree.
+ *
+ * This is package-private to avoid an accessor method.
+ */
+ Intersection[] cubicCubicIntersect(CubicSegment curve1, CubicSegment curve2)
+ {
+ Rectangle2D r1 = curve1.getBounds();
+ Rectangle2D r2 = curve2.getBounds();
+
+ if (! r1.intersects(r2))
+ return null;
+
+ cc_intersections = new Vector();
+ recursiveSubdivide(curve1.getCubicCurve2D(), curve2.getCubicCurve2D(),
+ getRecursionDepth(curve1), getRecursionDepth(curve2),
+ 0.0, 0.0, 1.0, 1.0);
+
+ if (cc_intersections.size() == 0)
+ return null;
+
+ Intersection[] results = new Intersection[cc_intersections.size()];
+ for (int i = 0; i < cc_intersections.size(); i++)
+ {
+ double[] temp = (double[]) cc_intersections.elementAt(i);
+ results[i] = new Intersection(curve1.evaluatePoint(temp[0]), temp[0],
+ temp[1]);
+ }
+ cc_intersections = null;
+ return (results);
+ }
+
+ /**
+ * Returns the intersections between a line and a quadratic bezier
+ * Or null if no intersections are found1
+ * This is done through combining the line's equation with the
+ * parametric form of the Bezier and solving the resulting quadratic.
+ * This is package-private to avoid an accessor method.
+ */
+ Intersection[] lineQuadIntersect(LineSegment l, QuadSegment c)
+ {
+ double[] y = new double[3];
+ double[] x = new double[3];
+ double[] r = new double[3];
+ int nRoots;
+ double x0 = c.P1.getX();
+ double y0 = c.P1.getY();
+ double x1 = c.cp.getX();
+ double y1 = c.cp.getY();
+ double x2 = c.P2.getX();
+ double y2 = c.P2.getY();
+
+ double lx0 = l.P1.getX();
+ double ly0 = l.P1.getY();
+ double lx1 = l.P2.getX();
+ double ly1 = l.P2.getY();
+ double dx = lx1 - lx0;
+ double dy = ly1 - ly0;
+
+ // form r(t) = y(t) - x(t) for the bezier
+ y[0] = y0;
+ y[1] = 2 * (y1 - y0);
+ y[2] = (y2 - 2 * y1 + y0);
+
+ x[0] = x0;
+ x[1] = 2 * (x1 - x0);
+ x[2] = (x2 - 2 * x1 + x0);
+
+ // a point, not a line
+ if (dy == 0 && dx == 0)
+ return null;
+
+ // line on y axis
+ if (dx == 0 || (dy / dx) > 1.0)
+ {
+ double k = dx / dy;
+ x[0] -= lx0;
+ y[0] -= ly0;
+ y[0] *= k;
+ y[1] *= k;
+ y[2] *= k;
+ }
+ else
+ {
+ double k = dy / dx;
+ x[0] -= lx0;
+ y[0] -= ly0;
+ x[0] *= k;
+ x[1] *= k;
+ x[2] *= k;
+ }
+
+ for (int i = 0; i < 3; i++)
+ r[i] = y[i] - x[i];
+
+ if ((nRoots = QuadCurve2D.solveQuadratic(r)) > 0)
+ {
+ Intersection[] temp = new Intersection[nRoots];
+ int intersections = 0;
+ for (int i = 0; i < nRoots; i++)
+ {
+ double t = r[i];
+ if (t >= 0.0 && t <= 1.0)
+ {
+ Point2D p = c.evaluatePoint(t);
+
+ // if the line is on an axis, snap the point to that axis.
+ if (dx == 0)
+ p.setLocation(lx0, p.getY());
+ if (dy == 0)
+ p.setLocation(p.getX(), ly0);
+
+ if (p.getX() <= Math.max(lx0, lx1)
+ && p.getX() >= Math.min(lx0, lx1)
+ && p.getY() <= Math.max(ly0, ly1)
+ && p.getY() >= Math.min(ly0, ly1))
+ {
+ double lineparameter = p.distance(l.P1) / l.P2.distance(l.P1);
+ temp[i] = new Intersection(p, lineparameter, t);
+ intersections++;
+ }
+ }
+ else
+ temp[i] = null;
+ }
+ if (intersections == 0)
+ return null;
+
+ Intersection[] rValues = new Intersection[intersections];
+
+ for (int i = 0; i < nRoots; i++)
+ if (temp[i] != null)
+ rValues[--intersections] = temp[i];
+ return (rValues);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the intersections between a line and a cubic segment
+ * This is done through combining the line's equation with the
+ * parametric form of the Bezier and solving the resulting quadratic.
+ * This is package-private to avoid an accessor method.
+ */
+ Intersection[] lineCubicIntersect(LineSegment l, CubicSegment c)
+ {
+ double[] y = new double[4];
+ double[] x = new double[4];
+ double[] r = new double[4];
+ int nRoots;
+ double x0 = c.P1.getX();
+ double y0 = c.P1.getY();
+ double x1 = c.cp1.getX();
+ double y1 = c.cp1.getY();
+ double x2 = c.cp2.getX();
+ double y2 = c.cp2.getY();
+ double x3 = c.P2.getX();
+ double y3 = c.P2.getY();
+
+ double lx0 = l.P1.getX();
+ double ly0 = l.P1.getY();
+ double lx1 = l.P2.getX();
+ double ly1 = l.P2.getY();
+ double dx = lx1 - lx0;
+ double dy = ly1 - ly0;
+
+ // form r(t) = y(t) - x(t) for the bezier
+ y[0] = y0;
+ y[1] = 3 * (y1 - y0);
+ y[2] = 3 * (y2 + y0 - 2 * y1);
+ y[3] = y3 - 3 * y2 + 3 * y1 - y0;
+
+ x[0] = x0;
+ x[1] = 3 * (x1 - x0);
+ x[2] = 3 * (x2 + x0 - 2 * x1);
+ x[3] = x3 - 3 * x2 + 3 * x1 - x0;
+
+ // a point, not a line
+ if (dy == 0 && dx == 0)
+ return null;
+
+ // line on y axis
+ if (dx == 0 || (dy / dx) > 1.0)
+ {
+ double k = dx / dy;
+ x[0] -= lx0;
+ y[0] -= ly0;
+ y[0] *= k;
+ y[1] *= k;
+ y[2] *= k;
+ y[3] *= k;
+ }
+ else
+ {
+ double k = dy / dx;
+ x[0] -= lx0;
+ y[0] -= ly0;
+ x[0] *= k;
+ x[1] *= k;
+ x[2] *= k;
+ x[3] *= k;
+ }
+ for (int i = 0; i < 4; i++)
+ r[i] = y[i] - x[i];
+
+ if ((nRoots = CubicCurve2D.solveCubic(r)) > 0)
+ {
+ Intersection[] temp = new Intersection[nRoots];
+ int intersections = 0;
+ for (int i = 0; i < nRoots; i++)
+ {
+ double t = r[i];
+ if (t >= 0.0 && t <= 1.0)
+ {
+ // if the line is on an axis, snap the point to that axis.
+ Point2D p = c.evaluatePoint(t);
+ if (dx == 0)
+ p.setLocation(lx0, p.getY());
+ if (dy == 0)
+ p.setLocation(p.getX(), ly0);
+
+ if (p.getX() <= Math.max(lx0, lx1)
+ && p.getX() >= Math.min(lx0, lx1)
+ && p.getY() <= Math.max(ly0, ly1)
+ && p.getY() >= Math.min(ly0, ly1))
+ {
+ double lineparameter = p.distance(l.P1) / l.P2.distance(l.P1);
+ temp[i] = new Intersection(p, lineparameter, t);
+ intersections++;
+ }
+ }
+ else
+ temp[i] = null;
+ }
+
+ if (intersections == 0)
+ return null;
+
+ Intersection[] rValues = new Intersection[intersections];
+ for (int i = 0; i < nRoots; i++)
+ if (temp[i] != null)
+ rValues[--intersections] = temp[i];
+ return (rValues);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the intersection between two lines, or null if there is no
+ * intersection.
+ * This is package-private to avoid an accessor method.
+ */
+ Intersection linesIntersect(LineSegment a, LineSegment b)
+ {
+ Point2D P1 = a.P1;
+ Point2D P2 = a.P2;
+ Point2D P3 = b.P1;
+ Point2D P4 = b.P2;
+
+ if (! Line2D.linesIntersect(P1.getX(), P1.getY(), P2.getX(), P2.getY(),
+ P3.getX(), P3.getY(), P4.getX(), P4.getY()))
+ return null;
+
+ double x1 = P1.getX();
+ double y1 = P1.getY();
+ double rx = P2.getX() - x1;
+ double ry = P2.getY() - y1;
+
+ double x2 = P3.getX();
+ double y2 = P3.getY();
+ double sx = P4.getX() - x2;
+ double sy = P4.getY() - y2;
+
+ double determinant = sx * ry - sy * rx;
+ double nom = (sx * (y2 - y1) + sy * (x1 - x2));
+
+ // Parallel lines don't intersect. At least we pretend they don't.
+ if (Math.abs(determinant) < EPSILON)
+ return null;
+
+ nom = nom / determinant;
+
+ if (nom == 0.0)
+ return null;
+ if (nom == 1.0)
+ return null;
+
+ Point2D p = new Point2D.Double(x1 + nom * rx, y1 + nom * ry);
+
+ return new Intersection(p, p.distance(P1) / P1.distance(P2),
+ p.distance(P3) / P3.distance(P4));
+ }
+
+ /**
+ * Determines if two points are equal, within an error margin
+ * 'snap distance'
+ * This is package-private to avoid an accessor method.
+ */
+ boolean pointEquals(Point2D a, Point2D b)
+ {
+ return (a.equals(b) || a.distance(b) < PE_EPSILON);
+ }
+
+ /**
+ * Helper method
+ * Turns a shape into a Vector of Segments
+ */
+ private Vector makeSegment(Shape s)
+ {
+ Vector paths = new Vector();
+ PathIterator pi = s.getPathIterator(null);
+ double[] coords = new double[6];
+ Segment subpath = null;
+ Segment current = null;
+ double cx;
+ double cy;
+ double subpathx;
+ double subpathy;
+ cx = cy = subpathx = subpathy = 0.0;
+
+ this.windingRule = pi.getWindingRule();
+
+ while (! pi.isDone())
+ {
+ Segment v;
+ switch (pi.currentSegment(coords))
+ {
+ case PathIterator.SEG_MOVETO:
+ if (subpath != null)
+ { // close existing open path
+ current.next = new LineSegment(cx, cy, subpathx, subpathy);
+ current = current.next;
+ current.next = subpath;
+ }
+ subpath = null;
+ subpathx = cx = coords[0];
+ subpathy = cy = coords[1];
+ break;
+
+ // replace 'close' with a line-to.
+ case PathIterator.SEG_CLOSE:
+ if (subpath != null && (subpathx != cx || subpathy != cy))
+ {
+ current.next = new LineSegment(cx, cy, subpathx, subpathy);
+ current = current.next;
+ current.next = subpath;
+ cx = subpathx;
+ cy = subpathy;
+ subpath = null;
+ }
+ else if (subpath != null)
+ {
+ current.next = subpath;
+ subpath = null;
+ }
+ break;
+ case PathIterator.SEG_LINETO:
+ if (cx != coords[0] || cy != coords[1])
+ {
+ v = new LineSegment(cx, cy, coords[0], coords[1]);
+ if (subpath == null)
+ {
+ subpath = current = v;
+ paths.add(subpath);
+ }
+ else
+ {
+ current.next = v;
+ current = current.next;
+ }
+ cx = coords[0];
+ cy = coords[1];
+ }
+ break;
+ case PathIterator.SEG_QUADTO:
+ v = new QuadSegment(cx, cy, coords[0], coords[1], coords[2],
+ coords[3]);
+ if (subpath == null)
+ {
+ subpath = current = v;
+ paths.add(subpath);
+ }
+ else
+ {
+ current.next = v;
+ current = current.next;
+ }
+ cx = coords[2];
+ cy = coords[3];
+ break;
+ case PathIterator.SEG_CUBICTO:
+ v = new CubicSegment(cx, cy, coords[0], coords[1], coords[2],
+ coords[3], coords[4], coords[5]);
+ if (subpath == null)
+ {
+ subpath = current = v;
+ paths.add(subpath);
+ }
+ else
+ {
+ current.next = v;
+ current = current.next;
+ }
+
+ // check if the cubic is self-intersecting
+ double[] lpts = ((CubicSegment) v).getLoop();
+ if (lpts != null)
+ {
+ // if it is, break off the loop into its own path.
+ v.subdivideInsert(lpts[0]);
+ v.next.subdivideInsert((lpts[1] - lpts[0]) / (1.0 - lpts[0]));
+
+ CubicSegment loop = (CubicSegment) v.next;
+ v.next = loop.next;
+ loop.next = loop;
+
+ v.P2 = v.next.P1 = loop.P2 = loop.P1; // snap points
+ paths.add(loop);
+ current = v.next;
+ }
+
+ cx = coords[4];
+ cy = coords[5];
+ break;
+ }
+ pi.next();
+ }
+
+ if (subpath != null)
+ { // close any open path
+ if (subpathx != cx || subpathy != cy)
+ {
+ current.next = new LineSegment(cx, cy, subpathx, subpathy);
+ current = current.next;
+ current.next = subpath;
+ }
+ else
+ current.next = subpath;
+ }
+
+ if (paths.size() == 0)
+ return (null);
+
+ return (paths);
+ }
+
+ /**
+ * Find the intersections of two separate closed paths,
+ * A and B, split the segments at the intersection points,
+ * and create nodes pointing from one to the other
+ */
+ private int createNodes(Segment A, Segment B)
+ {
+ int nNodes = 0;
+
+ Segment a = A;
+ Segment b = B;
+
+ do
+ {
+ do
+ {
+ nNodes += a.splitIntersections(b);
+ b = b.next;
+ }
+ while (b != B);
+
+ a = a.next; // move to the next segment
+ }
+ while (a != A); // until one wrap.
+
+ return (nNodes);
+ }
+
+ /**
+ * Find the intersections of a path with itself.
+ * Splits the segments at the intersection points,
+ * and create nodes pointing from one to the other.
+ */
+ private int createNodesSelf(Segment A)
+ {
+ int nNodes = 0;
+ Segment a = A;
+
+ if (A.next == A)
+ return 0;
+
+ do
+ {
+ Segment b = a.next;
+ do
+ {
+ if (b != a) // necessary
+ nNodes += a.splitIntersections(b);
+ b = b.next;
+ }
+ while (b != A);
+ a = a.next; // move to the next segment
+ }
+ while (a != A); // until one wrap.
+
+ return (nNodes);
+ }
+
+ /**
+ * Deletes paths which are redundant from a list, (i.e. solid areas within
+ * solid areas) Clears any nodes. Sorts the remaining paths into solids
+ * and holes, sets their orientation and sets the solids and holes lists.
+ */
+ private void deleteRedundantPaths(Vector paths)
+ {
+ int npaths = paths.size();
+
+ int[][] contains = new int[npaths][npaths];
+ int[][] windingNumbers = new int[npaths][2];
+ int neg;
+ Rectangle2D[] bb = new Rectangle2D[npaths]; // path bounding boxes
+
+ neg = ((windingRule == PathIterator.WIND_NON_ZERO) ? -1 : 1);
+
+ for (int i = 0; i < npaths; i++)
+ bb[i] = ((Segment) paths.elementAt(i)).getPathBounds();
+
+ // Find which path contains which, assign winding numbers
+ for (int i = 0; i < npaths; i++)
+ {
+ Segment pathA = (Segment) paths.elementAt(i);
+ pathA.nullNodes(); // remove any now-redundant nodes, in case.
+ int windingA = pathA.hasClockwiseOrientation() ? 1 : neg;
+
+ for (int j = 0; j < npaths; j++)
+ if (i != j)
+ {
+ Segment pathB = (Segment) paths.elementAt(j);
+
+ // A contains B
+ if (bb[i].intersects(bb[j]))
+ {
+ Segment s = pathB.next;
+ while (s.P1.getY() == s.P2.getY() && s != pathB)
+ s = s.next;
+ Point2D p = s.getMidPoint();
+ if (pathA.contains(p.getX(), p.getY()))
+ contains[i][j] = windingA;
+ }
+ else
+ // A does not contain B
+ contains[i][j] = 0;
+ }
+ else
+ contains[i][j] = windingA; // i == j
+ }
+
+ for (int i = 0; i < npaths; i++)
+ {
+ windingNumbers[i][0] = 0;
+ for (int j = 0; j < npaths; j++)
+ windingNumbers[i][0] += contains[j][i];
+ windingNumbers[i][1] = contains[i][i];
+ }
+
+ Vector solids = new Vector();
+ Vector holes = new Vector();
+
+ if (windingRule == PathIterator.WIND_NON_ZERO)
+ {
+ for (int i = 0; i < npaths; i++)
+ {
+ if (windingNumbers[i][0] == 0)
+ holes.add(paths.elementAt(i));
+ else if (windingNumbers[i][0] - windingNumbers[i][1] == 0
+ && Math.abs(windingNumbers[i][0]) == 1)
+ solids.add(paths.elementAt(i));
+ }
+ }
+ else
+ {
+ windingRule = PathIterator.WIND_NON_ZERO;
+ for (int i = 0; i < npaths; i++)
+ {
+ if ((windingNumbers[i][0] & 1) == 0)
+ holes.add(paths.elementAt(i));
+ else if ((windingNumbers[i][0] & 1) == 1)
+ solids.add(paths.elementAt(i));
+ }
+ }
+
+ setDirection(holes, false);
+ setDirection(solids, true);
+ this.holes = holes;
+ this.solids = solids;
+ }
+
+ /**
+ * Sets the winding direction of a Vector of paths
+ * @param clockwise gives the direction,
+ * true = clockwise, false = counter-clockwise
+ */
+ private void setDirection(Vector paths, boolean clockwise)
+ {
+ Segment v;
+ for (int i = 0; i < paths.size(); i++)
+ {
+ v = (Segment) paths.elementAt(i);
+ if (clockwise != v.hasClockwiseOrientation())
+ v.reverseAll();
+ }
+ }
+
+ /**
+ * Class representing a linked-list of vertices forming a closed polygon,
+ * convex or concave, without holes.
+ */
+ private abstract class Segment implements Cloneable
+ {
+ // segment type, PathIterator segment types are used.
+ Point2D P1;
+ Point2D P2;
+ Segment next;
+ Segment node;
+
+ Segment()
+ {
+ P1 = P2 = null;
+ node = next = null;
+ }
+
+ /**
+ * Reverses the direction of a single segment
+ */
+ abstract void reverseCoords();
+
+ /**
+ * Returns the segment's midpoint
+ */
+ abstract Point2D getMidPoint();
+
+ /**
+ * Returns the bounding box of this segment
+ */
+ abstract Rectangle2D getBounds();
+
+ /**
+ * Transforms a single segment
+ */
+ abstract void transform(AffineTransform at);
+
+ /**
+ * Returns the PathIterator type of a segment
+ */
+ abstract int getType();
+
+ /**
+ */
+ abstract int splitIntersections(Segment b);
+
+ /**
+ * Returns the PathIterator coords of a segment
+ */
+ abstract int pathIteratorFormat(double[] coords);
+
+ /**
+ * Returns the number of intersections on the positive X axis,
+ * with the origin at (x,y), used for contains()-testing
+ *
+ * (Although that could be done by the line-intersect methods,
+ * a dedicated method is better to guarantee consitent handling
+ * of endpoint-special-cases)
+ */
+ abstract int rayCrossing(double x, double y);
+
+ /**
+ * Subdivides the segment at parametric value t, inserting
+ * the new segment into the linked list after this,
+ * such that this becomes [0,t] and this.next becomes [t,1]
+ */
+ abstract void subdivideInsert(double t);
+
+ /**
+ * Returns twice the area of a curve, relative the P1-P2 line
+ * Used for area calculations.
+ */
+ abstract double curveArea();
+
+ /**
+ * Compare two segments.
+ */
+ abstract boolean equals(Segment b);
+
+ /**
+ * Determines if this path of segments contains the point (x,y)
+ */
+ boolean contains(double x, double y)
+ {
+ Segment v = this;
+ int crossings = 0;
+ do
+ {
+ int n = v.rayCrossing(x, y);
+ crossings += n;
+ v = v.next;
+ }
+ while (v != this);
+ return ((crossings & 1) == 1);
+ }
+
+ /**
+ * Nulls all nodes of the path. Clean up any 'hairs'.
+ */
+ void nullNodes()
+ {
+ Segment v = this;
+ do
+ {
+ v.node = null;
+ v = v.next;
+ }
+ while (v != this);
+ }
+
+ /**
+ * Transforms each segment in the closed path
+ */
+ void transformSegmentList(AffineTransform at)
+ {
+ Segment v = this;
+ do
+ {
+ v.transform(at);
+ v = v.next;
+ }
+ while (v != this);
+ }
+
+ /**
+ * Determines the winding direction of the path
+ * By the sign of the area.
+ */
+ boolean hasClockwiseOrientation()
+ {
+ return (getSignedArea() > 0.0);
+ }
+
+ /**
+ * Returns the bounds of this path
+ */
+ public Rectangle2D getPathBounds()
+ {
+ double xmin;
+ double xmax;
+ double ymin;
+ double ymax;
+ xmin = xmax = P1.getX();
+ ymin = ymax = P1.getY();
+
+ Segment v = this;
+ do
+ {
+ Rectangle2D r = v.getBounds();
+ xmin = Math.min(r.getMinX(), xmin);
+ ymin = Math.min(r.getMinY(), ymin);
+ xmax = Math.max(r.getMaxX(), xmax);
+ ymax = Math.max(r.getMaxY(), ymax);
+ v = v.next;
+ }
+ while (v != this);
+
+ return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
+ }
+
+ /**
+ * Calculates twice the signed area of the path;
+ */
+ double getSignedArea()
+ {
+ Segment s;
+ double area = 0.0;
+
+ s = this;
+ do
+ {
+ area += s.curveArea();
+
+ area += s.P1.getX() * s.next.P1.getY()
+ - s.P1.getY() * s.next.P1.getX();
+ s = s.next;
+ }
+ while (s != this);
+
+ return area;
+ }
+
+ /**
+ * Reverses the orientation of the whole polygon
+ */
+ void reverseAll()
+ {
+ reverseCoords();
+ Segment v = next;
+ Segment former = this;
+ while (v != this)
+ {
+ v.reverseCoords();
+ Segment vnext = v.next;
+ v.next = former;
+ former = v;
+ v = vnext;
+ }
+ next = former;
+ }
+
+ /**
+ * Inserts a Segment after this one
+ */
+ void insert(Segment v)
+ {
+ Segment n = next;
+ next = v;
+ v.next = n;
+ }
+
+ /**
+ * Returns if this segment path is polygonal
+ */
+ boolean isPolygonal()
+ {
+ Segment v = this;
+ do
+ {
+ if (! (v instanceof LineSegment))
+ return false;
+ v = v.next;
+ }
+ while (v != this);
+ return true;
+ }
+
+ /**
+ * Clones this path
+ */
+ Segment cloneSegmentList() throws CloneNotSupportedException
+ {
+ Vector list = new Vector();
+ Segment v = next;
+
+ while (v != this)
+ {
+ list.add(v);
+ v = v.next;
+ }
+
+ Segment clone = (Segment) this.clone();
+ v = clone;
+ for (int i = 0; i < list.size(); i++)
+ {
+ clone.next = (Segment) ((Segment) list.elementAt(i)).clone();
+ clone = clone.next;
+ }
+ clone.next = v;
+ return v;
+ }
+
+ /**
+ * Creates a node between this segment and segment b
+ * at the given intersection
+ * @return the number of nodes created (0 or 1)
+ */
+ int createNode(Segment b, Intersection i)
+ {
+ Point2D p = i.p;
+ if ((pointEquals(P1, p) || pointEquals(P2, p))
+ && (pointEquals(b.P1, p) || pointEquals(b.P2, p)))
+ return 0;
+
+ subdivideInsert(i.ta);
+ b.subdivideInsert(i.tb);
+
+ // snap points
+ b.P2 = b.next.P1 = P2 = next.P1 = i.p;
+
+ node = b.next;
+ b.node = next;
+ return 1;
+ }
+
+ /**
+ * Creates multiple nodes from a list of intersections,
+ * This must be done in the order of ascending parameters,
+ * and the parameters must be recalculated in accordance
+ * with each split.
+ * @return the number of nodes created
+ */
+ protected int createNodes(Segment b, Intersection[] x)
+ {
+ Vector v = new Vector();
+ for (int i = 0; i < x.length; i++)
+ {
+ Point2D p = x[i].p;
+ if (! ((pointEquals(P1, p) || pointEquals(P2, p))
+ && (pointEquals(b.P1, p) || pointEquals(b.P2, p))))
+ v.add(x[i]);
+ }
+
+ int nNodes = v.size();
+ Intersection[] A = new Intersection[nNodes];
+ Intersection[] B = new Intersection[nNodes];
+ for (int i = 0; i < nNodes; i++)
+ A[i] = B[i] = (Intersection) v.elementAt(i);
+
+ // Create two lists sorted by the parameter
+ // Bubble sort, OK I suppose, since the number of intersections
+ // cannot be larger than 9 (cubic-cubic worst case) anyway
+ for (int i = 0; i < nNodes - 1; i++)
+ {
+ for (int j = i + 1; j < nNodes; j++)
+ {
+ if (A[i].ta > A[j].ta)
+ {
+ Intersection swap = A[i];
+ A[i] = A[j];
+ A[j] = swap;
+ }
+ if (B[i].tb > B[j].tb)
+ {
+ Intersection swap = B[i];
+ B[i] = B[j];
+ B[j] = swap;
+ }
+ }
+ }
+ // subdivide a
+ Segment s = this;
+ for (int i = 0; i < nNodes; i++)
+ {
+ s.subdivideInsert(A[i].ta);
+
+ // renormalize the parameters
+ for (int j = i + 1; j < nNodes; j++)
+ A[j].ta = (A[j].ta - A[i].ta) / (1.0 - A[i].ta);
+
+ A[i].seg = s;
+ s = s.next;
+ }
+
+ // subdivide b, set nodes
+ s = b;
+ for (int i = 0; i < nNodes; i++)
+ {
+ s.subdivideInsert(B[i].tb);
+
+ for (int j = i + 1; j < nNodes; j++)
+ B[j].tb = (B[j].tb - B[i].tb) / (1.0 - B[i].tb);
+
+ // set nodes
+ B[i].seg.node = s.next; // node a -> b
+ s.node = B[i].seg.next; // node b -> a
+
+ // snap points
+ B[i].seg.P2 = B[i].seg.next.P1 = s.P2 = s.next.P1 = B[i].p;
+ s = s.next;
+ }
+ return nNodes;
+ }
+
+ /**
+ * Determines if two paths are equal.
+ * Colinear line segments are ignored in the comparison.
+ */
+ boolean pathEquals(Segment B)
+ {
+ if (! getPathBounds().equals(B.getPathBounds()))
+ return false;
+
+ Segment startA = getTopLeft();
+ Segment startB = B.getTopLeft();
+ Segment a = startA;
+ Segment b = startB;
+ do
+ {
+ if (! a.equals(b))
+ return false;
+
+ if (a instanceof LineSegment)
+ a = ((LineSegment) a).lastCoLinear();
+ if (b instanceof LineSegment)
+ b = ((LineSegment) b).lastCoLinear();
+
+ a = a.next;
+ b = b.next;
+ }
+ while (a != startA && b != startB);
+ return true;
+ }
+
+ /**
+ * Return the segment with the top-leftmost first point
+ */
+ Segment getTopLeft()
+ {
+ Segment v = this;
+ Segment tl = this;
+ do
+ {
+ if (v.P1.getY() < tl.P1.getY())
+ tl = v;
+ else if (v.P1.getY() == tl.P1.getY())
+ {
+ if (v.P1.getX() < tl.P1.getX())
+ tl = v;
+ }
+ v = v.next;
+ }
+ while (v != this);
+ return tl;
+ }
+
+ /**
+ * Returns if the path has a segment outside a shape
+ */
+ boolean isSegmentOutside(Shape shape)
+ {
+ return ! shape.contains(getMidPoint());
+ }
+ } // class Segment
+
+ private class LineSegment extends Segment
+ {
+ public LineSegment(double x1, double y1, double x2, double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ }
+
+ public LineSegment(Point2D p1, Point2D p2)
+ {
+ super();
+ P1 = (Point2D) p1.clone();
+ P2 = (Point2D) p2.clone();
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new LineSegment(P1, P2);
+ }
+
+ /**
+ * Transforms the segment
+ */
+ void transform(AffineTransform at)
+ {
+ P1 = at.transform(P1, null);
+ P2 = at.transform(P2, null);
+ }
+
+ /**
+ * Swap start and end points
+ */
+ void reverseCoords()
+ {
+ Point2D p = P1;
+ P1 = P2;
+ P2 = p;
+ }
+
+ /**
+ * Returns the segment's midpoint
+ */
+ Point2D getMidPoint()
+ {
+ return (new Point2D.Double(0.5 * (P1.getX() + P2.getX()),
+ 0.5 * (P1.getY() + P2.getY())));
+ }
+
+ /**
+ * Returns twice the area of a curve, relative the P1-P2 line
+ * Obviously, a line does not enclose any area besides the line
+ */
+ double curveArea()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the PathIterator type of a segment
+ */
+ int getType()
+ {
+ return (PathIterator.SEG_LINETO);
+ }
+
+ /**
+ * Subdivides the segment at parametric value t, inserting
+ * the new segment into the linked list after this,
+ * such that this becomes [0,t] and this.next becomes [t,1]
+ */
+ void subdivideInsert(double t)
+ {
+ Point2D p = new Point2D.Double((P2.getX() - P1.getX()) * t + P1.getX(),
+ (P2.getY() - P1.getY()) * t + P1.getY());
+ insert(new LineSegment(p, P2));
+ P2 = p;
+ next.node = node;
+ node = null;
+ }
+
+ /**
+ * Determines if two line segments are strictly colinear
+ */
+ boolean isCoLinear(LineSegment b)
+ {
+ double x1 = P1.getX();
+ double y1 = P1.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+ double x3 = b.P1.getX();
+ double y3 = b.P1.getY();
+ double x4 = b.P2.getX();
+ double y4 = b.P2.getY();
+
+ if ((y1 - y3) * (x4 - x3) - (x1 - x3) * (y4 - y3) != 0.0)
+ return false;
+
+ return ((x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3) == 0.0);
+ }
+
+ /**
+ * Return the last segment colinear with this one.
+ * Used in comparing paths.
+ */
+ Segment lastCoLinear()
+ {
+ Segment prev = this;
+ Segment v = next;
+
+ while (v instanceof LineSegment)
+ {
+ if (isCoLinear((LineSegment) v))
+ {
+ prev = v;
+ v = v.next;
+ }
+ else
+ return prev;
+ }
+ return prev;
+ }
+
+ /**
+ * Compare two segments.
+ * We must take into account that the lines may be broken into colinear
+ * subsegments and ignore them.
+ */
+ boolean equals(Segment b)
+ {
+ if (! (b instanceof LineSegment))
+ return false;
+ Point2D p1 = P1;
+ Point2D p3 = b.P1;
+
+ if (! p1.equals(p3))
+ return false;
+
+ Point2D p2 = lastCoLinear().P2;
+ Point2D p4 = ((LineSegment) b).lastCoLinear().P2;
+ return (p2.equals(p4));
+ }
+
+ /**
+ * Returns a line segment
+ */
+ int pathIteratorFormat(double[] coords)
+ {
+ coords[0] = P2.getX();
+ coords[1] = P2.getY();
+ return (PathIterator.SEG_LINETO);
+ }
+
+ /**
+ * Returns if the line has intersections.
+ */
+ boolean hasIntersections(Segment b)
+ {
+ if (b instanceof LineSegment)
+ return (linesIntersect(this, (LineSegment) b) != null);
+
+ if (b instanceof QuadSegment)
+ return (lineQuadIntersect(this, (QuadSegment) b) != null);
+
+ if (b instanceof CubicSegment)
+ return (lineCubicIntersect(this, (CubicSegment) b) != null);
+
+ return false;
+ }
+
+ /**
+ * Splits intersections into nodes,
+ * This one handles line-line, line-quadratic, line-cubic
+ */
+ int splitIntersections(Segment b)
+ {
+ if (b instanceof LineSegment)
+ {
+ Intersection i = linesIntersect(this, (LineSegment) b);
+
+ if (i == null)
+ return 0;
+
+ return createNode(b, i);
+ }
+
+ Intersection[] x = null;
+
+ if (b instanceof QuadSegment)
+ x = lineQuadIntersect(this, (QuadSegment) b);
+
+ if (b instanceof CubicSegment)
+ x = lineCubicIntersect(this, (CubicSegment) b);
+
+ if (x == null)
+ return 0;
+
+ if (x.length == 1)
+ return createNode(b, (Intersection) x[0]);
+
+ return createNodes(b, x);
+ }
+
+ /**
+ * Returns the bounding box of this segment
+ */
+ Rectangle2D getBounds()
+ {
+ return (new Rectangle2D.Double(Math.min(P1.getX(), P2.getX()),
+ Math.min(P1.getY(), P2.getY()),
+ Math.abs(P1.getX() - P2.getX()),
+ Math.abs(P1.getY() - P2.getY())));
+ }
+
+ /**
+ * Returns the number of intersections on the positive X axis,
+ * with the origin at (x,y), used for contains()-testing
+ */
+ int rayCrossing(double x, double y)
+ {
+ double x0 = P1.getX() - x;
+ double y0 = P1.getY() - y;
+ double x1 = P2.getX() - x;
+ double y1 = P2.getY() - y;
+
+ if (y0 * y1 > 0)
+ return 0;
+
+ if (x0 < 0 && x1 < 0)
+ return 0;
+
+ if (y0 == 0.0)
+ y0 -= EPSILON;
+
+ if (y1 == 0.0)
+ y1 -= EPSILON;
+
+ if (Line2D.linesIntersect(x0, y0, x1, y1,
+ EPSILON, 0.0, Double.MAX_VALUE, 0.0))
+ return 1;
+ return 0;
+ }
+ } // class LineSegment
+
+ /**
+ * Quadratic Bezier curve segment
+ *
+ * Note: Most peers don't support quadratics directly, so it might make
+ * sense to represent them as cubics internally and just be done with it.
+ * I think we should be peer-agnostic, however, and stay faithful to the
+ * input geometry types as far as possible.
+ */
+ private class QuadSegment extends Segment
+ {
+ Point2D cp; // control point
+
+ /**
+ * Constructor, takes the coordinates of the start, control,
+ * and end point, respectively.
+ */
+ QuadSegment(double x1, double y1, double cx, double cy, double x2,
+ double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ cp = new Point2D.Double(cx, cy);
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new QuadSegment(P1.getX(), P1.getY(), cp.getX(), cp.getY(),
+ P2.getX(), P2.getY());
+ }
+
+ /**
+ * Returns twice the area of a curve, relative the P1-P2 line
+ *
+ * The area formula can be derived by using Green's formula in the
+ * plane on the parametric form of the bezier.
+ */
+ double curveArea()
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+
+ double P = (y2 - 2 * y1 + y0);
+ double Q = 2 * (y1 - y0);
+
+ double A = (x2 - 2 * x1 + x0);
+ double B = 2 * (x1 - x0);
+
+ double area = (B * P - A * Q) / 3.0;
+ return (area);
+ }
+
+ /**
+ * Compare two segments.
+ */
+ boolean equals(Segment b)
+ {
+ if (! (b instanceof QuadSegment))
+ return false;
+
+ return (P1.equals(b.P1) && cp.equals(((QuadSegment) b).cp)
+ && P2.equals(b.P2));
+ }
+
+ /**
+ * Returns a Point2D corresponding to the parametric value t
+ * of the curve
+ */
+ Point2D evaluatePoint(double t)
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+
+ return new Point2D.Double(t * t * (x2 - 2 * x1 + x0) + 2 * t * (x1 - x0)
+ + x0,
+ t * t * (y2 - 2 * y1 + y0) + 2 * t * (y1 - y0)
+ + y0);
+ }
+
+ /**
+ * Returns the bounding box of this segment
+ */
+ Rectangle2D getBounds()
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+ double r0;
+ double r1;
+
+ double xmax = Math.max(x0, x2);
+ double ymax = Math.max(y0, y2);
+ double xmin = Math.min(x0, x2);
+ double ymin = Math.min(y0, y2);
+
+ r0 = 2 * (y1 - y0);
+ r1 = 2 * (y2 - 2 * y1 + y0);
+ if (r1 != 0.0)
+ {
+ double t = -r0 / r1;
+ if (t > 0.0 && t < 1.0)
+ {
+ double y = evaluatePoint(t).getY();
+ ymax = Math.max(y, ymax);
+ ymin = Math.min(y, ymin);
+ }
+ }
+ r0 = 2 * (x1 - x0);
+ r1 = 2 * (x2 - 2 * x1 + x0);
+ if (r1 != 0.0)
+ {
+ double t = -r0 / r1;
+ if (t > 0.0 && t < 1.0)
+ {
+ double x = evaluatePoint(t).getY();
+ xmax = Math.max(x, xmax);
+ xmin = Math.min(x, xmin);
+ }
+ }
+
+ return (new Rectangle2D.Double(xmin, ymin, xmax - xmin, ymax - ymin));
+ }
+
+ /**
+ * Returns a cubic segment corresponding to this curve
+ */
+ CubicSegment getCubicSegment()
+ {
+ double x1 = P1.getX() + 2.0 * (cp.getX() - P1.getX()) / 3.0;
+ double y1 = P1.getY() + 2.0 * (cp.getY() - P1.getY()) / 3.0;
+ double x2 = cp.getX() + (P2.getX() - cp.getX()) / 3.0;
+ double y2 = cp.getY() + (P2.getY() - cp.getY()) / 3.0;
+
+ return new CubicSegment(P1.getX(), P1.getY(), x1, y1, x2, y2, P2.getX(),
+ P2.getY());
+ }
+
+ /**
+ * Returns the segment's midpoint
+ */
+ Point2D getMidPoint()
+ {
+ return evaluatePoint(0.5);
+ }
+
+ /**
+ * Returns the PathIterator type of a segment
+ */
+ int getType()
+ {
+ return (PathIterator.SEG_QUADTO);
+ }
+
+ /**
+ * Returns the PathIterator coords of a segment
+ */
+ int pathIteratorFormat(double[] coords)
+ {
+ coords[0] = cp.getX();
+ coords[1] = cp.getY();
+ coords[2] = P2.getX();
+ coords[3] = P2.getY();
+ return (PathIterator.SEG_QUADTO);
+ }
+
+ /**
+ * Returns the number of intersections on the positive X axis,
+ * with the origin at (x,y), used for contains()-testing
+ */
+ int rayCrossing(double x, double y)
+ {
+ double x0 = P1.getX() - x;
+ double y0 = P1.getY() - y;
+ double x1 = cp.getX() - x;
+ double y1 = cp.getY() - y;
+ double x2 = P2.getX() - x;
+ double y2 = P2.getY() - y;
+ double[] r = new double[3];
+ int nRoots;
+ int nCrossings = 0;
+
+ /* check if curve may intersect X+ axis. */
+ if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0) && (y0 * y1 <= 0 || y1 * y2 <= 0))
+ {
+ if (y0 == 0.0)
+ y0 -= EPSILON;
+ if (y2 == 0.0)
+ y2 -= EPSILON;
+
+ r[0] = y0;
+ r[1] = 2 * (y1 - y0);
+ r[2] = (y2 - 2 * y1 + y0);
+
+ nRoots = QuadCurve2D.solveQuadratic(r);
+ for (int i = 0; i < nRoots; i++)
+ if (r[i] > 0.0f && r[i] < 1.0f)
+ {
+ double t = r[i];
+ if (t * t * (x2 - 2 * x1 + x0) + 2 * t * (x1 - x0) + x0 > 0.0)
+ nCrossings++;
+ }
+ }
+ return nCrossings;
+ }
+
+ /**
+ * Swap start and end points
+ */
+ void reverseCoords()
+ {
+ Point2D temp = P1;
+ P1 = P2;
+ P2 = temp;
+ }
+
+ /**
+ * Splits intersections into nodes,
+ * This one handles quadratic-quadratic only,
+ * Quadratic-line is passed on to the LineSegment class,
+ * Quadratic-cubic is passed on to the CubicSegment class
+ */
+ int splitIntersections(Segment b)
+ {
+ if (b instanceof LineSegment)
+ return (b.splitIntersections(this));
+
+ if (b instanceof CubicSegment)
+ return (b.splitIntersections(this));
+
+ if (b instanceof QuadSegment)
+ {
+ // Use the cubic-cubic intersection routine for quads as well,
+ // Since a quadratic can be exactly described as a cubic, this
+ // should not be a problem;
+ // The recursion depth will be the same in any case.
+ Intersection[] x = cubicCubicIntersect(getCubicSegment(),
+ ((QuadSegment) b)
+ .getCubicSegment());
+ if (x == null)
+ return 0;
+
+ if (x.length == 1)
+ return createNode(b, (Intersection) x[0]);
+
+ return createNodes(b, x);
+ }
+ return 0;
+ }
+
+ /**
+ * Subdivides the segment at parametric value t, inserting
+ * the new segment into the linked list after this,
+ * such that this becomes [0,t] and this.next becomes [t,1]
+ */
+ void subdivideInsert(double t)
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+
+ double p10x = x0 + t * (x1 - x0);
+ double p10y = y0 + t * (y1 - y0);
+ double p11x = x1 + t * (x2 - x1);
+ double p11y = y1 + t * (y2 - y1);
+ double p20x = p10x + t * (p11x - p10x);
+ double p20y = p10y + t * (p11y - p10y);
+
+ insert(new QuadSegment(p20x, p20y, p11x, p11y, x2, y2));
+ P2 = next.P1;
+ cp.setLocation(p10x, p10y);
+
+ next.node = node;
+ node = null;
+ }
+
+ /**
+ * Transforms the segment
+ */
+ void transform(AffineTransform at)
+ {
+ P1 = at.transform(P1, null);
+ P2 = at.transform(P2, null);
+ cp = at.transform(cp, null);
+ }
+ } // class QuadSegment
+
+ /**
+ * Cubic Bezier curve segment
+ */
+ private class CubicSegment extends Segment
+ {
+ Point2D cp1; // control points
+ Point2D cp2; // control points
+
+ /**
+ * Constructor - takes coordinates of the starting point,
+ * first control point, second control point and end point,
+ * respecively.
+ */
+ public CubicSegment(double x1, double y1, double c1x, double c1y,
+ double c2x, double c2y, double x2, double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ cp1 = new Point2D.Double(c1x, c1y);
+ cp2 = new Point2D.Double(c2x, c2y);
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new CubicSegment(P1.getX(), P1.getY(), cp1.getX(), cp1.getY(),
+ cp2.getX(), cp2.getY(), P2.getX(), P2.getY());
+ }
+
+ /**
+ * Returns twice the area of a curve, relative the P1-P2 line
+ *
+ * The area formula can be derived by using Green's formula in the
+ * plane on the parametric form of the bezier.
+ */
+ double curveArea()
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp1.getX();
+ double y1 = cp1.getY();
+ double x2 = cp2.getX();
+ double y2 = cp2.getY();
+ double x3 = P2.getX();
+ double y3 = P2.getY();
+
+ double P = y3 - 3 * y2 + 3 * y1 - y0;
+ double Q = 3 * (y2 + y0 - 2 * y1);
+ double R = 3 * (y1 - y0);
+
+ double A = x3 - 3 * x2 + 3 * x1 - x0;
+ double B = 3 * (x2 + x0 - 2 * x1);
+ double C = 3 * (x1 - x0);
+
+ double area = (B * P - A * Q) / 5.0 + (C * P - A * R) / 2.0
+ + (C * Q - B * R) / 3.0;
+
+ return (area);
+ }
+
+ /**
+ * Compare two segments.
+ */
+ boolean equals(Segment b)
+ {
+ if (! (b instanceof CubicSegment))
+ return false;
+
+ return (P1.equals(b.P1) && cp1.equals(((CubicSegment) b).cp1)
+ && cp2.equals(((CubicSegment) b).cp2) && P2.equals(b.P2));
+ }
+
+ /**
+ * Returns a Point2D corresponding to the parametric value t
+ * of the curve
+ */
+ Point2D evaluatePoint(double t)
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp1.getX();
+ double y1 = cp1.getY();
+ double x2 = cp2.getX();
+ double y2 = cp2.getY();
+ double x3 = P2.getX();
+ double y3 = P2.getY();
+
+ return new Point2D.Double(-(t * t * t) * (x0 - 3 * x1 + 3 * x2 - x3)
+ + 3 * t * t * (x0 - 2 * x1 + x2)
+ + 3 * t * (x1 - x0) + x0,
+ -(t * t * t) * (y0 - 3 * y1 + 3 * y2 - y3)
+ + 3 * t * t * (y0 - 2 * y1 + y2)
+ + 3 * t * (y1 - y0) + y0);
+ }
+
+ /**
+ * Returns the bounding box of this segment
+ */
+ Rectangle2D getBounds()
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp1.getX();
+ double y1 = cp1.getY();
+ double x2 = cp2.getX();
+ double y2 = cp2.getY();
+ double x3 = P2.getX();
+ double y3 = P2.getY();
+ double[] r = new double[3];
+
+ double xmax = Math.max(x0, x3);
+ double ymax = Math.max(y0, y3);
+ double xmin = Math.min(x0, x3);
+ double ymin = Math.min(y0, y3);
+
+ r[0] = 3 * (y1 - y0);
+ r[1] = 6.0 * (y2 + y0 - 2 * y1);
+ r[2] = 3.0 * (y3 - 3 * y2 + 3 * y1 - y0);
+
+ int n = QuadCurve2D.solveQuadratic(r);
+ for (int i = 0; i < n; i++)
+ {
+ double t = r[i];
+ if (t > 0 && t < 1.0)
+ {
+ double y = evaluatePoint(t).getY();
+ ymax = Math.max(y, ymax);
+ ymin = Math.min(y, ymin);
+ }
+ }
+
+ r[0] = 3 * (x1 - x0);
+ r[1] = 6.0 * (x2 + x0 - 2 * x1);
+ r[2] = 3.0 * (x3 - 3 * x2 + 3 * x1 - x0);
+ n = QuadCurve2D.solveQuadratic(r);
+ for (int i = 0; i < n; i++)
+ {
+ double t = r[i];
+ if (t > 0 && t < 1.0)
+ {
+ double x = evaluatePoint(t).getX();
+ xmax = Math.max(x, xmax);
+ xmin = Math.min(x, xmin);
+ }
+ }
+ return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
+ }
+
+ /**
+ * Returns a CubicCurve2D object corresponding to this segment.
+ */
+ CubicCurve2D getCubicCurve2D()
+ {
+ return new CubicCurve2D.Double(P1.getX(), P1.getY(), cp1.getX(),
+ cp1.getY(), cp2.getX(), cp2.getY(),
+ P2.getX(), P2.getY());
+ }
+
+ /**
+ * Returns the parametric points of self-intersection if the cubic
+ * is self-intersecting, null otherwise.
+ */
+ double[] getLoop()
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp1.getX();
+ double y1 = cp1.getY();
+ double x2 = cp2.getX();
+ double y2 = cp2.getY();
+ double x3 = P2.getX();
+ double y3 = P2.getY();
+ double[] r = new double[4];
+ double k;
+ double R;
+ double T;
+ double A;
+ double B;
+ double[] results = new double[2];
+
+ R = x3 - 3 * x2 + 3 * x1 - x0;
+ T = y3 - 3 * y2 + 3 * y1 - y0;
+
+ // A qudratic
+ if (R == 0.0 && T == 0.0)
+ return null;
+
+ // true cubic
+ if (R != 0.0 && T != 0.0)
+ {
+ A = 3 * (x2 + x0 - 2 * x1) / R;
+ B = 3 * (x1 - x0) / R;
+
+ double P = 3 * (y2 + y0 - 2 * y1) / T;
+ double Q = 3 * (y1 - y0) / T;
+
+ if (A == P || Q == B)
+ return null;
+
+ k = (Q - B) / (A - P);
+ }
+ else
+ {
+ if (R == 0.0)
+ {
+ // quadratic in x
+ k = -(3 * (x1 - x0)) / (3 * (x2 + x0 - 2 * x1));
+ A = 3 * (y2 + y0 - 2 * y1) / T;
+ B = 3 * (y1 - y0) / T;
+ }
+ else
+ {
+ // quadratic in y
+ k = -(3 * (y1 - y0)) / (3 * (y2 + y0 - 2 * y1));
+ A = 3 * (x2 + x0 - 2 * x1) / R;
+ B = 3 * (x1 - x0) / R;
+ }
+ }
+
+ r[0] = -k * k * k - A * k * k - B * k;
+ r[1] = 3 * k * k + 2 * k * A + 2 * B;
+ r[2] = -3 * k;
+ r[3] = 2;
+
+ int n = CubicCurve2D.solveCubic(r);
+ if (n != 3)
+ return null;
+
+ // sort r
+ double t;
+ for (int i = 0; i < 2; i++)
+ for (int j = i + 1; j < 3; j++)
+ if (r[j] < r[i])
+ {
+ t = r[i];
+ r[i] = r[j];
+ r[j] = t;
+ }
+
+ if (Math.abs(r[0] + r[2] - k) < 1E-13)
+ if (r[0] >= 0.0 && r[0] <= 1.0 && r[2] >= 0.0 && r[2] <= 1.0)
+ if (evaluatePoint(r[0]).distance(evaluatePoint(r[2])) < PE_EPSILON * 10)
+ { // we snap the points anyway
+ results[0] = r[0];
+ results[1] = r[2];
+ return (results);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the segment's midpoint
+ */
+ Point2D getMidPoint()
+ {
+ return evaluatePoint(0.5);
+ }
+
+ /**
+ * Returns the PathIterator type of a segment
+ */
+ int getType()
+ {
+ return (PathIterator.SEG_CUBICTO);
+ }
+
+ /**
+ * Returns the PathIterator coords of a segment
+ */
+ int pathIteratorFormat(double[] coords)
+ {
+ coords[0] = cp1.getX();
+ coords[1] = cp1.getY();
+ coords[2] = cp2.getX();
+ coords[3] = cp2.getY();
+ coords[4] = P2.getX();
+ coords[5] = P2.getY();
+ return (PathIterator.SEG_CUBICTO);
+ }
+
+ /**
+ * Returns the number of intersections on the positive X axis,
+ * with the origin at (x,y), used for contains()-testing
+ */
+ int rayCrossing(double x, double y)
+ {
+ double x0 = P1.getX() - x;
+ double y0 = P1.getY() - y;
+ double x1 = cp1.getX() - x;
+ double y1 = cp1.getY() - y;
+ double x2 = cp2.getX() - x;
+ double y2 = cp2.getY() - y;
+ double x3 = P2.getX() - x;
+ double y3 = P2.getY() - y;
+ double[] r = new double[4];
+ int nRoots;
+ int nCrossings = 0;
+
+ /* check if curve may intersect X+ axis. */
+ if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0 || x3 > 0.0)
+ && (y0 * y1 <= 0 || y1 * y2 <= 0 || y2 * y3 <= 0))
+ {
+ if (y0 == 0.0)
+ y0 -= EPSILON;
+ if (y3 == 0.0)
+ y3 -= EPSILON;
+
+ r[0] = y0;
+ r[1] = 3 * (y1 - y0);
+ r[2] = 3 * (y2 + y0 - 2 * y1);
+ r[3] = y3 - 3 * y2 + 3 * y1 - y0;
+
+ if ((nRoots = CubicCurve2D.solveCubic(r)) > 0)
+ for (int i = 0; i < nRoots; i++)
+ {
+ if (r[i] > 0.0 && r[i] < 1.0)
+ {
+ double t = r[i];
+ if (-(t * t * t) * (x0 - 3 * x1 + 3 * x2 - x3)
+ + 3 * t * t * (x0 - 2 * x1 + x2) + 3 * t * (x1 - x0)
+ + x0 > 0.0)
+ nCrossings++;
+ }
+ }
+ }
+ return nCrossings;
+ }
+
+ /**
+ * Swap start and end points
+ */
+ void reverseCoords()
+ {
+ Point2D p = P1;
+ P1 = P2;
+ P2 = p;
+ p = cp1; // swap control points
+ cp1 = cp2;
+ cp2 = p;
+ }
+
+ /**
+ * Splits intersections into nodes,
+ * This one handles cubic-cubic and cubic-quadratic intersections
+ */
+ int splitIntersections(Segment b)
+ {
+ if (b instanceof LineSegment)
+ return (b.splitIntersections(this));
+
+ Intersection[] x = null;
+
+ if (b instanceof QuadSegment)
+ x = cubicCubicIntersect(this, ((QuadSegment) b).getCubicSegment());
+
+ if (b instanceof CubicSegment)
+ x = cubicCubicIntersect(this, (CubicSegment) b);
+
+ if (x == null)
+ return 0;
+
+ if (x.length == 1)
+ return createNode(b, x[0]);
+
+ return createNodes(b, x);
+ }
+
+ /**
+ * Subdivides the segment at parametric value t, inserting
+ * the new segment into the linked list after this,
+ * such that this becomes [0,t] and this.next becomes [t,1]
+ */
+ void subdivideInsert(double t)
+ {
+ CubicSegment s = (CubicSegment) clone();
+ double p1x = (s.cp1.getX() - s.P1.getX()) * t + s.P1.getX();
+ double p1y = (s.cp1.getY() - s.P1.getY()) * t + s.P1.getY();
+
+ double px = (s.cp2.getX() - s.cp1.getX()) * t + s.cp1.getX();
+ double py = (s.cp2.getY() - s.cp1.getY()) * t + s.cp1.getY();
+
+ s.cp2.setLocation((s.P2.getX() - s.cp2.getX()) * t + s.cp2.getX(),
+ (s.P2.getY() - s.cp2.getY()) * t + s.cp2.getY());
+
+ s.cp1.setLocation((s.cp2.getX() - px) * t + px,
+ (s.cp2.getY() - py) * t + py);
+
+ double p2x = (px - p1x) * t + p1x;
+ double p2y = (py - p1y) * t + p1y;
+
+ double p3x = (s.cp1.getX() - p2x) * t + p2x;
+ double p3y = (s.cp1.getY() - p2y) * t + p2y;
+ s.P1.setLocation(p3x, p3y);
+
+ // insert new curve
+ insert(s);
+
+ // set this curve
+ cp1.setLocation(p1x, p1y);
+ cp2.setLocation(p2x, p2y);
+ P2 = s.P1;
+ next.node = node;
+ node = null;
+ }
+
+ /**
+ * Transforms the segment
+ */
+ void transform(AffineTransform at)
+ {
+ P1 = at.transform(P1, null);
+ P2 = at.transform(P2, null);
+ cp1 = at.transform(cp1, null);
+ cp2 = at.transform(cp2, null);
+ }
+ } // class CubicSegment
+} // class Area
diff --git a/libjava/classpath/java/awt/geom/CubicCurve2D.java b/libjava/classpath/java/awt/geom/CubicCurve2D.java
new file mode 100644
index 0000000..50c3811
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/CubicCurve2D.java
@@ -0,0 +1,1724 @@
+/* CubicCurve2D.java -- represents a parameterized cubic curve in 2-D space
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+
+/**
+ * A two-dimensional curve that is parameterized with a cubic
+ * function.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Graydon Hoare (graydon@redhat.com)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Sven de Marothy (sven@physto.se)
+ *
+ * @since 1.2
+ */
+public abstract class CubicCurve2D implements Shape, Cloneable
+{
+ private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
+ private static final double EPSILON = 1E-10;
+
+ /**
+ * Constructs a new CubicCurve2D. Typical users will want to
+ * construct instances of a subclass, such as {@link
+ * CubicCurve2D.Float} or {@link CubicCurve2D.Double}.
+ */
+ protected CubicCurve2D()
+ {
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public abstract double getX1();
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public abstract double getY1();
+
+ /**
+ * Returns the curve&#x2019;s start point.
+ */
+ public abstract Point2D getP1();
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s first
+ * control point.
+ */
+ public abstract double getCtrlX1();
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s first
+ * control point.
+ */
+ public abstract double getCtrlY1();
+
+ /**
+ * Returns the curve&#x2019;s first control point.
+ */
+ public abstract Point2D getCtrlP1();
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s second
+ * control point.
+ */
+ public abstract double getCtrlX2();
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s second
+ * control point.
+ */
+ public abstract double getCtrlY2();
+
+ /**
+ * Returns the curve&#x2019;s second control point.
+ */
+ public abstract Point2D getCtrlP2();
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public abstract double getX2();
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public abstract double getY2();
+
+ /**
+ * Returns the curve&#x2019;s end point.
+ */
+ public abstract Point2D getP2();
+
+ /**
+ * Changes the curve geometry, separately specifying each coordinate
+ * value.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s new
+ * first control point.
+ *
+ * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s new
+ * first control point.
+ *
+ * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s new
+ * second control point.
+ *
+ * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s new
+ * second control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
+ * point.
+ */
+ public abstract void setCurve(double x1, double y1, double cx1, double cy1,
+ double cx2, double cy2, double x2, double y2);
+
+ /**
+ * Changes the curve geometry, specifying coordinate values in an
+ * array.
+ *
+ * @param coords an array containing the new coordinate values. The
+ * <i>x</i> coordinate of the new start point is located at
+ * <code>coords[offset]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
+ * new first control point is located at <code>coords[offset +
+ * 2]</code>, its <i>y</i> coordinate at <code>coords[offset +
+ * 3]</code>. The <i>x</i> coordinate of the new second control
+ * point is located at <code>coords[offset + 4]</code>, its <i>y</i>
+ * coordinate at <code>coords[offset + 5]</code>. The <i>x</i>
+ * coordinate of the new end point is located at <code>coords[offset
+ * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset +
+ * 7]</code>.
+ *
+ * @param offset the offset of the first coordinate value in
+ * <code>coords</code>.
+ */
+ public void setCurve(double[] coords, int offset)
+ {
+ setCurve(coords[offset++], coords[offset++], coords[offset++],
+ coords[offset++], coords[offset++], coords[offset++],
+ coords[offset++], coords[offset++]);
+ }
+
+ /**
+ * Changes the curve geometry, specifying coordinate values in
+ * separate Point objects.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * <p>The curve does not keep any reference to the passed point
+ * objects. Therefore, a later change to <code>p1</code>,
+ * <code>c1</code>, <code>c2</code> or <code>p2</code> will not
+ * affect the curve geometry.
+ *
+ * @param p1 the new start point.
+ * @param c1 the new first control point.
+ * @param c2 the new second control point.
+ * @param p2 the new end point.
+ */
+ public void setCurve(Point2D p1, Point2D c1, Point2D c2, Point2D p2)
+ {
+ setCurve(p1.getX(), p1.getY(), c1.getX(), c1.getY(), c2.getX(), c2.getY(),
+ p2.getX(), p2.getY());
+ }
+
+ /**
+ * Changes the curve geometry, specifying coordinate values in an
+ * array of Point objects.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * <p>The curve does not keep references to the passed point
+ * objects. Therefore, a later change to the <code>pts</code> array
+ * or any of its elements will not affect the curve geometry.
+ *
+ * @param pts an array containing the points. The new start point
+ * is located at <code>pts[offset]</code>, the new first control
+ * point at <code>pts[offset + 1]</code>, the new second control
+ * point at <code>pts[offset + 2]</code>, and the new end point
+ * at <code>pts[offset + 3]</code>.
+ *
+ * @param offset the offset of the start point in <code>pts</code>.
+ */
+ public void setCurve(Point2D[] pts, int offset)
+ {
+ setCurve(pts[offset].getX(), pts[offset++].getY(), pts[offset].getX(),
+ pts[offset++].getY(), pts[offset].getX(), pts[offset++].getY(),
+ pts[offset].getX(), pts[offset++].getY());
+ }
+
+ /**
+ * Changes the curve geometry to that of another curve.
+ *
+ * @param c the curve whose coordinates will be copied.
+ */
+ public void setCurve(CubicCurve2D c)
+ {
+ setCurve(c.getX1(), c.getY1(), c.getCtrlX1(), c.getCtrlY1(),
+ c.getCtrlX2(), c.getCtrlY2(), c.getX2(), c.getY2());
+ }
+
+ /**
+ * Calculates the squared flatness of a cubic curve, directly
+ * specifying each coordinate value. The flatness is the maximal
+ * distance of a control point to the line between start and end
+ * point.
+ *
+ * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. In comparison to C1,
+ * control point C2 is father away from the gray line. Therefore,
+ * the result will be the square of the distance between C2 and the
+ * gray line, i.e. the squared length of the red line.
+ *
+ * @param x1 the <i>x</i> coordinate of the start point P1.
+ * @param y1 the <i>y</i> coordinate of the start point P1.
+ * @param cx1 the <i>x</i> coordinate of the first control point C1.
+ * @param cy1 the <i>y</i> coordinate of the first control point C1.
+ * @param cx2 the <i>x</i> coordinate of the second control point C2.
+ * @param cy2 the <i>y</i> coordinate of the second control point C2.
+ * @param x2 the <i>x</i> coordinate of the end point P2.
+ * @param y2 the <i>y</i> coordinate of the end point P2.
+ */
+ public static double getFlatnessSq(double x1, double y1, double cx1,
+ double cy1, double cx2, double cy2,
+ double x2, double y2)
+ {
+ return Math.max(Line2D.ptSegDistSq(x1, y1, x2, y2, cx1, cy1),
+ Line2D.ptSegDistSq(x1, y1, x2, y2, cx2, cy2));
+ }
+
+ /**
+ * Calculates the flatness of a cubic curve, directly specifying
+ * each coordinate value. The flatness is the maximal distance of a
+ * control point to the line between start and end point.
+ *
+ * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. In comparison to C1,
+ * control point C2 is father away from the gray line. Therefore,
+ * the result will be the distance between C2 and the gray line,
+ * i.e. the length of the red line.
+ *
+ * @param x1 the <i>x</i> coordinate of the start point P1.
+ * @param y1 the <i>y</i> coordinate of the start point P1.
+ * @param cx1 the <i>x</i> coordinate of the first control point C1.
+ * @param cy1 the <i>y</i> coordinate of the first control point C1.
+ * @param cx2 the <i>x</i> coordinate of the second control point C2.
+ * @param cy2 the <i>y</i> coordinate of the second control point C2.
+ * @param x2 the <i>x</i> coordinate of the end point P2.
+ * @param y2 the <i>y</i> coordinate of the end point P2.
+ */
+ public static double getFlatness(double x1, double y1, double cx1,
+ double cy1, double cx2, double cy2,
+ double x2, double y2)
+ {
+ return Math.sqrt(getFlatnessSq(x1, y1, cx1, cy1, cx2, cy2, x2, y2));
+ }
+
+ /**
+ * Calculates the squared flatness of a cubic curve, specifying the
+ * coordinate values in an array. The flatness is the maximal
+ * distance of a control point to the line between start and end
+ * point.
+ *
+ * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. In comparison to C1,
+ * control point C2 is father away from the gray line. Therefore,
+ * the result will be the square of the distance between C2 and the
+ * gray line, i.e. the squared length of the red line.
+ *
+ * @param coords an array containing the coordinate values. The
+ * <i>x</i> coordinate of the start point P1 is located at
+ * <code>coords[offset]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
+ * first control point C1 is located at <code>coords[offset +
+ * 2]</code>, its <i>y</i> coordinate at <code>coords[offset +
+ * 3]</code>. The <i>x</i> coordinate of the second control point C2
+ * is located at <code>coords[offset + 4]</code>, its <i>y</i>
+ * coordinate at <code>coords[offset + 5]</code>. The <i>x</i>
+ * coordinate of the end point P2 is located at <code>coords[offset
+ * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset +
+ * 7]</code>.
+ *
+ * @param offset the offset of the first coordinate value in
+ * <code>coords</code>.
+ */
+ public static double getFlatnessSq(double[] coords, int offset)
+ {
+ return getFlatnessSq(coords[offset++], coords[offset++], coords[offset++],
+ coords[offset++], coords[offset++], coords[offset++],
+ coords[offset++], coords[offset++]);
+ }
+
+ /**
+ * Calculates the flatness of a cubic curve, specifying the
+ * coordinate values in an array. The flatness is the maximal
+ * distance of a control point to the line between start and end
+ * point.
+ *
+ * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. In comparison to C1,
+ * control point C2 is father away from the gray line. Therefore,
+ * the result will be the distance between C2 and the gray line,
+ * i.e. the length of the red line.
+ *
+ * @param coords an array containing the coordinate values. The
+ * <i>x</i> coordinate of the start point P1 is located at
+ * <code>coords[offset]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
+ * first control point C1 is located at <code>coords[offset +
+ * 2]</code>, its <i>y</i> coordinate at <code>coords[offset +
+ * 3]</code>. The <i>x</i> coordinate of the second control point C2
+ * is located at <code>coords[offset + 4]</code>, its <i>y</i>
+ * coordinate at <code>coords[offset + 5]</code>. The <i>x</i>
+ * coordinate of the end point P2 is located at <code>coords[offset
+ * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset +
+ * 7]</code>.
+ *
+ * @param offset the offset of the first coordinate value in
+ * <code>coords</code>.
+ */
+ public static double getFlatness(double[] coords, int offset)
+ {
+ return Math.sqrt(getFlatnessSq(coords[offset++], coords[offset++],
+ coords[offset++], coords[offset++],
+ coords[offset++], coords[offset++],
+ coords[offset++], coords[offset++]));
+ }
+
+ /**
+ * Calculates the squared flatness of this curve. The flatness is
+ * the maximal distance of a control point to the line between start
+ * and end point.
+ *
+ * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. In comparison to C1,
+ * control point C2 is father away from the gray line. Therefore,
+ * the result will be the square of the distance between C2 and the
+ * gray line, i.e. the squared length of the red line.
+ */
+ public double getFlatnessSq()
+ {
+ return getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(),
+ getCtrlX2(), getCtrlY2(), getX2(), getY2());
+ }
+
+ /**
+ * Calculates the flatness of this curve. The flatness is the
+ * maximal distance of a control point to the line between start and
+ * end point.
+ *
+ * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. In comparison to C1,
+ * control point C2 is father away from the gray line. Therefore,
+ * the result will be the distance between C2 and the gray line,
+ * i.e. the length of the red line.
+ */
+ public double getFlatness()
+ {
+ return Math.sqrt(getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(),
+ getCtrlX2(), getCtrlY2(), getX2(), getY2()));
+ }
+
+ /**
+ * Subdivides this curve into two halves.
+ *
+ * <p><img src="doc-files/CubicCurve2D-3.png" width="700"
+ * height="180" alt="A drawing that illustrates the effects of
+ * subdividing a CubicCurve2D" />
+ *
+ * @param left a curve whose geometry will be set to the left half
+ * of this curve, or <code>null</code> if the caller is not
+ * interested in the left half.
+ *
+ * @param right a curve whose geometry will be set to the right half
+ * of this curve, or <code>null</code> if the caller is not
+ * interested in the right half.
+ */
+ public void subdivide(CubicCurve2D left, CubicCurve2D right)
+ {
+ // Use empty slots at end to share single array.
+ double[] d = new double[]
+ {
+ getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(),
+ getCtrlY2(), getX2(), getY2(), 0, 0, 0, 0, 0, 0
+ };
+ subdivide(d, 0, d, 0, d, 6);
+ if (left != null)
+ left.setCurve(d, 0);
+ if (right != null)
+ right.setCurve(d, 6);
+ }
+
+ /**
+ * Subdivides a cubic curve into two halves.
+ *
+ * <p><img src="doc-files/CubicCurve2D-3.png" width="700"
+ * height="180" alt="A drawing that illustrates the effects of
+ * subdividing a CubicCurve2D" />
+ *
+ * @param src the curve to be subdivided.
+ *
+ * @param left a curve whose geometry will be set to the left half
+ * of <code>src</code>, or <code>null</code> if the caller is not
+ * interested in the left half.
+ *
+ * @param right a curve whose geometry will be set to the right half
+ * of <code>src</code>, or <code>null</code> if the caller is not
+ * interested in the right half.
+ */
+ public static void subdivide(CubicCurve2D src, CubicCurve2D left,
+ CubicCurve2D right)
+ {
+ src.subdivide(left, right);
+ }
+
+ /**
+ * Subdivides a cubic curve into two halves, passing all coordinates
+ * in an array.
+ *
+ * <p><img src="doc-files/CubicCurve2D-3.png" width="700"
+ * height="180" alt="A drawing that illustrates the effects of
+ * subdividing a CubicCurve2D" />
+ *
+ * <p>The left end point and the right start point will always be
+ * identical. Memory-concious programmers thus may want to pass the
+ * same array for both <code>left</code> and <code>right</code>, and
+ * set <code>rightOff</code> to <code>leftOff + 6</code>.
+ *
+ * @param src an array containing the coordinates of the curve to be
+ * subdivided. The <i>x</i> coordinate of the start point P1 is
+ * located at <code>src[srcOff]</code>, its <i>y</i> at
+ * <code>src[srcOff + 1]</code>. The <i>x</i> coordinate of the
+ * first control point C1 is located at <code>src[srcOff +
+ * 2]</code>, its <i>y</i> at <code>src[srcOff + 3]</code>. The
+ * <i>x</i> coordinate of the second control point C2 is located at
+ * <code>src[srcOff + 4]</code>, its <i>y</i> at <code>src[srcOff +
+ * 5]</code>. The <i>x</i> coordinate of the end point is located at
+ * <code>src[srcOff + 6]</code>, its <i>y</i> at <code>src[srcOff +
+ * 7]</code>.
+ *
+ * @param srcOff an offset into <code>src</code>, specifying
+ * the index of the start point&#x2019;s <i>x</i> coordinate.
+ *
+ * @param left an array that will receive the coordinates of the
+ * left half of <code>src</code>. It is acceptable to pass
+ * <code>src</code>. A caller who is not interested in the left half
+ * can pass <code>null</code>.
+ *
+ * @param leftOff an offset into <code>left</code>, specifying the
+ * index where the start point&#x2019;s <i>x</i> coordinate will be
+ * stored.
+ *
+ * @param right an array that will receive the coordinates of the
+ * right half of <code>src</code>. It is acceptable to pass
+ * <code>src</code> or <code>left</code>. A caller who is not
+ * interested in the right half can pass <code>null</code>.
+ *
+ * @param rightOff an offset into <code>right</code>, specifying the
+ * index where the start point&#x2019;s <i>x</i> coordinate will be
+ * stored.
+ */
+ public static void subdivide(double[] src, int srcOff, double[] left,
+ int leftOff, double[] right, int rightOff)
+ {
+ // To understand this code, please have a look at the image
+ // "CubicCurve2D-3.png" in the sub-directory "doc-files".
+ double src_C1_x;
+ double src_C1_y;
+ double src_C2_x;
+ double src_C2_y;
+ double left_P1_x;
+ double left_P1_y;
+ double left_C1_x;
+ double left_C1_y;
+ double left_C2_x;
+ double left_C2_y;
+ double right_C1_x;
+ double right_C1_y;
+ double right_C2_x;
+ double right_C2_y;
+ double right_P2_x;
+ double right_P2_y;
+ double Mid_x; // Mid = left.P2 = right.P1
+ double Mid_y; // Mid = left.P2 = right.P1
+
+ left_P1_x = src[srcOff];
+ left_P1_y = src[srcOff + 1];
+ src_C1_x = src[srcOff + 2];
+ src_C1_y = src[srcOff + 3];
+ src_C2_x = src[srcOff + 4];
+ src_C2_y = src[srcOff + 5];
+ right_P2_x = src[srcOff + 6];
+ right_P2_y = src[srcOff + 7];
+
+ left_C1_x = (left_P1_x + src_C1_x) / 2;
+ left_C1_y = (left_P1_y + src_C1_y) / 2;
+ right_C2_x = (right_P2_x + src_C2_x) / 2;
+ right_C2_y = (right_P2_y + src_C2_y) / 2;
+ Mid_x = (src_C1_x + src_C2_x) / 2;
+ Mid_y = (src_C1_y + src_C2_y) / 2;
+ left_C2_x = (left_C1_x + Mid_x) / 2;
+ left_C2_y = (left_C1_y + Mid_y) / 2;
+ right_C1_x = (Mid_x + right_C2_x) / 2;
+ right_C1_y = (Mid_y + right_C2_y) / 2;
+ Mid_x = (left_C2_x + right_C1_x) / 2;
+ Mid_y = (left_C2_y + right_C1_y) / 2;
+
+ if (left != null)
+ {
+ left[leftOff] = left_P1_x;
+ left[leftOff + 1] = left_P1_y;
+ left[leftOff + 2] = left_C1_x;
+ left[leftOff + 3] = left_C1_y;
+ left[leftOff + 4] = left_C2_x;
+ left[leftOff + 5] = left_C2_y;
+ left[leftOff + 6] = Mid_x;
+ left[leftOff + 7] = Mid_y;
+ }
+
+ if (right != null)
+ {
+ right[rightOff] = Mid_x;
+ right[rightOff + 1] = Mid_y;
+ right[rightOff + 2] = right_C1_x;
+ right[rightOff + 3] = right_C1_y;
+ right[rightOff + 4] = right_C2_x;
+ right[rightOff + 5] = right_C2_y;
+ right[rightOff + 6] = right_P2_x;
+ right[rightOff + 7] = right_P2_y;
+ }
+ }
+
+ /**
+ * Finds the non-complex roots of a cubic equation, placing the
+ * results into the same array as the equation coefficients. The
+ * following equation is being solved:
+ *
+ * <blockquote><code>eqn[3]</code> &#xb7; <i>x</i><sup>3</sup>
+ * + <code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
+ * + <code>eqn[1]</code> &#xb7; <i>x</i>
+ * + <code>eqn[0]</code>
+ * = 0
+ * </blockquote>
+ *
+ * <p>For some background about solving cubic equations, see the
+ * article <a
+ * href="http://planetmath.org/encyclopedia/CubicFormula.html"
+ * >&#x201c;Cubic Formula&#x201d;</a> in <a
+ * href="http://planetmath.org/" >PlanetMath</a>. For an extensive
+ * library of numerical algorithms written in the C programming
+ * language, see the <a href= "http://www.gnu.org/software/gsl/">GNU
+ * Scientific Library</a>, from which this implementation was
+ * adapted.
+ *
+ * @param eqn an array with the coefficients of the equation. When
+ * this procedure has returned, <code>eqn</code> will contain the
+ * non-complex solutions of the equation, in no particular order.
+ *
+ * @return the number of non-complex solutions. A result of 0
+ * indicates that the equation has no non-complex solutions. A
+ * result of -1 indicates that the equation is constant (i.e.,
+ * always or never zero).
+ *
+ * @see #solveCubic(double[], double[])
+ * @see QuadCurve2D#solveQuadratic(double[],double[])
+ *
+ * @author Brian Gough (bjg@network-theory.com)
+ * (original C implementation in the <a href=
+ * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * (adaptation to Java)
+ */
+ public static int solveCubic(double[] eqn)
+ {
+ return solveCubic(eqn, eqn);
+ }
+
+ /**
+ * Finds the non-complex roots of a cubic equation. The following
+ * equation is being solved:
+ *
+ * <blockquote><code>eqn[3]</code> &#xb7; <i>x</i><sup>3</sup>
+ * + <code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
+ * + <code>eqn[1]</code> &#xb7; <i>x</i>
+ * + <code>eqn[0]</code>
+ * = 0
+ * </blockquote>
+ *
+ * <p>For some background about solving cubic equations, see the
+ * article <a
+ * href="http://planetmath.org/encyclopedia/CubicFormula.html"
+ * >&#x201c;Cubic Formula&#x201d;</a> in <a
+ * href="http://planetmath.org/" >PlanetMath</a>. For an extensive
+ * library of numerical algorithms written in the C programming
+ * language, see the <a href= "http://www.gnu.org/software/gsl/">GNU
+ * Scientific Library</a>, from which this implementation was
+ * adapted.
+ *
+ * @see QuadCurve2D#solveQuadratic(double[],double[])
+ *
+ * @param eqn an array with the coefficients of the equation.
+ *
+ * @param res an array into which the non-complex roots will be
+ * stored. The results may be in an arbitrary order. It is safe to
+ * pass the same array object reference for both <code>eqn</code>
+ * and <code>res</code>.
+ *
+ * @return the number of non-complex solutions. A result of 0
+ * indicates that the equation has no non-complex solutions. A
+ * result of -1 indicates that the equation is constant (i.e.,
+ * always or never zero).
+ *
+ * @author Brian Gough (bjg@network-theory.com)
+ * (original C implementation in the <a href=
+ * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * (adaptation to Java)
+ */
+ public static int solveCubic(double[] eqn, double[] res)
+ {
+ // Adapted from poly/solve_cubic.c in the GNU Scientific Library
+ // (GSL), revision 1.7 of 2003-07-26. For the original source, see
+ // http://www.gnu.org/software/gsl/
+ //
+ // Brian Gough, the author of that code, has granted the
+ // permission to use it in GNU Classpath under the GNU Classpath
+ // license, and has assigned the copyright to the Free Software
+ // Foundation.
+ //
+ // The Java implementation is very similar to the GSL code, but
+ // not a strict one-to-one copy. For example, GSL would sort the
+ // result.
+
+ double a;
+ double b;
+ double c;
+ double q;
+ double r;
+ double Q;
+ double R;
+ double c3;
+ double Q3;
+ double R2;
+ double CR2;
+ double CQ3;
+
+ // If the cubic coefficient is zero, we have a quadratic equation.
+ c3 = eqn[3];
+ if (c3 == 0)
+ return QuadCurve2D.solveQuadratic(eqn, res);
+
+ // Divide the equation by the cubic coefficient.
+ c = eqn[0] / c3;
+ b = eqn[1] / c3;
+ a = eqn[2] / c3;
+
+ // We now need to solve x^3 + ax^2 + bx + c = 0.
+ q = a * a - 3 * b;
+ r = 2 * a * a * a - 9 * a * b + 27 * c;
+
+ Q = q / 9;
+ R = r / 54;
+
+ Q3 = Q * Q * Q;
+ R2 = R * R;
+
+ CR2 = 729 * r * r;
+ CQ3 = 2916 * q * q * q;
+
+ if (R == 0 && Q == 0)
+ {
+ // The GNU Scientific Library would return three identical
+ // solutions in this case.
+ res[0] = -a / 3;
+ return 1;
+ }
+
+ if (CR2 == CQ3)
+ {
+ /* this test is actually R2 == Q3, written in a form suitable
+ for exact computation with integers */
+ /* Due to finite precision some double roots may be missed, and
+ considered to be a pair of complex roots z = x +/- epsilon i
+ close to the real axis. */
+ double sqrtQ = Math.sqrt(Q);
+
+ if (R > 0)
+ {
+ res[0] = -2 * sqrtQ - a / 3;
+ res[1] = sqrtQ - a / 3;
+ }
+ else
+ {
+ res[0] = -sqrtQ - a / 3;
+ res[1] = 2 * sqrtQ - a / 3;
+ }
+ return 2;
+ }
+
+ if (CR2 < CQ3) /* equivalent to R2 < Q3 */
+ {
+ double sqrtQ = Math.sqrt(Q);
+ double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
+ double theta = Math.acos(R / sqrtQ3);
+ double norm = -2 * sqrtQ;
+ res[0] = norm * Math.cos(theta / 3) - a / 3;
+ res[1] = norm * Math.cos((theta + 2.0 * Math.PI) / 3) - a / 3;
+ res[2] = norm * Math.cos((theta - 2.0 * Math.PI) / 3) - a / 3;
+
+ // The GNU Scientific Library sorts the results. We don't.
+ return 3;
+ }
+
+ double sgnR = (R >= 0 ? 1 : -1);
+ double A = -sgnR * Math.pow(Math.abs(R) + Math.sqrt(R2 - Q3), 1.0 / 3.0);
+ double B = Q / A;
+ res[0] = A + B - a / 3;
+ return 1;
+ }
+
+ /**
+ * Determines whether a position lies inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; a CubicCurve2D.
+ */
+ public boolean contains(double x, double y)
+ {
+ if (! getBounds2D().contains(x, y))
+ return false;
+
+ return ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0);
+ }
+
+ /**
+ * Determines whether a point lies inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; a CubicCurve2D.
+ */
+ public boolean contains(Point2D p)
+ {
+ return contains(p.getX(), p.getY());
+ }
+
+ /**
+ * Determines whether any part of a rectangle is inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; in a CubicCurve2D.
+ * @see #contains(double, double)
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ if (! getBounds2D().contains(x, y, w, h))
+ return false;
+
+ /* Does any edge intersect? */
+ if (getAxisIntersections(x, y, true, w) != 0 /* top */
+ || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
+ || getAxisIntersections(x + w, y, false, h) != 0 /* right */
+ || getAxisIntersections(x, y, false, h) != 0) /* left */
+ return true;
+
+ /* No intersections, is any point inside? */
+ if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Determines whether any part of a Rectangle2D is inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ * @see #intersects(double, double, double, double)
+ */
+ public boolean intersects(Rectangle2D r)
+ {
+ return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Determine whether a rectangle is entirely inside the area that is bounded
+ * by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; a CubicCurve2D.
+ * @see #contains(double, double)
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ if (! getBounds2D().intersects(x, y, w, h))
+ return false;
+
+ /* Does any edge intersect? */
+ if (getAxisIntersections(x, y, true, w) != 0 /* top */
+ || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
+ || getAxisIntersections(x + w, y, false, h) != 0 /* right */
+ || getAxisIntersections(x, y, false, h) != 0) /* left */
+ return false;
+
+ /* No intersections, is any point inside? */
+ if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Determine whether a Rectangle2D is entirely inside the area that is
+ * bounded by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; a CubicCurve2D.
+ * @see #contains(double, double)
+ */
+ public boolean contains(Rectangle2D r)
+ {
+ return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Determines the smallest rectangle that encloses the
+ * curve&#x2019;s start, end and control points.
+ */
+ public Rectangle getBounds()
+ {
+ return getBounds2D().getBounds();
+ }
+
+ public PathIterator getPathIterator(final AffineTransform at)
+ {
+ return new PathIterator()
+ {
+ /** Current coordinate. */
+ private int current = 0;
+
+ public int getWindingRule()
+ {
+ return WIND_NON_ZERO;
+ }
+
+ public boolean isDone()
+ {
+ return current >= 2;
+ }
+
+ public void next()
+ {
+ current++;
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ int result;
+ switch (current)
+ {
+ case 0:
+ coords[0] = (float) getX1();
+ coords[1] = (float) getY1();
+ result = SEG_MOVETO;
+ break;
+ case 1:
+ coords[0] = (float) getCtrlX1();
+ coords[1] = (float) getCtrlY1();
+ coords[2] = (float) getCtrlX2();
+ coords[3] = (float) getCtrlY2();
+ coords[4] = (float) getX2();
+ coords[5] = (float) getY2();
+ result = SEG_CUBICTO;
+ break;
+ default:
+ throw new NoSuchElementException("cubic iterator out of bounds");
+ }
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 3);
+ return result;
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ int result;
+ switch (current)
+ {
+ case 0:
+ coords[0] = getX1();
+ coords[1] = getY1();
+ result = SEG_MOVETO;
+ break;
+ case 1:
+ coords[0] = getCtrlX1();
+ coords[1] = getCtrlY1();
+ coords[2] = getCtrlX2();
+ coords[3] = getCtrlY2();
+ coords[4] = getX2();
+ coords[5] = getY2();
+ result = SEG_CUBICTO;
+ break;
+ default:
+ throw new NoSuchElementException("cubic iterator out of bounds");
+ }
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 3);
+ return result;
+ }
+ };
+ }
+
+ public PathIterator getPathIterator(AffineTransform at, double flatness)
+ {
+ return new FlatteningPathIterator(getPathIterator(at), flatness);
+ }
+
+ /**
+ * Create a new curve with the same contents as this one.
+ *
+ * @return the clone.
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+
+ /**
+ * Helper method used by contains() and intersects() methods, that
+ * returns the number of curve/line intersections on a given axis
+ * extending from a certain point.
+ *
+ * @param x x coordinate of the origin point
+ * @param y y coordinate of the origin point
+ * @param useYaxis axis used, if true the positive Y axis is used,
+ * false uses the positive X axis.
+ *
+ * This is an implementation of the line-crossings algorithm,
+ * Detailed in an article on Eric Haines' page:
+ * http://www.acm.org/tog/editors/erich/ptinpoly/
+ *
+ * A special-case not adressed in this code is self-intersections
+ * of the curve, e.g. if the axis intersects the self-itersection,
+ * the degenerate roots of the polynomial will erroneously count as
+ * a single intersection of the curve, and not two.
+ */
+ private int getAxisIntersections(double x, double y, boolean useYaxis,
+ double distance)
+ {
+ int nCrossings = 0;
+ double a0;
+ double a1;
+ double a2;
+ double a3;
+ double b0;
+ double b1;
+ double b2;
+ double b3;
+ double[] r = new double[4];
+ int nRoots;
+
+ a0 = a3 = 0.0;
+
+ if (useYaxis)
+ {
+ a0 = getY1() - y;
+ a1 = getCtrlY1() - y;
+ a2 = getCtrlY2() - y;
+ a3 = getY2() - y;
+ b0 = getX1() - x;
+ b1 = getCtrlX1() - x;
+ b2 = getCtrlX2() - x;
+ b3 = getX2() - x;
+ }
+ else
+ {
+ a0 = getX1() - x;
+ a1 = getCtrlX1() - x;
+ a2 = getCtrlX2() - x;
+ a3 = getX2() - x;
+ b0 = getY1() - y;
+ b1 = getCtrlY1() - y;
+ b2 = getCtrlY2() - y;
+ b3 = getY2() - y;
+ }
+
+ /* If the axis intersects a start/endpoint, shift it up by some small
+ amount to guarantee the line is 'inside'
+ If this is not done, bad behaviour may result for points on that axis.*/
+ if (a0 == 0.0 || a3 == 0.0)
+ {
+ double small = getFlatness() * EPSILON;
+ if (a0 == 0.0)
+ a0 -= small;
+ if (a3 == 0.0)
+ a3 -= small;
+ }
+
+ if (useYaxis)
+ {
+ if (Line2D.linesIntersect(b0, a0, b3, a3, EPSILON, 0.0, distance, 0.0))
+ nCrossings++;
+ }
+ else
+ {
+ if (Line2D.linesIntersect(a0, b0, a3, b3, 0.0, EPSILON, 0.0, distance))
+ nCrossings++;
+ }
+
+ r[0] = a0;
+ r[1] = 3 * (a1 - a0);
+ r[2] = 3 * (a2 + a0 - 2 * a1);
+ r[3] = a3 - 3 * a2 + 3 * a1 - a0;
+
+ if ((nRoots = solveCubic(r)) != 0)
+ for (int i = 0; i < nRoots; i++)
+ {
+ double t = r[i];
+ if (t >= 0.0 && t <= 1.0)
+ {
+ double crossing = -(t * t * t) * (b0 - 3 * b1 + 3 * b2 - b3)
+ + 3 * t * t * (b0 - 2 * b1 + b2)
+ + 3 * t * (b1 - b0) + b0;
+ if (crossing > 0.0 && crossing <= distance)
+ nCrossings++;
+ }
+ }
+
+ return (nCrossings);
+ }
+
+ /**
+ * A two-dimensional curve that is parameterized with a cubic
+ * function and stores coordinate values in double-precision
+ * floating-point format.
+ *
+ * @see CubicCurve2D.Float
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ public static class Double extends CubicCurve2D
+ {
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s start point.
+ */
+ public double x1;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s start point.
+ */
+ public double y1;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s first control point.
+ */
+ public double ctrlx1;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s first control point.
+ */
+ public double ctrly1;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s second control point.
+ */
+ public double ctrlx2;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s second control point.
+ */
+ public double ctrly2;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s end point.
+ */
+ public double x2;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s end point.
+ */
+ public double y2;
+
+ /**
+ * Constructs a new CubicCurve2D that stores its coordinate values
+ * in double-precision floating-point format. All points are
+ * initially at position (0, 0).
+ */
+ public Double()
+ {
+ }
+
+ /**
+ * Constructs a new CubicCurve2D that stores its coordinate values
+ * in double-precision floating-point format, specifying the
+ * initial position of each point.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ *
+ * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s first
+ * control point.
+ *
+ * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s first
+ * control point.
+ *
+ * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s second
+ * control point.
+ *
+ * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s second
+ * control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public Double(double x1, double y1, double cx1, double cy1, double cx2,
+ double cy2, double x2, double y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ ctrlx1 = cx1;
+ ctrly1 = cy1;
+ ctrlx2 = cx2;
+ ctrly2 = cy2;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public double getX1()
+ {
+ return x1;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public double getY1()
+ {
+ return y1;
+ }
+
+ /**
+ * Returns the curve&#x2019;s start point.
+ */
+ public Point2D getP1()
+ {
+ return new Point2D.Double(x1, y1);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s first
+ * control point.
+ */
+ public double getCtrlX1()
+ {
+ return ctrlx1;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s first
+ * control point.
+ */
+ public double getCtrlY1()
+ {
+ return ctrly1;
+ }
+
+ /**
+ * Returns the curve&#x2019;s first control point.
+ */
+ public Point2D getCtrlP1()
+ {
+ return new Point2D.Double(ctrlx1, ctrly1);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s second
+ * control point.
+ */
+ public double getCtrlX2()
+ {
+ return ctrlx2;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s second
+ * control point.
+ */
+ public double getCtrlY2()
+ {
+ return ctrly2;
+ }
+
+ /**
+ * Returns the curve&#x2019;s second control point.
+ */
+ public Point2D getCtrlP2()
+ {
+ return new Point2D.Double(ctrlx2, ctrly2);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public double getX2()
+ {
+ return x2;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public double getY2()
+ {
+ return y2;
+ }
+
+ /**
+ * Returns the curve&#x2019;s end point.
+ */
+ public Point2D getP2()
+ {
+ return new Point2D.Double(x2, y2);
+ }
+
+ /**
+ * Changes the curve geometry, separately specifying each coordinate
+ * value.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s new
+ * first control point.
+ *
+ * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s new
+ * first control point.
+ *
+ * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s new
+ * second control point.
+ *
+ * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s new
+ * second control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
+ * point.
+ */
+ public void setCurve(double x1, double y1, double cx1, double cy1,
+ double cx2, double cy2, double x2, double y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ ctrlx1 = cx1;
+ ctrly1 = cy1;
+ ctrlx2 = cx2;
+ ctrly2 = cy2;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Determines the smallest rectangle that encloses the
+ * curve&#x2019;s start, end and control points. As the
+ * illustration below shows, the invisible control points may cause
+ * the bounds to be much larger than the area that is actually
+ * covered by the curve.
+ *
+ * <p><img src="doc-files/CubicCurve2D-2.png" width="350" height="180"
+ * alt="An illustration of the bounds of a CubicCurve2D" />
+ */
+ public Rectangle2D getBounds2D()
+ {
+ double nx1 = Math.min(Math.min(x1, ctrlx1), Math.min(ctrlx2, x2));
+ double ny1 = Math.min(Math.min(y1, ctrly1), Math.min(ctrly2, y2));
+ double nx2 = Math.max(Math.max(x1, ctrlx1), Math.max(ctrlx2, x2));
+ double ny2 = Math.max(Math.max(y1, ctrly1), Math.max(ctrly2, y2));
+ return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1);
+ }
+ }
+
+ /**
+ * A two-dimensional curve that is parameterized with a cubic
+ * function and stores coordinate values in single-precision
+ * floating-point format.
+ *
+ * @see CubicCurve2D.Float
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ public static class Float extends CubicCurve2D
+ {
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s start point.
+ */
+ public float x1;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s start point.
+ */
+ public float y1;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s first control point.
+ */
+ public float ctrlx1;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s first control point.
+ */
+ public float ctrly1;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s second control point.
+ */
+ public float ctrlx2;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s second control point.
+ */
+ public float ctrly2;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s end point.
+ */
+ public float x2;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s end point.
+ */
+ public float y2;
+
+ /**
+ * Constructs a new CubicCurve2D that stores its coordinate values
+ * in single-precision floating-point format. All points are
+ * initially at position (0, 0).
+ */
+ public Float()
+ {
+ }
+
+ /**
+ * Constructs a new CubicCurve2D that stores its coordinate values
+ * in single-precision floating-point format, specifying the
+ * initial position of each point.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ *
+ * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s first
+ * control point.
+ *
+ * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s first
+ * control point.
+ *
+ * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s second
+ * control point.
+ *
+ * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s second
+ * control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public Float(float x1, float y1, float cx1, float cy1, float cx2,
+ float cy2, float x2, float y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ ctrlx1 = cx1;
+ ctrly1 = cy1;
+ ctrlx2 = cx2;
+ ctrly2 = cy2;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public double getX1()
+ {
+ return x1;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public double getY1()
+ {
+ return y1;
+ }
+
+ /**
+ * Returns the curve&#x2019;s start point.
+ */
+ public Point2D getP1()
+ {
+ return new Point2D.Float(x1, y1);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s first
+ * control point.
+ */
+ public double getCtrlX1()
+ {
+ return ctrlx1;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s first
+ * control point.
+ */
+ public double getCtrlY1()
+ {
+ return ctrly1;
+ }
+
+ /**
+ * Returns the curve&#x2019;s first control point.
+ */
+ public Point2D getCtrlP1()
+ {
+ return new Point2D.Float(ctrlx1, ctrly1);
+ }
+
+ /**
+ * Returns the <i>s</i> coordinate of the curve&#x2019;s second
+ * control point.
+ */
+ public double getCtrlX2()
+ {
+ return ctrlx2;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s second
+ * control point.
+ */
+ public double getCtrlY2()
+ {
+ return ctrly2;
+ }
+
+ /**
+ * Returns the curve&#x2019;s second control point.
+ */
+ public Point2D getCtrlP2()
+ {
+ return new Point2D.Float(ctrlx2, ctrly2);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public double getX2()
+ {
+ return x2;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public double getY2()
+ {
+ return y2;
+ }
+
+ /**
+ * Returns the curve&#x2019;s end point.
+ */
+ public Point2D getP2()
+ {
+ return new Point2D.Float(x2, y2);
+ }
+
+ /**
+ * Changes the curve geometry, separately specifying each coordinate
+ * value as a double-precision floating-point number.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s new
+ * first control point.
+ *
+ * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s new
+ * first control point.
+ *
+ * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s new
+ * second control point.
+ *
+ * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s new
+ * second control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
+ * point.
+ */
+ public void setCurve(double x1, double y1, double cx1, double cy1,
+ double cx2, double cy2, double x2, double y2)
+ {
+ this.x1 = (float) x1;
+ this.y1 = (float) y1;
+ ctrlx1 = (float) cx1;
+ ctrly1 = (float) cy1;
+ ctrlx2 = (float) cx2;
+ ctrly2 = (float) cy2;
+ this.x2 = (float) x2;
+ this.y2 = (float) y2;
+ }
+
+ /**
+ * Changes the curve geometry, separately specifying each coordinate
+ * value as a single-precision floating-point number.
+ *
+ * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a CubicCurve2D" />
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s new
+ * first control point.
+ *
+ * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s new
+ * first control point.
+ *
+ * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s new
+ * second control point.
+ *
+ * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s new
+ * second control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
+ * point.
+ */
+ public void setCurve(float x1, float y1, float cx1, float cy1, float cx2,
+ float cy2, float x2, float y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ ctrlx1 = cx1;
+ ctrly1 = cy1;
+ ctrlx2 = cx2;
+ ctrly2 = cy2;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Determines the smallest rectangle that encloses the
+ * curve&#x2019;s start, end and control points. As the
+ * illustration below shows, the invisible control points may cause
+ * the bounds to be much larger than the area that is actually
+ * covered by the curve.
+ *
+ * <p><img src="doc-files/CubicCurve2D-2.png" width="350" height="180"
+ * alt="An illustration of the bounds of a CubicCurve2D" />
+ */
+ public Rectangle2D getBounds2D()
+ {
+ float nx1 = (float) Math.min(Math.min(x1, ctrlx1), Math.min(ctrlx2, x2));
+ float ny1 = (float) Math.min(Math.min(y1, ctrly1), Math.min(ctrly2, y2));
+ float nx2 = (float) Math.max(Math.max(x1, ctrlx1), Math.max(ctrlx2, x2));
+ float ny2 = (float) Math.max(Math.max(y1, ctrly1), Math.max(ctrly2, y2));
+ return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1);
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/geom/Dimension2D.java b/libjava/classpath/java/awt/geom/Dimension2D.java
new file mode 100644
index 0000000..6b5ce88
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/Dimension2D.java
@@ -0,0 +1,118 @@
+/* Dimension2D.java -- abstraction of a dimension
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.geom;
+
+/**
+ * This stores a dimension in 2-dimensional space - a width (along the x-axis)
+ * and height (along the y-axis). The storage is left to subclasses.
+ *
+ * @author Per Bothner (bothner@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public abstract class Dimension2D implements Cloneable
+{
+ /**
+ * The default constructor.
+ */
+ protected Dimension2D()
+ {
+ }
+
+ /**
+ * Get the width of this dimension. A negative result, while legal, is
+ * undefined in meaning.
+ *
+ * @return the width
+ */
+ public abstract double getWidth();
+
+ /**
+ * Get the height of this dimension. A negative result, while legal, is
+ * undefined in meaning.
+ *
+ * @return the height
+ */
+ public abstract double getHeight();
+
+ /**
+ * Set the size of this dimension to the requested values. Loss of precision
+ * may occur.
+ *
+ * @param w the new width
+ * @param h the new height
+ */
+ public abstract void setSize(double w, double h);
+
+ /**
+ * Set the size of this dimension to the requested value. Loss of precision
+ * may occur.
+ *
+ * @param d the dimension containing the new values
+ *
+ * @throws NullPointerException if d is null
+ */
+ public void setSize(Dimension2D d)
+ {
+ setSize(d.getWidth(), d.getHeight());
+ }
+
+ /**
+ * Create a new dimension of the same run-time type with the same contents
+ * as this one.
+ *
+ * @return the clone
+ *
+ * @exception OutOfMemoryError If there is not enough memory available.
+ *
+ * @since 1.2
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+} // class Dimension2D
diff --git a/libjava/classpath/java/awt/geom/Ellipse2D.java b/libjava/classpath/java/awt/geom/Ellipse2D.java
new file mode 100644
index 0000000..e883077
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/Ellipse2D.java
@@ -0,0 +1,413 @@
+/* Ellipse2D.java -- represents an ellipse in 2-D space
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+
+/**
+ * Ellipse2D is the shape of an ellipse.
+ * <BR>
+ * <img src="doc-files/Ellipse-1.png" width="347" height="221"
+ * alt="A drawing of an ellipse" /><BR>
+ * The ellipse is defined by it's bounding box (shown in red),
+ * and is defined by the implicit curve:<BR>
+ * <blockquote>(<i>x</i>/<i>a</i>)<sup>2</sup> +
+ * (<i>y</i>/<i>b</i>)<sup>2</sup> = 1<BR><BR></blockquote>
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ *
+ * @since 1.2
+ */
+public abstract class Ellipse2D extends RectangularShape
+{
+ /**
+ * Ellipse2D is defined as abstract.
+ * Implementing classes are Ellipse2D.Float and Ellipse2D.Double.
+ */
+ protected Ellipse2D()
+ {
+ }
+
+ /**
+ * Determines if a point is contained within the ellipse. <P>
+ * @param x - x coordinate of the point.
+ * @param y - y coordinate of the point.
+ * @return true if the point is within the ellipse, false otherwise.
+ */
+ public boolean contains(double x, double y)
+ {
+ double rx = getWidth() / 2;
+ double ry = getHeight() / 2;
+ double tx = (x - (getX() + rx)) / rx;
+ double ty = (y - (getY() + ry)) / ry;
+ return tx * tx + ty * ty < 1.0;
+ }
+
+ /**
+ * Determines if a rectangle is completely contained within the
+ * ellipse. <P>
+ * @param x - x coordinate of the upper-left corner of the rectangle
+ * @param y - y coordinate of the upper-left corner of the rectangle
+ * @param w - width of the rectangle
+ * @param h - height of the rectangle
+ * @return true if the rectangle is completely contained, false otherwise.
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ double x2 = x + w;
+ double y2 = y + h;
+ return (contains(x, y) && contains(x, y2) && contains(x2, y)
+ && contains(x2, y2));
+ }
+
+ /**
+ * Returns a PathIterator object corresponding to the ellipse.<P>
+ *
+ * Note: An ellipse cannot be represented exactly in PathIterator
+ * segments, the outline is thefore approximated with cubic
+ * Bezier segments.
+ *
+ * @param at an optional transform.
+ * @return A path iterator.
+ */
+ public PathIterator getPathIterator(AffineTransform at)
+ {
+ // An ellipse is just a complete arc.
+ return new Arc2D.ArcIterator(this, at);
+ }
+
+ /**
+ * Determines if a rectangle intersects any part of the ellipse.<P>
+ * @param x - x coordinate of the upper-left corner of the rectangle
+ * @param y - y coordinate of the upper-left corner of the rectangle
+ * @param w - width of the rectangle
+ * @param h - height of the rectangle
+ * @return true if the rectangle intersects the ellipse, false otherwise.
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ Rectangle2D r = new Rectangle2D.Double(x, y, w, h);
+ if (! r.intersects(getX(), getY(), getWidth(), getHeight()))
+ return false;
+
+ if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
+ || contains(x + w, y + h))
+ return true;
+
+ Line2D l1 = new Line2D.Double(getX(), getY() + (getHeight() / 2),
+ getX() + getWidth(),
+ getY() + (getHeight() / 2));
+ Line2D l2 = new Line2D.Double(getX() + (getWidth() / 2), getY(),
+ getX() + (getWidth() / 2),
+ getY() + getHeight());
+
+ if (l1.intersects(r) || l2.intersects(r))
+ return true;
+
+ return false;
+ }
+
+ /**
+ * An {@link Ellipse2D} that stores its coordinates using <code>double</code>
+ * primitives.
+ */
+ public static class Double extends Ellipse2D
+ {
+ /**
+ * The height of the ellipse.
+ */
+ public double height;
+
+ /**
+ * The width of the ellipse.
+ */
+ public double width;
+
+ /**
+ * The upper-left x coordinate of the bounding-box
+ */
+ public double x;
+
+ /**
+ * The upper-left y coordinate of the bounding-box
+ */
+ public double y;
+
+ /**
+ * Creates a new Ellipse2D with an upper-left coordinate of (0,0)
+ * and a zero size.
+ */
+ public Double()
+ {
+ }
+
+ /**
+ * Creates a new Ellipse2D within a given rectangle
+ * using double-precision coordinates.<P>
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ */
+ public Double(double x, double y, double w, double h)
+ {
+ this.x = x;
+ this.y = y;
+ height = h;
+ width = w;
+ }
+
+ /**
+ * Returns the bounding-box of the ellipse.
+ * @return The bounding box.
+ */
+ public Rectangle2D getBounds2D()
+ {
+ return new Rectangle2D.Double(x, y, width, height);
+ }
+
+ /**
+ * Returns the height of the ellipse.
+ * @return The height of the ellipse.
+ */
+ public double getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Returns the width of the ellipse.
+ * @return The width of the ellipse.
+ */
+ public double getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Returns x coordinate of the upper-left corner of
+ * the ellipse's bounding-box.
+ * @return The x coordinate.
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Returns y coordinate of the upper-left corner of
+ * the ellipse's bounding-box.
+ * @return The y coordinate.
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Returns <code>true</code> if the ellipse encloses no area, and
+ * <code>false</code> otherwise.
+ *
+ * @return A boolean.
+ */
+ public boolean isEmpty()
+ {
+ return height <= 0 || width <= 0;
+ }
+
+ /**
+ * Sets the geometry of the ellipse's bounding box.<P>
+ *
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ */
+ public void setFrame(double x, double y, double w, double h)
+ {
+ this.x = x;
+ this.y = y;
+ height = h;
+ width = w;
+ }
+ } // class Double
+
+ /**
+ * An {@link Ellipse2D} that stores its coordinates using <code>float</code>
+ * primitives.
+ */
+ public static class Float extends Ellipse2D
+ {
+ /**
+ * The height of the ellipse.
+ */
+ public float height;
+
+ /**
+ * The width of the ellipse.
+ */
+ public float width;
+
+ /**
+ * The upper-left x coordinate of the bounding-box
+ */
+ public float x;
+
+ /**
+ * The upper-left y coordinate of the bounding-box
+ */
+ public float y;
+
+ /**
+ * Creates a new Ellipse2D with an upper-left coordinate of (0,0)
+ * and a zero size.
+ */
+ public Float()
+ {
+ }
+
+ /**
+ * Creates a new Ellipse2D within a given rectangle
+ * using floating-point precision.<P>
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ *
+ */
+ public Float(float x, float y, float w, float h)
+ {
+ this.x = x;
+ this.y = y;
+ this.height = h;
+ this.width = w;
+ }
+
+ /**
+ * Returns the bounding-box of the ellipse.
+ * @return The bounding box.
+ */
+ public Rectangle2D getBounds2D()
+ {
+ return new Rectangle2D.Float(x, y, width, height);
+ }
+
+ /**
+ * Returns the height of the ellipse.
+ * @return The height of the ellipse.
+ */
+ public double getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Returns the width of the ellipse.
+ * @return The width of the ellipse.
+ */
+ public double getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Returns x coordinate of the upper-left corner of
+ * the ellipse's bounding-box.
+ * @return The x coordinate.
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Returns y coordinate of the upper-left corner of
+ * the ellipse's bounding-box.
+ * @return The y coordinate.
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Returns <code>true</code> if the ellipse encloses no area, and
+ * <code>false</code> otherwise.
+ *
+ * @return A boolean.
+ */
+ public boolean isEmpty()
+ {
+ return height <= 0 || width <= 0;
+ }
+
+ /**
+ * Sets the geometry of the ellipse's bounding box.<P>
+ *
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ */
+ public void setFrame(float x, float y, float w, float h)
+ {
+ this.x = x;
+ this.y = y;
+ height = h;
+ width = w;
+ }
+
+ /**
+ * Sets the geometry of the ellipse's bounding box.
+ *
+ * Note: This leads to a loss of precision.<P>
+ *
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ */
+ public void setFrame(double x, double y, double w, double h)
+ {
+ this.x = (float) x;
+ this.y = (float) y;
+ height = (float) h;
+ width = (float) w;
+ }
+ } // class Float
+} // class Ellipse2D
diff --git a/libjava/classpath/java/awt/geom/FlatteningPathIterator.java b/libjava/classpath/java/awt/geom/FlatteningPathIterator.java
new file mode 100644
index 0000000..b06e6cc
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/FlatteningPathIterator.java
@@ -0,0 +1,579 @@
+/* FlatteningPathIterator.java -- Approximates curves by straight lines
+ Copyright (C) 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+
+/**
+ * A PathIterator for approximating curved path segments by sequences
+ * of straight lines. Instances of this class will only return
+ * segments of type {@link PathIterator#SEG_MOVETO}, {@link
+ * PathIterator#SEG_LINETO}, and {@link PathIterator#SEG_CLOSE}.
+ *
+ * <p>The accuracy of the approximation is determined by two
+ * parameters:
+ *
+ * <ul><li>The <i>flatness</i> is a threshold value for deciding when
+ * a curved segment is consided flat enough for being approximated by
+ * a single straight line. Flatness is defined as the maximal distance
+ * of a curve control point to the straight line that connects the
+ * curve start and end. A lower flatness threshold means a closer
+ * approximation. See {@link QuadCurve2D#getFlatness()} and {@link
+ * CubicCurve2D#getFlatness()} for drawings which illustrate the
+ * meaning of flatness.</li>
+ *
+ * <li>The <i>recursion limit</i> imposes an upper bound for how often
+ * a curved segment gets subdivided. A limit of <i>n</i> means that
+ * for each individual quadratic and cubic B&#xe9;zier spline
+ * segment, at most 2<sup><small><i>n</i></small></sup> {@link
+ * PathIterator#SEG_LINETO} segments will be created.</li></ul>
+ *
+ * <p><b>Memory Efficiency:</b> The memory consumption grows linearly
+ * with the recursion limit. Neither the <i>flatness</i> parameter nor
+ * the number of segments in the flattened path will affect the memory
+ * consumption.
+ *
+ * <p><b>Thread Safety:</b> Multiple threads can safely work on
+ * separate instances of this class. However, multiple threads should
+ * not concurrently access the same instance, as no synchronization is
+ * performed.
+ *
+ * @see <a href="doc-files/FlatteningPathIterator-1.html"
+ * >Implementation Note</a>
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ *
+ * @since 1.2
+ */
+public class FlatteningPathIterator
+ implements PathIterator
+{
+ /**
+ * The PathIterator whose curved segments are being approximated.
+ */
+ private final PathIterator srcIter;
+
+
+ /**
+ * The square of the flatness threshold value, which determines when
+ * a curve segment is considered flat enough that no further
+ * subdivision is needed.
+ *
+ * <p>Calculating flatness actually produces the squared flatness
+ * value. To avoid the relatively expensive calculation of a square
+ * root for each curve segment, we perform all flatness comparisons
+ * on squared values.
+ *
+ * @see QuadCurve2D#getFlatnessSq()
+ * @see CubicCurve2D#getFlatnessSq()
+ */
+ private final double flatnessSq;
+
+
+ /**
+ * The maximal number of subdivions that are performed to
+ * approximate a quadratic or cubic curve segment.
+ */
+ private final int recursionLimit;
+
+
+ /**
+ * A stack for holding the coordinates of subdivided segments.
+ *
+ * @see <a href="doc-files/FlatteningPathIterator-1.html"
+ * >Implementation Note</a>
+ */
+ private double[] stack;
+
+
+ /**
+ * The current stack size.
+ *
+ * @see <a href="doc-files/FlatteningPathIterator-1.html"
+ * >Implementation Note</a>
+ */
+ private int stackSize;
+
+
+ /**
+ * The number of recursions that were performed to arrive at
+ * a segment on the stack.
+ *
+ * @see <a href="doc-files/FlatteningPathIterator-1.html"
+ * >Implementation Note</a>
+ */
+ private int[] recLevel;
+
+
+
+ private final double[] scratch = new double[6];
+
+
+ /**
+ * The segment type of the last segment that was returned by
+ * the source iterator.
+ */
+ private int srcSegType;
+
+
+ /**
+ * The current <i>x</i> position of the source iterator.
+ */
+ private double srcPosX;
+
+
+ /**
+ * The current <i>y</i> position of the source iterator.
+ */
+ private double srcPosY;
+
+
+ /**
+ * A flag that indicates when this path iterator has finished its
+ * iteration over path segments.
+ */
+ private boolean done;
+
+
+ /**
+ * Constructs a new PathIterator for approximating an input
+ * PathIterator with straight lines. The approximation works by
+ * recursive subdivisons, until the specified flatness threshold is
+ * not exceeded.
+ *
+ * <p>There will not be more than 10 nested recursion steps, which
+ * means that a single <code>SEG_QUADTO</code> or
+ * <code>SEG_CUBICTO</code> segment is approximated by at most
+ * 2<sup><small>10</small></sup> = 1024 straight lines.
+ */
+ public FlatteningPathIterator(PathIterator src, double flatness)
+ {
+ this(src, flatness, 10);
+ }
+
+
+ /**
+ * Constructs a new PathIterator for approximating an input
+ * PathIterator with straight lines. The approximation works by
+ * recursive subdivisons, until the specified flatness threshold is
+ * not exceeded. Additionally, the number of recursions is also
+ * bound by the specified recursion limit.
+ */
+ public FlatteningPathIterator(PathIterator src, double flatness,
+ int limit)
+ {
+ if (flatness < 0 || limit < 0)
+ throw new IllegalArgumentException();
+
+ srcIter = src;
+ flatnessSq = flatness * flatness;
+ recursionLimit = limit;
+ fetchSegment();
+ }
+
+
+ /**
+ * Returns the maximally acceptable flatness.
+ *
+ * @see QuadCurve2D#getFlatness()
+ * @see CubicCurve2D#getFlatness()
+ */
+ public double getFlatness()
+ {
+ return Math.sqrt(flatnessSq);
+ }
+
+
+ /**
+ * Returns the maximum number of recursive curve subdivisions.
+ */
+ public int getRecursionLimit()
+ {
+ return recursionLimit;
+ }
+
+
+ // Documentation will be copied from PathIterator.
+ public int getWindingRule()
+ {
+ return srcIter.getWindingRule();
+ }
+
+
+ // Documentation will be copied from PathIterator.
+ public boolean isDone()
+ {
+ return done;
+ }
+
+
+ // Documentation will be copied from PathIterator.
+ public void next()
+ {
+ if (stackSize > 0)
+ {
+ --stackSize;
+ if (stackSize > 0)
+ {
+ switch (srcSegType)
+ {
+ case PathIterator.SEG_QUADTO:
+ subdivideQuadratic();
+ return;
+
+ case PathIterator.SEG_CUBICTO:
+ subdivideCubic();
+ return;
+
+ default:
+ throw new IllegalStateException();
+ }
+ }
+ }
+
+ srcIter.next();
+ fetchSegment();
+ }
+
+
+ // Documentation will be copied from PathIterator.
+ public int currentSegment(double[] coords)
+ {
+ if (done)
+ throw new NoSuchElementException();
+
+ switch (srcSegType)
+ {
+ case PathIterator.SEG_CLOSE:
+ return srcSegType;
+
+ case PathIterator.SEG_MOVETO:
+ case PathIterator.SEG_LINETO:
+ coords[0] = srcPosX;
+ coords[1] = srcPosY;
+ return srcSegType;
+
+ case PathIterator.SEG_QUADTO:
+ if (stackSize == 0)
+ {
+ coords[0] = srcPosX;
+ coords[1] = srcPosY;
+ }
+ else
+ {
+ int sp = stack.length - 4 * stackSize;
+ coords[0] = stack[sp + 2];
+ coords[1] = stack[sp + 3];
+ }
+ return PathIterator.SEG_LINETO;
+
+ case PathIterator.SEG_CUBICTO:
+ if (stackSize == 0)
+ {
+ coords[0] = srcPosX;
+ coords[1] = srcPosY;
+ }
+ else
+ {
+ int sp = stack.length - 6 * stackSize;
+ coords[0] = stack[sp + 4];
+ coords[1] = stack[sp + 5];
+ }
+ return PathIterator.SEG_LINETO;
+ }
+
+ throw new IllegalStateException();
+ }
+
+
+ // Documentation will be copied from PathIterator.
+ public int currentSegment(float[] coords)
+ {
+ if (done)
+ throw new NoSuchElementException();
+
+ switch (srcSegType)
+ {
+ case PathIterator.SEG_CLOSE:
+ return srcSegType;
+
+ case PathIterator.SEG_MOVETO:
+ case PathIterator.SEG_LINETO:
+ coords[0] = (float) srcPosX;
+ coords[1] = (float) srcPosY;
+ return srcSegType;
+
+ case PathIterator.SEG_QUADTO:
+ if (stackSize == 0)
+ {
+ coords[0] = (float) srcPosX;
+ coords[1] = (float) srcPosY;
+ }
+ else
+ {
+ int sp = stack.length - 4 * stackSize;
+ coords[0] = (float) stack[sp + 2];
+ coords[1] = (float) stack[sp + 3];
+ }
+ return PathIterator.SEG_LINETO;
+
+ case PathIterator.SEG_CUBICTO:
+ if (stackSize == 0)
+ {
+ coords[0] = (float) srcPosX;
+ coords[1] = (float) srcPosY;
+ }
+ else
+ {
+ int sp = stack.length - 6 * stackSize;
+ coords[0] = (float) stack[sp + 4];
+ coords[1] = (float) stack[sp + 5];
+ }
+ return PathIterator.SEG_LINETO;
+ }
+
+ throw new IllegalStateException();
+ }
+
+
+ /**
+ * Fetches the next segment from the source iterator.
+ */
+ private void fetchSegment()
+ {
+ int sp;
+
+ if (srcIter.isDone())
+ {
+ done = true;
+ return;
+ }
+
+ srcSegType = srcIter.currentSegment(scratch);
+
+ switch (srcSegType)
+ {
+ case PathIterator.SEG_CLOSE:
+ return;
+
+ case PathIterator.SEG_MOVETO:
+ case PathIterator.SEG_LINETO:
+ srcPosX = scratch[0];
+ srcPosY = scratch[1];
+ return;
+
+ case PathIterator.SEG_QUADTO:
+ if (recursionLimit == 0)
+ {
+ srcPosX = scratch[2];
+ srcPosY = scratch[3];
+ stackSize = 0;
+ return;
+ }
+ sp = 4 * recursionLimit;
+ stackSize = 1;
+ if (stack == null)
+ {
+ stack = new double[sp + /* 4 + 2 */ 6];
+ recLevel = new int[recursionLimit + 1];
+ }
+ recLevel[0] = 0;
+ stack[sp] = srcPosX; // P1.x
+ stack[sp + 1] = srcPosY; // P1.y
+ stack[sp + 2] = scratch[0]; // C.x
+ stack[sp + 3] = scratch[1]; // C.y
+ srcPosX = stack[sp + 4] = scratch[2]; // P2.x
+ srcPosY = stack[sp + 5] = scratch[3]; // P2.y
+ subdivideQuadratic();
+ break;
+
+ case PathIterator.SEG_CUBICTO:
+ if (recursionLimit == 0)
+ {
+ srcPosX = scratch[4];
+ srcPosY = scratch[5];
+ stackSize = 0;
+ return;
+ }
+ sp = 6 * recursionLimit;
+ stackSize = 1;
+ if ((stack == null) || (stack.length < sp + 8))
+ {
+ stack = new double[sp + /* 6 + 2 */ 8];
+ recLevel = new int[recursionLimit + 1];
+ }
+ recLevel[0] = 0;
+ stack[sp] = srcPosX; // P1.x
+ stack[sp + 1] = srcPosY; // P1.y
+ stack[sp + 2] = scratch[0]; // C1.x
+ stack[sp + 3] = scratch[1]; // C1.y
+ stack[sp + 4] = scratch[2]; // C2.x
+ stack[sp + 5] = scratch[3]; // C2.y
+ srcPosX = stack[sp + 6] = scratch[4]; // P2.x
+ srcPosY = stack[sp + 7] = scratch[5]; // P2.y
+ subdivideCubic();
+ return;
+ }
+ }
+
+
+ /**
+ * Repeatedly subdivides the quadratic curve segment that is on top
+ * of the stack. The iteration terminates when the recursion limit
+ * has been reached, or when the resulting segment is flat enough.
+ */
+ private void subdivideQuadratic()
+ {
+ int sp;
+ int level;
+
+ sp = stack.length - 4 * stackSize - 2;
+ level = recLevel[stackSize - 1];
+ while ((level < recursionLimit)
+ && (QuadCurve2D.getFlatnessSq(stack, sp) >= flatnessSq))
+ {
+ recLevel[stackSize] = recLevel[stackSize - 1] = ++level;
+ QuadCurve2D.subdivide(stack, sp, stack, sp - 4, stack, sp);
+ ++stackSize;
+ sp -= 4;
+ }
+ }
+
+
+ /**
+ * Repeatedly subdivides the cubic curve segment that is on top
+ * of the stack. The iteration terminates when the recursion limit
+ * has been reached, or when the resulting segment is flat enough.
+ */
+ private void subdivideCubic()
+ {
+ int sp;
+ int level;
+
+ sp = stack.length - 6 * stackSize - 2;
+ level = recLevel[stackSize - 1];
+ while ((level < recursionLimit)
+ && (CubicCurve2D.getFlatnessSq(stack, sp) >= flatnessSq))
+ {
+ recLevel[stackSize] = recLevel[stackSize - 1] = ++level;
+
+ CubicCurve2D.subdivide(stack, sp, stack, sp - 6, stack, sp);
+ ++stackSize;
+ sp -= 6;
+ }
+ }
+
+
+ /* These routines were useful for debugging. Since they would
+ * just bloat the implementation, they are commented out.
+ *
+ *
+
+ private static String segToString(int segType, double[] d, int offset)
+ {
+ String s;
+
+ switch (segType)
+ {
+ case PathIterator.SEG_CLOSE:
+ return "SEG_CLOSE";
+
+ case PathIterator.SEG_MOVETO:
+ return "SEG_MOVETO (" + d[offset] + ", " + d[offset + 1] + ")";
+
+ case PathIterator.SEG_LINETO:
+ return "SEG_LINETO (" + d[offset] + ", " + d[offset + 1] + ")";
+
+ case PathIterator.SEG_QUADTO:
+ return "SEG_QUADTO (" + d[offset] + ", " + d[offset + 1]
+ + ") (" + d[offset + 2] + ", " + d[offset + 3] + ")";
+
+ case PathIterator.SEG_CUBICTO:
+ return "SEG_CUBICTO (" + d[offset] + ", " + d[offset + 1]
+ + ") (" + d[offset + 2] + ", " + d[offset + 3]
+ + ") (" + d[offset + 4] + ", " + d[offset + 5] + ")";
+ }
+
+ throw new IllegalStateException();
+ }
+
+
+ private void dumpQuadraticStack(String msg)
+ {
+ int sp = stack.length - 4 * stackSize - 2;
+ int i = 0;
+ System.err.print(" " + msg + ":");
+ while (sp < stack.length)
+ {
+ System.err.print(" (" + stack[sp] + ", " + stack[sp+1] + ")");
+ if (i < recLevel.length)
+ System.out.print("/" + recLevel[i++]);
+ if (sp + 3 < stack.length)
+ System.err.print(" [" + stack[sp+2] + ", " + stack[sp+3] + "]");
+ sp += 4;
+ }
+ System.err.println();
+ }
+
+
+ private void dumpCubicStack(String msg)
+ {
+ int sp = stack.length - 6 * stackSize - 2;
+ int i = 0;
+ System.err.print(" " + msg + ":");
+ while (sp < stack.length)
+ {
+ System.err.print(" (" + stack[sp] + ", " + stack[sp+1] + ")");
+ if (i < recLevel.length)
+ System.out.print("/" + recLevel[i++]);
+ if (sp + 3 < stack.length)
+ {
+ System.err.print(" [" + stack[sp+2] + ", " + stack[sp+3] + "]");
+ System.err.print(" [" + stack[sp+4] + ", " + stack[sp+5] + "]");
+ }
+ sp += 6;
+ }
+ System.err.println();
+ }
+
+ *
+ *
+ */
+}
diff --git a/libjava/classpath/java/awt/geom/GeneralPath.java b/libjava/classpath/java/awt/geom/GeneralPath.java
new file mode 100644
index 0000000..f5485587
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/GeneralPath.java
@@ -0,0 +1,958 @@
+/* GeneralPath.java -- represents a shape built from subpaths
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+
+/**
+ * A general geometric path, consisting of any number of subpaths
+ * constructed out of straight lines and cubic or quadratic Bezier
+ * curves.
+ *
+ * <p>The inside of the curve is defined for drawing purposes by a winding
+ * rule. Either the WIND_EVEN_ODD or WIND_NON_ZERO winding rule can be chosen.
+ *
+ * <p><img src="doc-files/GeneralPath-1.png" width="300" height="210"
+ * alt="A drawing of a GeneralPath" />
+ * <p>The EVEN_ODD winding rule defines a point as inside a path if:
+ * A ray from the point towards infinity in an arbitrary direction
+ * intersects the path an odd number of times. Points <b>A</b> and
+ * <b>C</b> in the image are considered to be outside the path.
+ * (both intersect twice)
+ * Point <b>B</b> intersects once, and is inside.
+ *
+ * <p>The NON_ZERO winding rule defines a point as inside a path if:
+ * The path intersects the ray in an equal number of opposite directions.
+ * Point <b>A</b> in the image is outside (one intersection in the
+ * &#x2019;up&#x2019;
+ * direction, one in the &#x2019;down&#x2019; direction) Point <b>B</b> in
+ * the image is inside (one intersection &#x2019;down&#x2019;)
+ * Point <b>C</b> in the image is outside (two intersections
+ * &#x2019;down&#x2019;)
+ *
+ * @see Line2D
+ * @see CubicCurve2D
+ * @see QuadCurve2D
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Sven de Marothy (sven@physto.se)
+ *
+ * @since 1.2
+ */
+public final class GeneralPath implements Shape, Cloneable
+{
+ public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
+ public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
+
+ /** Initial size if not specified. */
+ private static final int INIT_SIZE = 10;
+
+ /** A big number, but not so big it can't survive a few float operations */
+ private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
+
+ /** The winding rule.
+ * This is package-private to avoid an accessor method.
+ */
+ int rule;
+
+ /**
+ * The path type in points. Note that xpoints[index] and ypoints[index] maps
+ * to types[index]; the control points of quad and cubic paths map as
+ * well but are ignored.
+ * This is package-private to avoid an accessor method.
+ */
+ byte[] types;
+
+ /**
+ * The list of all points seen. Since you can only append floats, it makes
+ * sense for these to be float[]. I have no idea why Sun didn't choose to
+ * allow a general path of double precision points.
+ * Note: Storing x and y coords seperately makes for a slower transforms,
+ * But it speeds up and simplifies box-intersection checking a lot.
+ * These are package-private to avoid accessor methods.
+ */
+ float[] xpoints;
+ float[] ypoints;
+
+ /** The index of the most recent moveto point, or null. */
+ private int subpath = -1;
+
+ /** The next available index into points.
+ * This is package-private to avoid an accessor method.
+ */
+ int index;
+
+ /**
+ * Constructs a GeneralPath with the default (NON_ZERO)
+ * winding rule and initial capacity (20).
+ */
+ public GeneralPath()
+ {
+ this(WIND_NON_ZERO, INIT_SIZE);
+ }
+
+ /**
+ * Constructs a GeneralPath with a specific winding rule
+ * and the default initial capacity (20).
+ * @param rule the winding rule (WIND_NON_ZERO or WIND_EVEN_ODD)
+ */
+ public GeneralPath(int rule)
+ {
+ this(rule, INIT_SIZE);
+ }
+
+ /**
+ * Constructs a GeneralPath with a specific winding rule
+ * and the initial capacity. The initial capacity should be
+ * the approximate number of path segments to be used.
+ * @param rule the winding rule (WIND_NON_ZERO or WIND_EVEN_ODD)
+ * @param capacity the inital capacity, in path segments
+ */
+ public GeneralPath(int rule, int capacity)
+ {
+ if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO)
+ throw new IllegalArgumentException();
+ this.rule = rule;
+ if (capacity < INIT_SIZE)
+ capacity = INIT_SIZE;
+ types = new byte[capacity];
+ xpoints = new float[capacity];
+ ypoints = new float[capacity];
+ }
+
+ /**
+ * Constructs a GeneralPath from an arbitrary shape object.
+ * The Shapes PathIterator path and winding rule will be used.
+ * @param s the shape
+ */
+ public GeneralPath(Shape s)
+ {
+ types = new byte[INIT_SIZE];
+ xpoints = new float[INIT_SIZE];
+ ypoints = new float[INIT_SIZE];
+ PathIterator pi = s.getPathIterator(null);
+ setWindingRule(pi.getWindingRule());
+ append(pi, false);
+ }
+
+ /**
+ * Adds a new point to a path.
+ */
+ public void moveTo(float x, float y)
+ {
+ subpath = index;
+ ensureSize(index + 1);
+ types[index] = PathIterator.SEG_MOVETO;
+ xpoints[index] = x;
+ ypoints[index++] = y;
+ }
+
+ /**
+ * Appends a straight line to the current path.
+ * @param x x coordinate of the line endpoint.
+ * @param y y coordinate of the line endpoint.
+ */
+ public void lineTo(float x, float y)
+ {
+ ensureSize(index + 1);
+ types[index] = PathIterator.SEG_LINETO;
+ xpoints[index] = x;
+ ypoints[index++] = y;
+ }
+
+ /**
+ * Appends a quadratic Bezier curve to the current path.
+ * @param x1 x coordinate of the control point
+ * @param y1 y coordinate of the control point
+ * @param x2 x coordinate of the curve endpoint.
+ * @param y2 y coordinate of the curve endpoint.
+ */
+ public void quadTo(float x1, float y1, float x2, float y2)
+ {
+ ensureSize(index + 2);
+ types[index] = PathIterator.SEG_QUADTO;
+ xpoints[index] = x1;
+ ypoints[index++] = y1;
+ xpoints[index] = x2;
+ ypoints[index++] = y2;
+ }
+
+ /**
+ * Appends a cubic Bezier curve to the current path.
+ * @param x1 x coordinate of the first control point
+ * @param y1 y coordinate of the first control point
+ * @param x2 x coordinate of the second control point
+ * @param y2 y coordinate of the second control point
+ * @param x3 x coordinate of the curve endpoint.
+ * @param y3 y coordinate of the curve endpoint.
+ */
+ public void curveTo(float x1, float y1, float x2, float y2, float x3,
+ float y3)
+ {
+ ensureSize(index + 3);
+ types[index] = PathIterator.SEG_CUBICTO;
+ xpoints[index] = x1;
+ ypoints[index++] = y1;
+ xpoints[index] = x2;
+ ypoints[index++] = y2;
+ xpoints[index] = x3;
+ ypoints[index++] = y3;
+ }
+
+ /**
+ * Closes the current subpath by drawing a line
+ * back to the point of the last moveTo.
+ */
+ public void closePath()
+ {
+ ensureSize(index + 1);
+ types[index] = PathIterator.SEG_CLOSE;
+ xpoints[index] = xpoints[subpath];
+ ypoints[index++] = ypoints[subpath];
+ }
+
+ /**
+ * Appends the segments of a Shape to the path. If <code>connect</code> is
+ * true, the new path segments are connected to the existing one with a line.
+ * The winding rule of the Shape is ignored.
+ */
+ public void append(Shape s, boolean connect)
+ {
+ append(s.getPathIterator(null), connect);
+ }
+
+ /**
+ * Appends the segments of a PathIterator to this GeneralPath.
+ * Optionally, the initial {@link PathIterator#SEG_MOVETO} segment
+ * of the appended path is changed into a {@link
+ * PathIterator#SEG_LINETO} segment.
+ *
+ * @param iter the PathIterator specifying which segments shall be
+ * appended.
+ *
+ * @param connect <code>true</code> for substituting the initial
+ * {@link PathIterator#SEG_MOVETO} segment by a {@link
+ * PathIterator#SEG_LINETO}, or <code>false</code> for not
+ * performing any substitution. If this GeneralPath is currently
+ * empty, <code>connect</code> is assumed to be <code>false</code>,
+ * thus leaving the initial {@link PathIterator#SEG_MOVETO}
+ * unchanged.
+ */
+ public void append(PathIterator iter, boolean connect)
+ {
+ // A bad implementation of this method had caused Classpath bug #6076.
+ float[] f = new float[6];
+ while (! iter.isDone())
+ {
+ switch (iter.currentSegment(f))
+ {
+ case PathIterator.SEG_MOVETO:
+ if (! connect || (index == 0))
+ {
+ moveTo(f[0], f[1]);
+ break;
+ }
+ if ((index >= 1) && (types[index - 1] == PathIterator.SEG_CLOSE)
+ && (f[0] == xpoints[index - 1])
+ && (f[1] == ypoints[index - 1]))
+ break;
+
+ // Fall through.
+ case PathIterator.SEG_LINETO:
+ lineTo(f[0], f[1]);
+ break;
+ case PathIterator.SEG_QUADTO:
+ quadTo(f[0], f[1], f[2], f[3]);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ curveTo(f[0], f[1], f[2], f[3], f[4], f[5]);
+ break;
+ case PathIterator.SEG_CLOSE:
+ closePath();
+ break;
+ }
+
+ connect = false;
+ iter.next();
+ }
+ }
+
+ /**
+ * Returns the path&#x2019;s current winding rule.
+ */
+ public int getWindingRule()
+ {
+ return rule;
+ }
+
+ /**
+ * Sets the path&#x2019;s winding rule, which controls which areas are
+ * considered &#x2019;inside&#x2019; or &#x2019;outside&#x2019; the path
+ * on drawing. Valid rules are WIND_EVEN_ODD for an even-odd winding rule,
+ * or WIND_NON_ZERO for a non-zero winding rule.
+ */
+ public void setWindingRule(int rule)
+ {
+ if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO)
+ throw new IllegalArgumentException();
+ this.rule = rule;
+ }
+
+ /**
+ * Returns the current appending point of the path.
+ */
+ public Point2D getCurrentPoint()
+ {
+ if (subpath < 0)
+ return null;
+ return new Point2D.Float(xpoints[index - 1], ypoints[index - 1]);
+ }
+
+ /**
+ * Resets the path. All points and segments are destroyed.
+ */
+ public void reset()
+ {
+ subpath = -1;
+ index = 0;
+ }
+
+ /**
+ * Applies a transform to the path.
+ */
+ public void transform(AffineTransform xform)
+ {
+ double nx;
+ double ny;
+ double[] m = new double[6];
+ xform.getMatrix(m);
+ for (int i = 0; i < index; i++)
+ {
+ nx = m[0] * xpoints[i] + m[2] * ypoints[i] + m[4];
+ ny = m[1] * xpoints[i] + m[3] * ypoints[i] + m[5];
+ xpoints[i] = (float) nx;
+ ypoints[i] = (float) ny;
+ }
+ }
+
+ /**
+ * Creates a transformed version of the path.
+ * @param xform the transform to apply
+ * @return a new transformed GeneralPath
+ */
+ public Shape createTransformedShape(AffineTransform xform)
+ {
+ GeneralPath p = new GeneralPath(this);
+ p.transform(xform);
+ return p;
+ }
+
+ /**
+ * Returns the path&#x2019;s bounding box.
+ */
+ public Rectangle getBounds()
+ {
+ return getBounds2D().getBounds();
+ }
+
+ /**
+ * Returns the path&#x2019;s bounding box, in <code>float</code> precision
+ */
+ public Rectangle2D getBounds2D()
+ {
+ float x1;
+ float y1;
+ float x2;
+ float y2;
+
+ if (index > 0)
+ {
+ x1 = x2 = xpoints[0];
+ y1 = y2 = ypoints[0];
+ }
+ else
+ x1 = x2 = y1 = y2 = 0.0f;
+
+ for (int i = 0; i < index; i++)
+ {
+ x1 = Math.min(xpoints[i], x1);
+ y1 = Math.min(ypoints[i], y1);
+ x2 = Math.max(xpoints[i], x2);
+ y2 = Math.max(ypoints[i], y2);
+ }
+ return (new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1));
+ }
+
+ /**
+ * Evaluates if a point is within the GeneralPath,
+ * The NON_ZERO winding rule is used, regardless of the
+ * set winding rule.
+ * @param x x coordinate of the point to evaluate
+ * @param y y coordinate of the point to evaluate
+ * @return true if the point is within the path, false otherwise
+ */
+ public boolean contains(double x, double y)
+ {
+ return (getWindingNumber(x, y) != 0);
+ }
+
+ /**
+ * Evaluates if a Point2D is within the GeneralPath,
+ * The NON_ZERO winding rule is used, regardless of the
+ * set winding rule.
+ * @param p The Point2D to evaluate
+ * @return true if the point is within the path, false otherwise
+ */
+ public boolean contains(Point2D p)
+ {
+ return contains(p.getX(), p.getY());
+ }
+
+ /**
+ * Evaluates if a rectangle is completely contained within the path.
+ * This method will return false in the cases when the box
+ * intersects an inner segment of the path.
+ * (i.e.: The method is accurate for the EVEN_ODD winding rule)
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ if (! getBounds2D().intersects(x, y, w, h))
+ return false;
+
+ /* Does any edge intersect? */
+ if (getAxisIntersections(x, y, false, w) != 0 /* top */
+ || getAxisIntersections(x, y + h, false, w) != 0 /* bottom */
+ || getAxisIntersections(x + w, y, true, h) != 0 /* right */
+ || getAxisIntersections(x, y, true, h) != 0) /* left */
+ return false;
+
+ /* No intersections, is any point inside? */
+ if (getWindingNumber(x, y) != 0)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Evaluates if a rectangle is completely contained within the path.
+ * This method will return false in the cases when the box
+ * intersects an inner segment of the path.
+ * (i.e.: The method is accurate for the EVEN_ODD winding rule)
+ * @param r the rectangle
+ * @return <code>true</code> if the rectangle is completely contained
+ * within the path, <code>false</code> otherwise
+ */
+ public boolean contains(Rectangle2D r)
+ {
+ return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Evaluates if a rectangle intersects the path.
+ * @param x x coordinate of the rectangle
+ * @param y y coordinate of the rectangle
+ * @param w width of the rectangle
+ * @param h height of the rectangle
+ * @return <code>true</code> if the rectangle intersects the path,
+ * <code>false</code> otherwise
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ /* Does any edge intersect? */
+ if (getAxisIntersections(x, y, false, w) != 0 /* top */
+ || getAxisIntersections(x, y + h, false, w) != 0 /* bottom */
+ || getAxisIntersections(x + w, y, true, h) != 0 /* right */
+ || getAxisIntersections(x, y, true, h) != 0) /* left */
+ return true;
+
+ /* No intersections, is any point inside? */
+ if (getWindingNumber(x, y) != 0)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Evaluates if a Rectangle2D intersects the path.
+ * @param r The rectangle
+ * @return <code>true</code> if the rectangle intersects the path,
+ * <code>false</code> otherwise
+ */
+ public boolean intersects(Rectangle2D r)
+ {
+ return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * A PathIterator that iterates over the segments of a GeneralPath.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ private static class GeneralPathIterator implements PathIterator
+ {
+ /**
+ * The number of coordinate values for each segment type.
+ */
+ private static final int[] NUM_COORDS = {
+ /* 0: SEG_MOVETO */ 1,
+ /* 1: SEG_LINETO */ 1,
+ /* 2: SEG_QUADTO */ 2,
+ /* 3: SEG_CUBICTO */ 3,
+ /* 4: SEG_CLOSE */ 0};
+
+ /**
+ * The GeneralPath whose segments are being iterated.
+ * This is package-private to avoid an accessor method.
+ */
+ final GeneralPath path;
+
+ /**
+ * The affine transformation used to transform coordinates.
+ */
+ private final AffineTransform transform;
+
+ /**
+ * The current position of the iterator.
+ */
+ private int pos;
+
+ /**
+ * Constructs a new iterator for enumerating the segments of a
+ * GeneralPath.
+ *
+ * @param at an affine transformation for projecting the returned
+ * points, or <code>null</code> to return the original points
+ * without any mapping.
+ */
+ GeneralPathIterator(GeneralPath path, AffineTransform transform)
+ {
+ this.path = path;
+ this.transform = transform;
+ }
+
+ /**
+ * Returns the current winding rule of the GeneralPath.
+ */
+ public int getWindingRule()
+ {
+ return path.rule;
+ }
+
+ /**
+ * Determines whether the iterator has reached the last segment in
+ * the path.
+ */
+ public boolean isDone()
+ {
+ return pos >= path.index;
+ }
+
+ /**
+ * Advances the iterator position by one segment.
+ */
+ public void next()
+ {
+ int seg;
+
+ /*
+ * Increment pos by the number of coordinate pairs.
+ */
+ seg = path.types[pos];
+ if (seg == SEG_CLOSE)
+ pos++;
+ else
+ pos += NUM_COORDS[seg];
+ }
+
+ /**
+ * Returns the current segment in float coordinates.
+ */
+ public int currentSegment(float[] coords)
+ {
+ int seg;
+ int numCoords;
+
+ seg = path.types[pos];
+ numCoords = NUM_COORDS[seg];
+ if (numCoords > 0)
+ {
+ for (int i = 0; i < numCoords; i++)
+ {
+ coords[i << 1] = path.xpoints[pos + i];
+ coords[(i << 1) + 1] = path.ypoints[pos + i];
+ }
+
+ if (transform != null)
+ transform.transform( /* src */
+ coords, /* srcOffset */
+ 0, /* dest */ coords, /* destOffset */
+ 0, /* numPoints */ numCoords);
+ }
+ return seg;
+ }
+
+ /**
+ * Returns the current segment in double coordinates.
+ */
+ public int currentSegment(double[] coords)
+ {
+ int seg;
+ int numCoords;
+
+ seg = path.types[pos];
+ numCoords = NUM_COORDS[seg];
+ if (numCoords > 0)
+ {
+ for (int i = 0; i < numCoords; i++)
+ {
+ coords[i << 1] = (double) path.xpoints[pos + i];
+ coords[(i << 1) + 1] = (double) path.ypoints[pos + i];
+ }
+ if (transform != null)
+ transform.transform( /* src */
+ coords, /* srcOffset */
+ 0, /* dest */ coords, /* destOffset */
+ 0, /* numPoints */ numCoords);
+ }
+ return seg;
+ }
+ }
+
+ /**
+ * Creates a PathIterator for iterating along the segments of the path.
+ *
+ * @param at an affine transformation for projecting the returned
+ * points, or <code>null</code> to let the created iterator return
+ * the original points without any mapping.
+ */
+ public PathIterator getPathIterator(AffineTransform at)
+ {
+ return new GeneralPathIterator(this, at);
+ }
+
+ /**
+ * Creates a new FlatteningPathIterator for the path
+ */
+ public PathIterator getPathIterator(AffineTransform at, double flatness)
+ {
+ return new FlatteningPathIterator(getPathIterator(at), flatness);
+ }
+
+ /**
+ * Creates a new shape of the same run-time type with the same contents
+ * as this one.
+ *
+ * @return the clone
+ *
+ * @exception OutOfMemoryError If there is not enough memory available.
+ *
+ * @since 1.2
+ */
+ public Object clone()
+ {
+ // This class is final; no need to use super.clone().
+ return new GeneralPath(this);
+ }
+
+ /**
+ * Helper method - ensure the size of the data arrays,
+ * otherwise, reallocate new ones twice the size
+ */
+ private void ensureSize(int size)
+ {
+ if (subpath < 0)
+ throw new IllegalPathStateException("need initial moveto");
+ if (size <= xpoints.length)
+ return;
+ byte[] b = new byte[types.length << 1];
+ System.arraycopy(types, 0, b, 0, index);
+ types = b;
+ float[] f = new float[xpoints.length << 1];
+ System.arraycopy(xpoints, 0, f, 0, index);
+ xpoints = f;
+ f = new float[ypoints.length << 1];
+ System.arraycopy(ypoints, 0, f, 0, index);
+ ypoints = f;
+ }
+
+ /**
+ * Helper method - Get the total number of intersections from (x,y) along
+ * a given axis, within a given distance.
+ */
+ private int getAxisIntersections(double x, double y, boolean useYaxis,
+ double distance)
+ {
+ return (evaluateCrossings(x, y, false, useYaxis, distance));
+ }
+
+ /**
+ * Helper method - returns the winding number of a point.
+ */
+ private int getWindingNumber(double x, double y)
+ {
+ /* Evaluate the crossings from x,y to infinity on the y axis (arbitrary
+ choice). Note that we don't actually use Double.INFINITY, since that's
+ slower, and may cause problems. */
+ return (evaluateCrossings(x, y, true, true, BIG_VALUE));
+ }
+
+ /**
+ * Helper method - evaluates the number of intersections on an axis from
+ * the point (x,y) to the point (x,y+distance) or (x+distance,y).
+ * @param x x coordinate.
+ * @param y y coordinate.
+ * @param neg True if opposite-directed intersections should cancel,
+ * false to sum all intersections.
+ * @param useYaxis Use the Y axis, false uses the X axis.
+ * @param distance Interval from (x,y) on the selected axis to find
+ * intersections.
+ */
+ private int evaluateCrossings(double x, double y, boolean neg,
+ boolean useYaxis, double distance)
+ {
+ float cx = 0.0f;
+ float cy = 0.0f;
+ float firstx = 0.0f;
+ float firsty = 0.0f;
+
+ int negative = (neg) ? -1 : 1;
+ double x0;
+ double x1;
+ double x2;
+ double x3;
+ double y0;
+ double y1;
+ double y2;
+ double y3;
+ double[] r = new double[4];
+ int nRoots;
+ double epsilon = 0.0;
+ int pos = 0;
+ int windingNumber = 0;
+ boolean pathStarted = false;
+
+ if (index == 0)
+ return (0);
+ if (useYaxis)
+ {
+ float[] swap1;
+ swap1 = ypoints;
+ ypoints = xpoints;
+ xpoints = swap1;
+ double swap2;
+ swap2 = y;
+ y = x;
+ x = swap2;
+ }
+
+ /* Get a value which is hopefully small but not insignificant relative
+ the path. */
+ epsilon = ypoints[0] * 1E-7;
+
+ if(epsilon == 0)
+ epsilon = 1E-7;
+
+ pos = 0;
+ while (pos < index)
+ {
+ switch (types[pos])
+ {
+ case PathIterator.SEG_MOVETO:
+ if (pathStarted) // close old path
+ {
+ x0 = cx;
+ y0 = cy;
+ x1 = firstx;
+ y1 = firsty;
+
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y1 == 0.0)
+ y1 -= epsilon;
+ if (Line2D.linesIntersect(x0, y0, x1, y1,
+ epsilon, 0.0, distance, 0.0))
+ windingNumber += (y1 < y0) ? 1 : negative;
+
+ cx = firstx;
+ cy = firsty;
+ }
+ cx = firstx = xpoints[pos] - (float) x;
+ cy = firsty = ypoints[pos++] - (float) y;
+ pathStarted = true;
+ break;
+ case PathIterator.SEG_CLOSE:
+ x0 = cx;
+ y0 = cy;
+ x1 = firstx;
+ y1 = firsty;
+
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y1 == 0.0)
+ y1 -= epsilon;
+ if (Line2D.linesIntersect(x0, y0, x1, y1,
+ epsilon, 0.0, distance, 0.0))
+ windingNumber += (y1 < y0) ? 1 : negative;
+
+ cx = firstx;
+ cy = firsty;
+ pos++;
+ pathStarted = false;
+ break;
+ case PathIterator.SEG_LINETO:
+ x0 = cx;
+ y0 = cy;
+ x1 = xpoints[pos] - (float) x;
+ y1 = ypoints[pos++] - (float) y;
+
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y1 == 0.0)
+ y1 -= epsilon;
+ if (Line2D.linesIntersect(x0, y0, x1, y1,
+ epsilon, 0.0, distance, 0.0))
+ windingNumber += (y1 < y0) ? 1 : negative;
+
+ cx = xpoints[pos - 1] - (float) x;
+ cy = ypoints[pos - 1] - (float) y;
+ break;
+ case PathIterator.SEG_QUADTO:
+ x0 = cx;
+ y0 = cy;
+ x1 = xpoints[pos] - x;
+ y1 = ypoints[pos++] - y;
+ x2 = xpoints[pos] - x;
+ y2 = ypoints[pos++] - y;
+
+ /* check if curve may intersect X+ axis. */
+ if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0)
+ && (y0 * y1 <= 0 || y1 * y2 <= 0))
+ {
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y2 == 0.0)
+ y2 -= epsilon;
+
+ r[0] = y0;
+ r[1] = 2 * (y1 - y0);
+ r[2] = (y2 - 2 * y1 + y0);
+
+ /* degenerate roots (=tangent points) do not
+ contribute to the winding number. */
+ if ((nRoots = QuadCurve2D.solveQuadratic(r)) == 2)
+ for (int i = 0; i < nRoots; i++)
+ {
+ float t = (float) r[i];
+ if (t > 0.0f && t < 1.0f)
+ {
+ double crossing = t * t * (x2 - 2 * x1 + x0)
+ + 2 * t * (x1 - x0) + x0;
+ if (crossing >= 0.0 && crossing <= distance)
+ windingNumber += (2 * t * (y2 - 2 * y1 + y0)
+ + 2 * (y1 - y0) < 0) ? 1 : negative;
+ }
+ }
+ }
+
+ cx = xpoints[pos - 1] - (float) x;
+ cy = ypoints[pos - 1] - (float) y;
+ break;
+ case PathIterator.SEG_CUBICTO:
+ x0 = cx;
+ y0 = cy;
+ x1 = xpoints[pos] - x;
+ y1 = ypoints[pos++] - y;
+ x2 = xpoints[pos] - x;
+ y2 = ypoints[pos++] - y;
+ x3 = xpoints[pos] - x;
+ y3 = ypoints[pos++] - y;
+
+ /* check if curve may intersect X+ axis. */
+ if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0 || x3 > 0.0)
+ && (y0 * y1 <= 0 || y1 * y2 <= 0 || y2 * y3 <= 0))
+ {
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y3 == 0.0)
+ y3 -= epsilon;
+
+ r[0] = y0;
+ r[1] = 3 * (y1 - y0);
+ r[2] = 3 * (y2 + y0 - 2 * y1);
+ r[3] = y3 - 3 * y2 + 3 * y1 - y0;
+
+ if ((nRoots = CubicCurve2D.solveCubic(r)) != 0)
+ for (int i = 0; i < nRoots; i++)
+ {
+ float t = (float) r[i];
+ if (t > 0.0 && t < 1.0)
+ {
+ double crossing = -(t * t * t) * (x0 - 3 * x1
+ + 3 * x2 - x3)
+ + 3 * t * t * (x0 - 2 * x1 + x2)
+ + 3 * t * (x1 - x0) + x0;
+ if (crossing >= 0 && crossing <= distance)
+ windingNumber += (3 * t * t * (y3 + 3 * y1
+ - 3 * y2 - y0)
+ + 6 * t * (y0 - 2 * y1 + y2)
+ + 3 * (y1 - y0) < 0) ? 1 : negative;
+ }
+ }
+ }
+
+ cx = xpoints[pos - 1] - (float) x;
+ cy = ypoints[pos - 1] - (float) y;
+ break;
+ }
+ }
+
+ // swap coordinates back
+ if (useYaxis)
+ {
+ float[] swap;
+ swap = ypoints;
+ ypoints = xpoints;
+ xpoints = swap;
+ }
+ return (windingNumber);
+ }
+} // class GeneralPath
+
diff --git a/libjava/classpath/java/awt/geom/IllegalPathStateException.java b/libjava/classpath/java/awt/geom/IllegalPathStateException.java
new file mode 100644
index 0000000..4d190c7
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/IllegalPathStateException.java
@@ -0,0 +1,71 @@
+/* IllegalPathStateException.java -- an operation was in an illegal path state
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+/**
+ * Thrown when an operation on a path is in an illegal state, such as appending
+ * a segment to a <code>GeneralPath</code> without an initial moveto.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @see GeneralPath
+ * @status updated to 1.4
+ */
+public class IllegalPathStateException extends RuntimeException
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = -5158084205220481094L;
+
+ /**
+ * Create an exception with no message.
+ */
+ public IllegalPathStateException()
+ {
+ }
+
+ /**
+ * Create an exception with a message.
+ *
+ * @param msg the message
+ */
+ public IllegalPathStateException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/classpath/java/awt/geom/Line2D.java b/libjava/classpath/java/awt/geom/Line2D.java
new file mode 100644
index 0000000..e15e7cf
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/Line2D.java
@@ -0,0 +1,1182 @@
+/* Line2D.java -- represents a line in 2-D space, plus operations on a line
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+/**
+ * Represents a directed line bewteen two points in (x,y) Cartesian space.
+ * Remember, on-screen graphics have increasing x from left-to-right, and
+ * increasing y from top-to-bottom. The storage is left to subclasses.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author David Gilbert
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public abstract class Line2D implements Shape, Cloneable
+{
+ /**
+ * The default constructor.
+ */
+ protected Line2D()
+ {
+ }
+
+ /**
+ * Return the x coordinate of the first point.
+ *
+ * @return the starting x coordinate
+ */
+ public abstract double getX1();
+
+ /**
+ * Return the y coordinate of the first point.
+ *
+ * @return the starting y coordinate
+ */
+ public abstract double getY1();
+
+ /**
+ * Return the first point.
+ *
+ * @return the starting point
+ */
+ public abstract Point2D getP1();
+
+ /**
+ * Return the x coordinate of the second point.
+ *
+ * @return the ending x coordinate
+ */
+ public abstract double getX2();
+
+ /**
+ * Return the y coordinate of the second point.
+ *
+ * @return the ending y coordinate
+ */
+ public abstract double getY2();
+
+ /**
+ * Return the second point.
+ *
+ * @return the ending point
+ */
+ public abstract Point2D getP2();
+
+ /**
+ * Set the coordinates of the line to the given coordinates. Loss of
+ * precision may occur due to rounding issues.
+ *
+ * @param x1 the first x coordinate
+ * @param y1 the first y coordinate
+ * @param x2 the second x coordinate
+ * @param y2 the second y coordinate
+ */
+ public abstract void setLine(double x1, double y1, double x2, double y2);
+
+ /**
+ * Set the coordinates to the given points.
+ *
+ * @param p1 the first point
+ * @param p2 the second point
+ * @throws NullPointerException if either point is null
+ */
+ public void setLine(Point2D p1, Point2D p2)
+ {
+ setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+ }
+
+ /**
+ * Set the coordinates to those of the given line.
+ *
+ * @param l the line to copy
+ * @throws NullPointerException if l is null
+ */
+ public void setLine(Line2D l)
+ {
+ setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
+ }
+
+ /**
+ * Computes the relative rotation direction needed to pivot the line about
+ * the first point in order to have the second point colinear with point p.
+ * Because of floating point rounding, don't expect this to be a perfect
+ * measure of colinearity. The answer is 1 if the line has a shorter rotation
+ * in the direction of the positive X axis to the negative Y axis
+ * (counter-clockwise in the default Java coordinate system), or -1 if the
+ * shortest rotation is in the opposite direction (clockwise). If p
+ * is already colinear, the return value is -1 if it lies beyond the first
+ * point, 0 if it lies in the segment, or 1 if it lies beyond the second
+ * point. If the first and second point are coincident, this returns 0.
+ *
+ * @param x1 the first x coordinate
+ * @param y1 the first y coordinate
+ * @param x2 the second x coordinate
+ * @param y2 the second y coordinate
+ * @param px the reference x coordinate
+ * @param py the reference y coordinate
+ * @return the relative rotation direction
+ */
+ public static int relativeCCW(double x1, double y1, double x2, double y2,
+ double px, double py)
+ {
+ if ((x1 == x2 && y1 == y2)
+ || (x1 == px && y1 == py))
+ return 0; // Coincident points.
+ // Translate to the origin.
+ x2 -= x1;
+ y2 -= y1;
+ px -= x1;
+ py -= y1;
+ double slope2 = y2 / x2;
+ double slopep = py / px;
+ if (slope2 == slopep || (x2 == 0 && px == 0))
+ return y2 > 0 // Colinear.
+ ? (py < 0 ? -1 : py > y2 ? 1 : 0)
+ : (py > 0 ? -1 : py < y2 ? 1 : 0);
+ if (x2 >= 0 && slope2 >= 0)
+ return px >= 0 // Quadrant 1.
+ ? (slope2 > slopep ? 1 : -1)
+ : (slope2 < slopep ? 1 : -1);
+ if (y2 > 0)
+ return px < 0 // Quadrant 2.
+ ? (slope2 > slopep ? 1 : -1)
+ : (slope2 < slopep ? 1 : -1);
+ if (slope2 >= 0.0)
+ return px >= 0 // Quadrant 3.
+ ? (slope2 < slopep ? 1 : -1)
+ : (slope2 > slopep ? 1 : -1);
+ return px < 0 // Quadrant 4.
+ ? (slope2 < slopep ? 1 : -1)
+ : (slope2 > slopep ? 1 : -1);
+ }
+
+ /**
+ * Computes the relative rotation direction needed to pivot this line about
+ * the first point in order to have the second point colinear with point p.
+ * Because of floating point rounding, don't expect this to be a perfect
+ * measure of colinearity. The answer is 1 if the line has a shorter rotation
+ * in the direction of the positive X axis to the negative Y axis
+ * (counter-clockwise in the default Java coordinate system), or -1 if the
+ * shortest rotation is in the opposite direction (clockwise). If p
+ * is already colinear, the return value is -1 if it lies beyond the first
+ * point, 0 if it lies in the segment, or 1 if it lies beyond the second
+ * point. If the first and second point are coincident, this returns 0.
+ *
+ * @param px the reference x coordinate
+ * @param py the reference y coordinate
+ * @return the relative rotation direction
+ * @see #relativeCCW(double, double, double, double, double, double)
+ */
+ public int relativeCCW(double px, double py)
+ {
+ return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
+ }
+
+ /**
+ * Computes the relative rotation direction needed to pivot this line about
+ * the first point in order to have the second point colinear with point p.
+ * Because of floating point rounding, don't expect this to be a perfect
+ * measure of colinearity. The answer is 1 if the line has a shorter rotation
+ * in the direction of the positive X axis to the negative Y axis
+ * (counter-clockwise in the default Java coordinate system), or -1 if the
+ * shortest rotation is in the opposite direction (clockwise). If p
+ * is already colinear, the return value is -1 if it lies beyond the first
+ * point, 0 if it lies in the segment, or 1 if it lies beyond the second
+ * point. If the first and second point are coincident, this returns 0.
+ *
+ * @param p the reference point
+ * @return the relative rotation direction
+ * @throws NullPointerException if p is null
+ * @see #relativeCCW(double, double, double, double, double, double)
+ */
+ public int relativeCCW(Point2D p)
+ {
+ return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+ }
+
+ /**
+ * Computes twice the (signed) area of the triangle defined by the three
+ * points. This method is used for intersection testing.
+ *
+ * @param x1 the x-coordinate of the first point.
+ * @param y1 the y-coordinate of the first point.
+ * @param x2 the x-coordinate of the second point.
+ * @param y2 the y-coordinate of the second point.
+ * @param x3 the x-coordinate of the third point.
+ * @param y3 the y-coordinate of the third point.
+ *
+ * @return Twice the area.
+ */
+ private static double area2(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3)
+ {
+ return (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
+ }
+
+ /**
+ * Returns <code>true</code> if (x3, y3) lies between (x1, y1) and (x2, y2),
+ * and false otherwise, This test assumes that the three points are
+ * collinear, and is used for intersection testing.
+ *
+ * @param x1 the x-coordinate of the first point.
+ * @param y1 the y-coordinate of the first point.
+ * @param x2 the x-coordinate of the second point.
+ * @param y2 the y-coordinate of the second point.
+ * @param x3 the x-coordinate of the third point.
+ * @param y3 the y-coordinate of the third point.
+ *
+ * @return A boolean.
+ */
+ private static boolean between(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3)
+ {
+ if (x1 != x2) {
+ return (x1 <= x3 && x3 <= x2) || (x1 >= x3 && x3 >= x2);
+ }
+ else {
+ return (y1 <= y3 && y3 <= y2) || (y1 >= y3 && y3 >= y2);
+ }
+ }
+
+ /**
+ * Test if the line segment (x1,y1)-&gt;(x2,y2) intersects the line segment
+ * (x3,y3)-&gt;(x4,y4).
+ *
+ * @param x1 the first x coordinate of the first segment
+ * @param y1 the first y coordinate of the first segment
+ * @param x2 the second x coordinate of the first segment
+ * @param y2 the second y coordinate of the first segment
+ * @param x3 the first x coordinate of the second segment
+ * @param y3 the first y coordinate of the second segment
+ * @param x4 the second x coordinate of the second segment
+ * @param y4 the second y coordinate of the second segment
+ * @return true if the segments intersect
+ */
+ public static boolean linesIntersect(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+ {
+ double a1, a2, a3, a4;
+
+ // deal with special cases
+ if ((a1 = area2(x1, y1, x2, y2, x3, y3)) == 0.0)
+ {
+ // check if p3 is between p1 and p2 OR
+ // p4 is collinear also AND either between p1 and p2 OR at opposite ends
+ if (between(x1, y1, x2, y2, x3, y3))
+ {
+ return true;
+ }
+ else
+ {
+ if (area2(x1, y1, x2, y2, x4, y4) == 0.0)
+ {
+ return between(x3, y3, x4, y4, x1, y1)
+ || between (x3, y3, x4, y4, x2, y2);
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ else if ((a2 = area2(x1, y1, x2, y2, x4, y4)) == 0.0)
+ {
+ // check if p4 is between p1 and p2 (we already know p3 is not
+ // collinear)
+ return between(x1, y1, x2, y2, x4, y4);
+ }
+
+ if ((a3 = area2(x3, y3, x4, y4, x1, y1)) == 0.0) {
+ // check if p1 is between p3 and p4 OR
+ // p2 is collinear also AND either between p1 and p2 OR at opposite ends
+ if (between(x3, y3, x4, y4, x1, y1)) {
+ return true;
+ }
+ else {
+ if (area2(x3, y3, x4, y4, x2, y2) == 0.0) {
+ return between(x1, y1, x2, y2, x3, y3)
+ || between (x1, y1, x2, y2, x4, y4);
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ else if ((a4 = area2(x3, y3, x4, y4, x2, y2)) == 0.0) {
+ // check if p2 is between p3 and p4 (we already know p1 is not
+ // collinear)
+ return between(x3, y3, x4, y4, x2, y2);
+ }
+ else { // test for regular intersection
+ return ((a1 > 0.0) ^ (a2 > 0.0)) && ((a3 > 0.0) ^ (a4 > 0.0));
+ }
+ }
+
+ /**
+ * Test if this line intersects the line given by (x1,y1)-&gt;(x2,y2).
+ *
+ * @param x1 the first x coordinate of the other segment
+ * @param y1 the first y coordinate of the other segment
+ * @param x2 the second x coordinate of the other segment
+ * @param y2 the second y coordinate of the other segment
+ * @return true if the segments intersect
+ * @see #linesIntersect(double, double, double, double,
+ * double, double, double, double)
+ */
+ public boolean intersectsLine(double x1, double y1, double x2, double y2)
+ {
+ return linesIntersect(getX1(), getY1(), getX2(), getY2(),
+ x1, y1, x2, y2);
+ }
+
+ /**
+ * Test if this line intersects the given line.
+ *
+ * @param l the other segment
+ * @return true if the segments intersect
+ * @throws NullPointerException if l is null
+ * @see #linesIntersect(double, double, double, double,
+ * double, double, double, double)
+ */
+ public boolean intersectsLine(Line2D l)
+ {
+ return linesIntersect(getX1(), getY1(), getX2(), getY2(),
+ l.getX1(), l.getY1(), l.getX2(), l.getY2());
+ }
+
+ /**
+ * Measures the square of the shortest distance from the reference point
+ * to a point on the line segment. If the point is on the segment, the
+ * result will be 0.
+ *
+ * @param x1 the first x coordinate of the segment
+ * @param y1 the first y coordinate of the segment
+ * @param x2 the second x coordinate of the segment
+ * @param y2 the second y coordinate of the segment
+ * @param px the x coordinate of the point
+ * @param py the y coordinate of the point
+ * @return the square of the distance from the point to the segment
+ * @see #ptSegDist(double, double, double, double, double, double)
+ * @see #ptLineDistSq(double, double, double, double, double, double)
+ */
+ public static double ptSegDistSq(double x1, double y1, double x2, double y2,
+ double px, double py)
+ {
+ double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
+
+ double x, y;
+ if (pd2 == 0)
+ {
+ // Points are coincident.
+ x = x1;
+ y = y2;
+ }
+ else
+ {
+ double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
+
+ if (u < 0)
+ {
+ // "Off the end"
+ x = x1;
+ y = y1;
+ }
+ else if (u > 1.0)
+ {
+ x = x2;
+ y = y2;
+ }
+ else
+ {
+ x = x1 + u * (x2 - x1);
+ y = y1 + u * (y2 - y1);
+ }
+ }
+
+ return (x - px) * (x - px) + (y - py) * (y - py);
+ }
+
+ /**
+ * Measures the shortest distance from the reference point to a point on
+ * the line segment. If the point is on the segment, the result will be 0.
+ *
+ * @param x1 the first x coordinate of the segment
+ * @param y1 the first y coordinate of the segment
+ * @param x2 the second x coordinate of the segment
+ * @param y2 the second y coordinate of the segment
+ * @param px the x coordinate of the point
+ * @param py the y coordinate of the point
+ * @return the distance from the point to the segment
+ * @see #ptSegDistSq(double, double, double, double, double, double)
+ * @see #ptLineDist(double, double, double, double, double, double)
+ */
+ public static double ptSegDist(double x1, double y1, double x2, double y2,
+ double px, double py)
+ {
+ return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
+ }
+
+ /**
+ * Measures the square of the shortest distance from the reference point
+ * to a point on this line segment. If the point is on the segment, the
+ * result will be 0.
+ *
+ * @param px the x coordinate of the point
+ * @param py the y coordinate of the point
+ * @return the square of the distance from the point to the segment
+ * @see #ptSegDistSq(double, double, double, double, double, double)
+ */
+ public double ptSegDistSq(double px, double py)
+ {
+ return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+ }
+
+ /**
+ * Measures the square of the shortest distance from the reference point
+ * to a point on this line segment. If the point is on the segment, the
+ * result will be 0.
+ *
+ * @param p the point
+ * @return the square of the distance from the point to the segment
+ * @throws NullPointerException if p is null
+ * @see #ptSegDistSq(double, double, double, double, double, double)
+ */
+ public double ptSegDistSq(Point2D p)
+ {
+ return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+ }
+
+ /**
+ * Measures the shortest distance from the reference point to a point on
+ * this line segment. If the point is on the segment, the result will be 0.
+ *
+ * @param px the x coordinate of the point
+ * @param py the y coordinate of the point
+ * @return the distance from the point to the segment
+ * @see #ptSegDist(double, double, double, double, double, double)
+ */
+ public double ptSegDist(double px, double py)
+ {
+ return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
+ }
+
+ /**
+ * Measures the shortest distance from the reference point to a point on
+ * this line segment. If the point is on the segment, the result will be 0.
+ *
+ * @param p the point
+ * @return the distance from the point to the segment
+ * @throws NullPointerException if p is null
+ * @see #ptSegDist(double, double, double, double, double, double)
+ */
+ public double ptSegDist(Point2D p)
+ {
+ return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+ }
+
+ /**
+ * Measures the square of the shortest distance from the reference point
+ * to a point on the infinite line extended from the segment. If the point
+ * is on the segment, the result will be 0. If the segment is length 0,
+ * the distance is to the common endpoint.
+ *
+ * @param x1 the first x coordinate of the segment
+ * @param y1 the first y coordinate of the segment
+ * @param x2 the second x coordinate of the segment
+ * @param y2 the second y coordinate of the segment
+ * @param px the x coordinate of the point
+ * @param py the y coordinate of the point
+ * @return the square of the distance from the point to the extended line
+ * @see #ptLineDist(double, double, double, double, double, double)
+ * @see #ptSegDistSq(double, double, double, double, double, double)
+ */
+ public static double ptLineDistSq(double x1, double y1, double x2, double y2,
+ double px, double py)
+ {
+ double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
+
+ double x, y;
+ if (pd2 == 0)
+ {
+ // Points are coincident.
+ x = x1;
+ y = y2;
+ }
+ else
+ {
+ double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
+ x = x1 + u * (x2 - x1);
+ y = y1 + u * (y2 - y1);
+ }
+
+ return (x - px) * (x - px) + (y - py) * (y - py);
+ }
+
+ /**
+ * Measures the shortest distance from the reference point to a point on
+ * the infinite line extended from the segment. If the point is on the
+ * segment, the result will be 0. If the segment is length 0, the distance
+ * is to the common endpoint.
+ *
+ * @param x1 the first x coordinate of the segment
+ * @param y1 the first y coordinate of the segment
+ * @param x2 the second x coordinate of the segment
+ * @param y2 the second y coordinate of the segment
+ * @param px the x coordinate of the point
+ * @param py the y coordinate of the point
+ * @return the distance from the point to the extended line
+ * @see #ptLineDistSq(double, double, double, double, double, double)
+ * @see #ptSegDist(double, double, double, double, double, double)
+ */
+ public static double ptLineDist(double x1, double y1,
+ double x2, double y2,
+ double px, double py)
+ {
+ return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
+ }
+
+ /**
+ * Measures the square of the shortest distance from the reference point
+ * to a point on the infinite line extended from this segment. If the point
+ * is on the segment, the result will be 0. If the segment is length 0,
+ * the distance is to the common endpoint.
+ *
+ * @param px the x coordinate of the point
+ * @param py the y coordinate of the point
+ * @return the square of the distance from the point to the extended line
+ * @see #ptLineDistSq(double, double, double, double, double, double)
+ */
+ public double ptLineDistSq(double px, double py)
+ {
+ return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+ }
+
+ /**
+ * Measures the square of the shortest distance from the reference point
+ * to a point on the infinite line extended from this segment. If the point
+ * is on the segment, the result will be 0. If the segment is length 0,
+ * the distance is to the common endpoint.
+ *
+ * @param p the point
+ * @return the square of the distance from the point to the extended line
+ * @throws NullPointerException if p is null
+ * @see #ptLineDistSq(double, double, double, double, double, double)
+ */
+ public double ptLineDistSq(Point2D p)
+ {
+ return ptLineDistSq(getX1(), getY1(), getX2(), getY2(),
+ p.getX(), p.getY());
+ }
+
+ /**
+ * Measures the shortest distance from the reference point to a point on
+ * the infinite line extended from this segment. If the point is on the
+ * segment, the result will be 0. If the segment is length 0, the distance
+ * is to the common endpoint.
+ *
+ * @param px the x coordinate of the point
+ * @param py the y coordinate of the point
+ * @return the distance from the point to the extended line
+ * @see #ptLineDist(double, double, double, double, double, double)
+ */
+ public double ptLineDist(double px, double py)
+ {
+ return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
+ }
+
+ /**
+ * Measures the shortest distance from the reference point to a point on
+ * the infinite line extended from this segment. If the point is on the
+ * segment, the result will be 0. If the segment is length 0, the distance
+ * is to the common endpoint.
+ *
+ * @param p the point
+ * @return the distance from the point to the extended line
+ * @throws NullPointerException if p is null
+ * @see #ptLineDist(double, double, double, double, double, double)
+ */
+ public double ptLineDist(Point2D p)
+ {
+ return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+ }
+
+ /**
+ * Test if a point is contained inside the line. Since a line has no area,
+ * this returns false.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @return false; the line does not contain points
+ */
+ public boolean contains(double x, double y)
+ {
+ return false;
+ }
+
+ /**
+ * Test if a point is contained inside the line. Since a line has no area,
+ * this returns false.
+ *
+ * @param p the point
+ * @return false; the line does not contain points
+ */
+ public boolean contains(Point2D p)
+ {
+ return false;
+ }
+
+ /**
+ * Tests if this line intersects the interior of the specified rectangle.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @return true if the line intersects the rectangle
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ if (w <= 0 || h <= 0)
+ return false;
+ double x1 = getX1();
+ double y1 = getY1();
+ double x2 = getX2();
+ double y2 = getY2();
+
+ if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h)
+ return true;
+ if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y + h)
+ return true;
+
+ double x3 = x + w;
+ double y3 = y + h;
+
+ return (linesIntersect(x1, y1, x2, y2, x, y, x, y3)
+ || linesIntersect(x1, y1, x2, y2, x, y3, x3, y3)
+ || linesIntersect(x1, y1, x2, y2, x3, y3, x3, y)
+ || linesIntersect(x1, y1, x2, y2, x3, y, x, y));
+ }
+
+ /**
+ * Tests if this line intersects the interior of the specified rectangle.
+ *
+ * @param r the rectangle
+ * @return true if the line intersects the rectangle
+ * @throws NullPointerException if r is null
+ */
+ public boolean intersects(Rectangle2D r)
+ {
+ return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Tests if the line contains a rectangle. Since lines have no area, this
+ * always returns false.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @return false; the line does not contain points
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ return false;
+ }
+
+ /**
+ * Tests if the line contains a rectangle. Since lines have no area, this
+ * always returns false.
+ *
+ * @param r the rectangle
+ * @return false; the line does not contain points
+ */
+ public boolean contains(Rectangle2D r)
+ {
+ return false;
+ }
+
+ /**
+ * Gets a bounding box (not necessarily minimal) for this line.
+ *
+ * @return the integer bounding box
+ * @see #getBounds2D()
+ */
+ public Rectangle getBounds()
+ {
+ return getBounds2D().getBounds();
+ }
+
+ /**
+ * Return a path iterator, possibly applying a transform on the result. This
+ * iterator is not threadsafe.
+ *
+ * @param at the transform, or null
+ * @return a new path iterator
+ */
+ public PathIterator getPathIterator(final AffineTransform at)
+ {
+ return new PathIterator()
+ {
+ /** Current coordinate. */
+ private int current = 0;
+
+ public int getWindingRule()
+ {
+ return WIND_NON_ZERO;
+ }
+
+ public boolean isDone()
+ {
+ return current >= 2;
+ }
+
+ public void next()
+ {
+ current++;
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ int result;
+ switch (current)
+ {
+ case 0:
+ coords[0] = (float) getX1();
+ coords[1] = (float) getY1();
+ result = SEG_MOVETO;
+ break;
+ case 1:
+ coords[0] = (float) getX2();
+ coords[1] = (float) getY2();
+ result = SEG_LINETO;
+ break;
+ default:
+ throw new NoSuchElementException("line iterator out of bounds");
+ }
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 1);
+ return result;
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ int result;
+ switch (current)
+ {
+ case 0:
+ coords[0] = getX1();
+ coords[1] = getY1();
+ result = SEG_MOVETO;
+ break;
+ case 1:
+ coords[0] = getX2();
+ coords[1] = getY2();
+ result = SEG_LINETO;
+ break;
+ default:
+ throw new NoSuchElementException("line iterator out of bounds");
+ }
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 1);
+ return result;
+ }
+ };
+ }
+
+ /**
+ * Return a flat path iterator, possibly applying a transform on the result.
+ * This iterator is not threadsafe.
+ *
+ * @param at the transform, or null
+ * @param flatness ignored, since lines are already flat
+ * @return a new path iterator
+ * @see #getPathIterator(AffineTransform)
+ */
+ public PathIterator getPathIterator(AffineTransform at, double flatness)
+ {
+ return getPathIterator(at);
+ }
+
+ /**
+ * Create a new line of the same run-time type with the same contents as
+ * this one.
+ *
+ * @return the clone
+ *
+ * @exception OutOfMemoryError If there is not enough memory available.
+ *
+ * @since 1.2
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+
+ /**
+ * This class defines a point in <code>double</code> precision.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+ public static class Double extends Line2D
+ {
+ /** The x coordinate of the first point. */
+ public double x1;
+
+ /** The y coordinate of the first point. */
+ public double y1;
+
+ /** The x coordinate of the second point. */
+ public double x2;
+
+ /** The y coordinate of the second point. */
+ public double y2;
+
+ /**
+ * Construct the line segment (0,0)-&gt;(0,0).
+ */
+ public Double()
+ {
+ }
+
+ /**
+ * Construct the line segment with the specified points.
+ *
+ * @param x1 the x coordinate of the first point
+ * @param y1 the y coordinate of the first point
+ * @param x2 the x coordinate of the second point
+ * @param y2 the y coordinate of the second point
+ */
+ public Double(double x1, double y1, double x2, double y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Construct the line segment with the specified points.
+ *
+ * @param p1 the first point
+ * @param p2 the second point
+ * @throws NullPointerException if either point is null
+ */
+ public Double(Point2D p1, Point2D p2)
+ {
+ x1 = p1.getX();
+ y1 = p1.getY();
+ x2 = p2.getX();
+ y2 = p2.getY();
+ }
+
+ /**
+ * Return the x coordinate of the first point.
+ *
+ * @return the value of x1
+ */
+ public double getX1()
+ {
+ return x1;
+ }
+
+ /**
+ * Return the y coordinate of the first point.
+ *
+ * @return the value of y1
+ */
+ public double getY1()
+ {
+ return y1;
+ }
+
+ /**
+ * Return the first point.
+ *
+ * @return the point (x1,y1)
+ */
+ public Point2D getP1()
+ {
+ return new Point2D.Double(x1, y1);
+ }
+
+ /**
+ * Return the x coordinate of the second point.
+ *
+ * @return the value of x2
+ */
+ public double getX2()
+ {
+ return x2;
+ }
+
+ /**
+ * Return the y coordinate of the second point.
+ *
+ * @return the value of y2
+ */
+ public double getY2()
+ {
+ return y2;
+ }
+
+ /**
+ * Return the second point.
+ *
+ * @return the point (x2,y2)
+ */
+ public Point2D getP2()
+ {
+ return new Point2D.Double(x2, y2);
+ }
+
+ /**
+ * Set this line to the given points.
+ *
+ * @param x1 the new x coordinate of the first point
+ * @param y1 the new y coordinate of the first point
+ * @param x2 the new x coordinate of the second point
+ * @param y2 the new y coordinate of the second point
+ */
+ public void setLine(double x1, double y1, double x2, double y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Return the exact bounds of this line segment.
+ *
+ * @return the bounding box
+ */
+ public Rectangle2D getBounds2D()
+ {
+ double x = Math.min(x1, x2);
+ double y = Math.min(y1, y2);
+ double w = Math.abs(x1 - x2);
+ double h = Math.abs(y1 - y2);
+ return new Rectangle2D.Double(x, y, w, h);
+ }
+ } // class Double
+
+ /**
+ * This class defines a point in <code>float</code> precision.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+ public static class Float extends Line2D
+ {
+ /** The x coordinate of the first point. */
+ public float x1;
+
+ /** The y coordinate of the first point. */
+ public float y1;
+
+ /** The x coordinate of the second point. */
+ public float x2;
+
+ /** The y coordinate of the second point. */
+ public float y2;
+
+ /**
+ * Construct the line segment (0,0)-&gt;(0,0).
+ */
+ public Float()
+ {
+ }
+
+ /**
+ * Construct the line segment with the specified points.
+ *
+ * @param x1 the x coordinate of the first point
+ * @param y1 the y coordinate of the first point
+ * @param x2 the x coordinate of the second point
+ * @param y2 the y coordinate of the second point
+ */
+ public Float(float x1, float y1, float x2, float y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Construct the line segment with the specified points.
+ *
+ * @param p1 the first point
+ * @param p2 the second point
+ * @throws NullPointerException if either point is null
+ */
+ public Float(Point2D p1, Point2D p2)
+ {
+ x1 = (float) p1.getX();
+ y1 = (float) p1.getY();
+ x2 = (float) p2.getX();
+ y2 = (float) p2.getY();
+ }
+
+ /**
+ * Return the x coordinate of the first point.
+ *
+ * @return the value of x1
+ */
+ public double getX1()
+ {
+ return x1;
+ }
+
+ /**
+ * Return the y coordinate of the first point.
+ *
+ * @return the value of y1
+ */
+ public double getY1()
+ {
+ return y1;
+ }
+
+ /**
+ * Return the first point.
+ *
+ * @return the point (x1,y1)
+ */
+ public Point2D getP1()
+ {
+ return new Point2D.Float(x1, y1);
+ }
+
+ /**
+ * Return the x coordinate of the second point.
+ *
+ * @return the value of x2
+ */
+ public double getX2()
+ {
+ return x2;
+ }
+
+ /**
+ * Return the y coordinate of the second point.
+ *
+ * @return the value of y2
+ */
+ public double getY2()
+ {
+ return y2;
+ }
+
+ /**
+ * Return the second point.
+ *
+ * @return the point (x2,y2)
+ */
+ public Point2D getP2()
+ {
+ return new Point2D.Float(x2, y2);
+ }
+
+ /**
+ * Set this line to the given points.
+ *
+ * @param x1 the new x coordinate of the first point
+ * @param y1 the new y coordinate of the first point
+ * @param x2 the new x coordinate of the second point
+ * @param y2 the new y coordinate of the second point
+ */
+ public void setLine(double x1, double y1, double x2, double y2)
+ {
+ this.x1 = (float) x1;
+ this.y1 = (float) y1;
+ this.x2 = (float) x2;
+ this.y2 = (float) y2;
+ }
+
+ /**
+ * Set this line to the given points.
+ *
+ * @param x1 the new x coordinate of the first point
+ * @param y1 the new y coordinate of the first point
+ * @param x2 the new x coordinate of the second point
+ * @param y2 the new y coordinate of the second point
+ */
+ public void setLine(float x1, float y1, float x2, float y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Return the exact bounds of this line segment.
+ *
+ * @return the bounding box
+ */
+ public Rectangle2D getBounds2D()
+ {
+ float x = Math.min(x1, x2);
+ float y = Math.min(y1, y2);
+ float w = Math.abs(x1 - x2);
+ float h = Math.abs(y1 - y2);
+ return new Rectangle2D.Float(x, y, w, h);
+ }
+ } // class Float
+} // class Line2D
diff --git a/libjava/classpath/java/awt/geom/NoninvertibleTransformException.java b/libjava/classpath/java/awt/geom/NoninvertibleTransformException.java
new file mode 100644
index 0000000..7995a52
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/NoninvertibleTransformException.java
@@ -0,0 +1,65 @@
+/* NoninvertibleTransformException.java -- a transform can't be inverted
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+/**
+ * Thrown if an operation requires an inverse of an
+ * <code>AffineTransform</code>, but the transform is in a non-invertible
+ * state.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @see AffineTransform
+ * @status updated to 1.4
+ */
+public class NoninvertibleTransformException extends Exception
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 6137225240503990466L;
+
+ /**
+ * Create an exception with a message.
+ *
+ * @param s the message
+ */
+ public NoninvertibleTransformException(String s)
+ {
+ super(s);
+ }
+}
diff --git a/libjava/classpath/java/awt/geom/PathIterator.java b/libjava/classpath/java/awt/geom/PathIterator.java
new file mode 100644
index 0000000..2cd08b9
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/PathIterator.java
@@ -0,0 +1,189 @@
+/* PathIterator.java -- describes a shape by iterating over its vertices
+ Copyright (C) 2000, 2002, 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+/**
+ * This interface provides a directed path over the boundary of a shape. The
+ * path can contain 1st through 3rd order Bezier curves (lines, and quadratic
+ * and cubic splines). A shape can have multiple disjoint paths via the
+ * MOVETO directive, and can close a circular path back to the previos
+ * MOVETO via the CLOSE directive.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see java.awt.Shape
+ * @see java.awt.Stroke
+ * @see FlatteningPathIterator
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface PathIterator
+{
+ /**
+ * The even-odd winding mode: a point is internal to the shape if a ray
+ * from the point to infinity (in any direction) crosses an odd number of
+ * segments.
+ */
+ int WIND_EVEN_ODD = 0;
+
+ /**
+ * The non-zero winding mode: a point is internal to the shape if a ray
+ * from the point to infinity (in any direction) crosses a different number
+ * of segments headed clockwise than those headed counterclockwise.
+ */
+ int WIND_NON_ZERO = 1;
+
+ /**
+ * Starts a new subpath. There is no segment from the previous vertex.
+ */
+ int SEG_MOVETO = 0;
+
+ /**
+ * The current segment is a line.
+ */
+ int SEG_LINETO = 1;
+
+ /**
+ * The current segment is a quadratic parametric curve. It is interpolated
+ * as t varies from 0 to 1 over the current point (CP), first control point
+ * (P1), and final interpolated control point (P2):
+ * <pre>
+ * P(t) = B(2,0)*CP + B(2,1)*P1 + B(2,2)*P2
+ * 0 &lt;= t &lt;= 1
+ * B(n,m) = mth coefficient of nth degree Bernstein polynomial
+ * = C(n,m) * t^(m) * (1 - t)^(n-m)
+ * C(n,m) = Combinations of n things, taken m at a time
+ * = n! / (m! * (n-m)!)
+ * </pre>
+ */
+ int SEG_QUADTO = 2;
+
+ /**
+ * The current segment is a cubic parametric curve (more commonly known as
+ * a Bezier curve). It is interpolated as t varies from 0 to 1 over the
+ * current point (CP), first control point (P1), the second control point
+ * (P2), and final interpolated control point (P3):
+ * <pre>
+ * P(t) = B(3,0)*CP + B(3,1)*P1 + B(3,2)*P2 + B(3,3)*P3
+ * 0 &lt;= t &lt;= 1
+ * B(n,m) = mth coefficient of nth degree Bernstein polynomial
+ * = C(n,m) * t^(m) * (1 - t)^(n-m)
+ * C(n,m) = Combinations of n things, taken m at a time
+ * = n! / (m! * (n-m)!)
+ * </pre>
+ */
+ int SEG_CUBICTO = 3;
+
+ /**
+ * The current segment closes a loop by an implicit line to the previous
+ * SEG_MOVETO coordinate.
+ */
+ int SEG_CLOSE = 4;
+
+ /**
+ * Returns the winding rule to determine which points are inside this path.
+ *
+ * @return the winding rule
+ * @see #WIND_EVEN_ODD
+ * @see #WIND_NON_ZERO
+ */
+ int getWindingRule();
+
+ /**
+ * Tests if the iterator is exhausted. If this returns true, currentSegment
+ * and next may throw a NoSuchElementException (although this is not
+ * required).
+ *
+ * @return true if the iteration is complete
+ */
+ boolean isDone();
+
+ /**
+ * Advance to the next segment in the iteration. It is not specified what
+ * this does if called when isDone() returns true.
+ *
+ * @throws java.util.NoSuchElementException optional when isDone() is true
+ */
+ void next();
+
+ /**
+ * Returns the coordinates of the next point(s), as well as the type of
+ * line segment. The input array must be at least a float[6], to accomodate
+ * up to three (x,y) point pairs (although if you know the iterator is
+ * flat, you can probably get by with a float[2]). If the returned type is
+ * SEG_MOVETO or SEG_LINETO, the first point in the array is modified; if
+ * the returned type is SEG_QUADTO, the first two points are modified; if
+ * the returned type is SEG_CUBICTO, all three points are modified; and if
+ * the returned type is SEG_CLOSE, the array is untouched.
+ *
+ * @param coords the array to place the point coordinates in
+ * @return the segment type
+ * @throws NullPointerException if coords is null
+ * @throws ArrayIndexOutOfBoundsException if coords is too small
+ * @throws java.util.NoSuchElementException optional when isDone() is true
+ * @see #SEG_MOVETO
+ * @see #SEG_LINETO
+ * @see #SEG_QUADTO
+ * @see #SEG_CUBICTO
+ * @see #SEG_CLOSE
+ */
+ int currentSegment(float[] coords);
+
+ /**
+ * Returns the coordinates of the next point(s), as well as the type of
+ * line segment. The input array must be at least a double[6], to accomodate
+ * up to three (x,y) point pairs (although if you know the iterator is
+ * flat, you can probably get by with a double[2]). If the returned type is
+ * SEG_MOVETO or SEG_LINETO, the first point in the array is modified; if
+ * the returned type is SEG_QUADTO, the first two points are modified; if
+ * the returned type is SEG_CUBICTO, all three points are modified; and if
+ * the returned type is SEG_CLOSE, the array is untouched.
+ *
+ * @param coords the array to place the point coordinates in
+ * @return the segment type
+ * @throws NullPointerException if coords is null
+ * @throws ArrayIndexOutOfBoundsException if coords is too small
+ * @throws java.util.NoSuchElementException optional when isDone() is true
+ * @see #SEG_MOVETO
+ * @see #SEG_LINETO
+ * @see #SEG_QUADTO
+ * @see #SEG_CUBICTO
+ * @see #SEG_CLOSE
+ */
+ int currentSegment(double[] coords);
+} // interface PathIterator
diff --git a/libjava/classpath/java/awt/geom/Point2D.java b/libjava/classpath/java/awt/geom/Point2D.java
new file mode 100644
index 0000000..9f22a5a
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/Point2D.java
@@ -0,0 +1,396 @@
+/* Point2D.java -- generic point in 2-D space
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.geom;
+
+/**
+ * This class implements a generic point in 2D Cartesian space. The storage
+ * representation is left up to the subclass. Point includes two useful
+ * nested classes, for float and double storage respectively.
+ *
+ * @author Per Bothner (bothner@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public abstract class Point2D implements Cloneable
+{
+ /**
+ * The default constructor.
+ *
+ * @see java.awt.Point
+ * @see Point2D.Float
+ * @see Point2D.Double
+ */
+ protected Point2D()
+ {
+ }
+
+ /**
+ * Get the X coordinate, in double precision.
+ *
+ * @return the x coordinate
+ */
+ public abstract double getX();
+
+ /**
+ * Get the Y coordinate, in double precision.
+ *
+ * @return the y coordinate
+ */
+ public abstract double getY();
+
+ /**
+ * Set the location of this point to the new coordinates. There may be a
+ * loss of precision.
+ *
+ * @param x the new x coordinate
+ * @param y the new y coordinate
+ */
+ public abstract void setLocation(double x, double y);
+
+ /**
+ * Set the location of this point to the new coordinates. There may be a
+ * loss of precision.
+ *
+ * @param p the point to copy
+ * @throws NullPointerException if p is null
+ */
+ public void setLocation(Point2D p)
+ {
+ setLocation(p.getX(), p.getY());
+ }
+
+ /**
+ * Return the square of the distance between two points.
+ *
+ * @param x1 the x coordinate of point 1
+ * @param y1 the y coordinate of point 1
+ * @param x2 the x coordinate of point 2
+ * @param y2 the y coordinate of point 2
+ * @return (x2 - x1)^2 + (y2 - y1)^2
+ */
+ public static double distanceSq(double x1, double y1, double x2, double y2)
+ {
+ x2 -= x1;
+ y2 -= y1;
+ return x2 * x2 + y2 * y2;
+ }
+
+ /**
+ * Return the distance between two points.
+ *
+ * @param x1 the x coordinate of point 1
+ * @param y1 the y coordinate of point 1
+ * @param x2 the x coordinate of point 2
+ * @param y2 the y coordinate of point 2
+ * @return the distance from (x1,y1) to (x2,y2)
+ */
+ public static double distance(double x1, double y1, double x2, double y2)
+ {
+ return Math.sqrt(distanceSq(x1, y1, x2, y2));
+ }
+
+ /**
+ * Return the square of the distance from this point to the given one.
+ *
+ * @param x the x coordinate of the other point
+ * @param y the y coordinate of the other point
+ * @return the square of the distance
+ */
+ public double distanceSq(double x, double y)
+ {
+ return distanceSq(getX(), x, getY(), y);
+ }
+
+ /**
+ * Return the square of the distance from this point to the given one.
+ *
+ * @param p the other point
+ * @return the square of the distance
+ * @throws NullPointerException if p is null
+ */
+ public double distanceSq(Point2D p)
+ {
+ return distanceSq(getX(), p.getX(), getY(), p.getY());
+ }
+
+ /**
+ * Return the distance from this point to the given one.
+ *
+ * @param x the x coordinate of the other point
+ * @param y the y coordinate of the other point
+ * @return the distance
+ */
+ public double distance(double x, double y)
+ {
+ return distance(getX(), x, getY(), y);
+ }
+
+ /**
+ * Return the distance from this point to the given one.
+ *
+ * @param p the other point
+ * @return the distance
+ * @throws NullPointerException if p is null
+ */
+ public double distance(Point2D p)
+ {
+ return distance(getX(), p.getX(), getY(), p.getY());
+ }
+
+ /**
+ * Create a new point of the same run-time type with the same contents as
+ * this one.
+ *
+ * @return the clone
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+
+ /**
+ * Return the hashcode for this point. The formula is not documented, but
+ * appears to be the same as:
+ * <pre>
+ * long l = Double.doubleToLongBits(getY());
+ * l = l * 31 ^ Double.doubleToLongBits(getX());
+ * return (int) ((l >> 32) ^ l);
+ * </pre>
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ // Talk about a fun time reverse engineering this one!
+ long l = java.lang.Double.doubleToLongBits(getY());
+ l = l * 31 ^ java.lang.Double.doubleToLongBits(getX());
+ return (int) ((l >> 32) ^ l);
+ }
+
+ /**
+ * Compares two points for equality. This returns true if they have the
+ * same coordinates.
+ *
+ * @param o the point to compare
+ * @return true if it is equal
+ */
+ public boolean equals(Object o)
+ {
+ if (! (o instanceof Point2D))
+ return false;
+ Point2D p = (Point2D) o;
+ return getX() == p.getX() && getY() == p.getY();
+ }
+
+ /**
+ * This class defines a point in <code>double</code> precision.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+ public static class Double extends Point2D
+ {
+ /** The X coordinate. */
+ public double x;
+
+ /** The Y coordinate. */
+ public double y;
+
+ /**
+ * Create a new point at (0,0).
+ */
+ public Double()
+ {
+ }
+
+ /**
+ * Create a new point at (x,y).
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+ public Double(double x, double y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Return the x coordinate.
+ *
+ * @return the x coordinate
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Return the y coordinate.
+ *
+ * @return the y coordinate
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Sets the location of this point.
+ *
+ * @param x the new x coordinate
+ * @param y the new y coordinate
+ */
+ public void setLocation(double x, double y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Returns a string representation of this object. The format is:
+ * <code>"Point2D.Double[" + x + ", " + y + ']'</code>.
+ *
+ * @return a string representation of this object
+ */
+ public String toString()
+ {
+ return "Point2D.Double[" + x + ", " + y + ']';
+ }
+ } // class Double
+
+ /**
+ * This class defines a point in <code>float</code> precision.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+ public static class Float extends Point2D
+ {
+ /** The X coordinate. */
+ public float x;
+
+ /** The Y coordinate. */
+ public float y;
+
+ /**
+ * Create a new point at (0,0).
+ */
+ public Float()
+ {
+ }
+
+ /**
+ * Create a new point at (x,y).
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+ public Float(float x, float y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Return the x coordinate.
+ *
+ * @return the x coordinate
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Return the y coordinate.
+ *
+ * @return the y coordinate
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Sets the location of this point.
+ *
+ * @param x the new x coordinate
+ * @param y the new y coordinate
+ */
+ public void setLocation(double x, double y)
+ {
+ this.x = (float) x;
+ this.y = (float) y;
+ }
+
+ /**
+ * Sets the location of this point.
+ *
+ * @param x the new x coordinate
+ * @param y the new y coordinate
+ */
+ public void setLocation(float x, float y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Returns a string representation of this object. The format is:
+ * <code>"Point2D.Float[" + x + ", " + y + ']'</code>.
+ *
+ * @return a string representation of this object
+ */
+ public String toString()
+ {
+ return "Point2D.Float[" + x + ", " + y + ']';
+ }
+ } // class Float
+} // class Point2D
diff --git a/libjava/classpath/java/awt/geom/QuadCurve2D.java b/libjava/classpath/java/awt/geom/QuadCurve2D.java
new file mode 100644
index 0000000..41021db
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/QuadCurve2D.java
@@ -0,0 +1,1467 @@
+/* QuadCurve2D.java -- represents a parameterized quadratic curve in 2-D space
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+/**
+ * A two-dimensional curve that is parameterized with a quadratic
+ * function.
+ *
+ * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a QuadCurve2D" />
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Graydon Hoare (graydon@redhat.com)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Sven de Marothy (sven@physto.se)
+ *
+ * @since 1.2
+ */
+public abstract class QuadCurve2D implements Shape, Cloneable
+{
+ private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
+ private static final double EPSILON = 1E-10;
+
+ /**
+ * Constructs a new QuadCurve2D. Typical users will want to
+ * construct instances of a subclass, such as {@link
+ * QuadCurve2D.Float} or {@link QuadCurve2D.Double}.
+ */
+ protected QuadCurve2D()
+ {
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public abstract double getX1();
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public abstract double getY1();
+
+ /**
+ * Returns the curve&#x2019;s start point.
+ */
+ public abstract Point2D getP1();
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s control
+ * point.
+ */
+ public abstract double getCtrlX();
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s control
+ * point.
+ */
+ public abstract double getCtrlY();
+
+ /**
+ * Returns the curve&#x2019;s control point.
+ */
+ public abstract Point2D getCtrlPt();
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public abstract double getX2();
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public abstract double getY2();
+
+ /**
+ * Returns the curve&#x2019;s end point.
+ */
+ public abstract Point2D getP2();
+
+ /**
+ * Changes the curve geometry, separately specifying each coordinate
+ * value.
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
+ * point.
+ *
+ * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
+ * control point.
+ *
+ * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
+ * control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
+ * point.
+ */
+ public abstract void setCurve(double x1, double y1, double cx, double cy,
+ double x2, double y2);
+
+ /**
+ * Changes the curve geometry, passing coordinate values in an
+ * array.
+ *
+ * @param coords an array containing the new coordinate values. The
+ * <i>x</i> coordinate of the new start point is located at
+ * <code>coords[offset]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
+ * new control point is located at <code>coords[offset + 2]</code>,
+ * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
+ * <i>x</i> coordinate of the new end point is located at
+ * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 5]</code>.
+ *
+ * @param offset the offset of the first coordinate value in
+ * <code>coords</code>.
+ */
+ public void setCurve(double[] coords, int offset)
+ {
+ setCurve(coords[offset++], coords[offset++], coords[offset++],
+ coords[offset++], coords[offset++], coords[offset++]);
+ }
+
+ /**
+ * Changes the curve geometry, specifying coordinate values in
+ * separate Point objects.
+ *
+ * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a QuadCurve2D" />
+ *
+ * <p>The curve does not keep any reference to the passed point
+ * objects. Therefore, a later change to <code>p1</code>,
+ * <code>c</code> <code>p2</code> will not affect the curve
+ * geometry.
+ *
+ * @param p1 the new start point.
+ * @param c the new control point.
+ * @param p2 the new end point.
+ */
+ public void setCurve(Point2D p1, Point2D c, Point2D p2)
+ {
+ setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(), p2.getX(), p2.getY());
+ }
+
+ /**
+ * Changes the curve geometry, specifying coordinate values in an
+ * array of Point objects.
+ *
+ * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
+ * alt="A drawing of a QuadCurve2D" />
+ *
+ * <p>The curve does not keep references to the passed point
+ * objects. Therefore, a later change to the <code>pts</code> array
+ * or any of its elements will not affect the curve geometry.
+ *
+ * @param pts an array containing the points. The new start point
+ * is located at <code>pts[offset]</code>, the new control
+ * point at <code>pts[offset + 1]</code>, and the new end point
+ * at <code>pts[offset + 2]</code>.
+ *
+ * @param offset the offset of the start point in <code>pts</code>.
+ */
+ public void setCurve(Point2D[] pts, int offset)
+ {
+ setCurve(pts[offset].getX(), pts[offset].getY(), pts[offset + 1].getX(),
+ pts[offset + 1].getY(), pts[offset + 2].getX(),
+ pts[offset + 2].getY());
+ }
+
+ /**
+ * Changes the geometry of the curve to that of another curve.
+ *
+ * @param c the curve whose coordinates will be copied.
+ */
+ public void setCurve(QuadCurve2D c)
+ {
+ setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(), c.getX2(),
+ c.getY2());
+ }
+
+ /**
+ * Calculates the squared flatness of a quadratic curve, directly
+ * specifying each coordinate value. The flatness is the distance of
+ * the control point to the line between start and end point.
+ *
+ * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. The result will be the
+ * the square of the distance between C and the gray line, i.e.
+ * the squared length of the red line.
+ *
+ * @param x1 the <i>x</i> coordinate of the start point P1.
+ * @param y1 the <i>y</i> coordinate of the start point P1.
+ * @param cx the <i>x</i> coordinate of the control point C.
+ * @param cy the <i>y</i> coordinate of the control point C.
+ * @param x2 the <i>x</i> coordinate of the end point P2.
+ * @param y2 the <i>y</i> coordinate of the end point P2.
+ */
+ public static double getFlatnessSq(double x1, double y1, double cx,
+ double cy, double x2, double y2)
+ {
+ return Line2D.ptSegDistSq(x1, y1, x2, y2, cx, cy);
+ }
+
+ /**
+ * Calculates the flatness of a quadratic curve, directly specifying
+ * each coordinate value. The flatness is the distance of the
+ * control point to the line between start and end point.
+ *
+ * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. The result will be the
+ * the distance between C and the gray line, i.e. the length of
+ * the red line.
+ *
+ * @param x1 the <i>x</i> coordinate of the start point P1.
+ * @param y1 the <i>y</i> coordinate of the start point P1.
+ * @param cx the <i>x</i> coordinate of the control point C.
+ * @param cy the <i>y</i> coordinate of the control point C.
+ * @param x2 the <i>x</i> coordinate of the end point P2.
+ * @param y2 the <i>y</i> coordinate of the end point P2.
+ */
+ public static double getFlatness(double x1, double y1, double cx, double cy,
+ double x2, double y2)
+ {
+ return Line2D.ptSegDist(x1, y1, x2, y2, cx, cy);
+ }
+
+ /**
+ * Calculates the squared flatness of a quadratic curve, specifying
+ * the coordinate values in an array. The flatness is the distance
+ * of the control point to the line between start and end point.
+ *
+ * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. The result will be the
+ * the square of the distance between C and the gray line, i.e.
+ * the squared length of the red line.
+ *
+ * @param coords an array containing the coordinate values. The
+ * <i>x</i> coordinate of the start point P1 is located at
+ * <code>coords[offset]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
+ * control point C is located at <code>coords[offset + 2]</code>,
+ * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
+ * <i>x</i> coordinate of the end point P2 is located at
+ * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 5]</code>.
+ *
+ * @param offset the offset of the first coordinate value in
+ * <code>coords</code>.
+ */
+ public static double getFlatnessSq(double[] coords, int offset)
+ {
+ return Line2D.ptSegDistSq(coords[offset], coords[offset + 1],
+ coords[offset + 4], coords[offset + 5],
+ coords[offset + 2], coords[offset + 3]);
+ }
+
+ /**
+ * Calculates the flatness of a quadratic curve, specifying the
+ * coordinate values in an array. The flatness is the distance of
+ * the control point to the line between start and end point.
+ *
+ * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. The result will be the
+ * the the distance between C and the gray line, i.e. the length of
+ * the red line.
+ *
+ * @param coords an array containing the coordinate values. The
+ * <i>x</i> coordinate of the start point P1 is located at
+ * <code>coords[offset]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
+ * control point C is located at <code>coords[offset + 2]</code>,
+ * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
+ * <i>x</i> coordinate of the end point P2 is located at
+ * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
+ * <code>coords[offset + 5]</code>.
+ *
+ * @param offset the offset of the first coordinate value in
+ * <code>coords</code>.
+ */
+ public static double getFlatness(double[] coords, int offset)
+ {
+ return Line2D.ptSegDist(coords[offset], coords[offset + 1],
+ coords[offset + 4], coords[offset + 5],
+ coords[offset + 2], coords[offset + 3]);
+ }
+
+ /**
+ * Calculates the squared flatness of this curve. The flatness is
+ * the distance of the control point to the line between start and
+ * end point.
+ *
+ * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. The result will be the
+ * the square of the distance between C and the gray line, i.e. the
+ * squared length of the red line.
+ */
+ public double getFlatnessSq()
+ {
+ return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
+ getCtrlY());
+ }
+
+ /**
+ * Calculates the flatness of this curve. The flatness is the
+ * distance of the control point to the line between start and end
+ * point.
+ *
+ * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
+ * alt="A drawing that illustrates the flatness" />
+ *
+ * <p>In the above drawing, the straight line connecting start point
+ * P1 and end point P2 is depicted in gray. The result will be the
+ * the distance between C and the gray line, i.e. the length of the
+ * red line.
+ */
+ public double getFlatness()
+ {
+ return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
+ getCtrlY());
+ }
+
+ /**
+ * Subdivides this curve into two halves.
+ *
+ * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
+ * height="180" alt="A drawing that illustrates the effects of
+ * subdividing a QuadCurve2D" />
+ *
+ * @param left a curve whose geometry will be set to the left half
+ * of this curve, or <code>null</code> if the caller is not
+ * interested in the left half.
+ *
+ * @param right a curve whose geometry will be set to the right half
+ * of this curve, or <code>null</code> if the caller is not
+ * interested in the right half.
+ */
+ public void subdivide(QuadCurve2D left, QuadCurve2D right)
+ {
+ // Use empty slots at end to share single array.
+ double[] d = new double[]
+ {
+ getX1(), getY1(), getCtrlX(), getCtrlY(), getX2(), getY2(),
+ 0, 0, 0, 0
+ };
+ subdivide(d, 0, d, 0, d, 4);
+ if (left != null)
+ left.setCurve(d, 0);
+ if (right != null)
+ right.setCurve(d, 4);
+ }
+
+ /**
+ * Subdivides a quadratic curve into two halves.
+ *
+ * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
+ * height="180" alt="A drawing that illustrates the effects of
+ * subdividing a QuadCurve2D" />
+ *
+ * @param src the curve to be subdivided.
+ *
+ * @param left a curve whose geometry will be set to the left half
+ * of <code>src</code>, or <code>null</code> if the caller is not
+ * interested in the left half.
+ *
+ * @param right a curve whose geometry will be set to the right half
+ * of <code>src</code>, or <code>null</code> if the caller is not
+ * interested in the right half.
+ */
+ public static void subdivide(QuadCurve2D src, QuadCurve2D left,
+ QuadCurve2D right)
+ {
+ src.subdivide(left, right);
+ }
+
+ /**
+ * Subdivides a quadratic curve into two halves, passing all
+ * coordinates in an array.
+ *
+ * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
+ * height="180" alt="A drawing that illustrates the effects of
+ * subdividing a QuadCurve2D" />
+ *
+ * <p>The left end point and the right start point will always be
+ * identical. Memory-concious programmers thus may want to pass the
+ * same array for both <code>left</code> and <code>right</code>, and
+ * set <code>rightOff</code> to <code>leftOff + 4</code>.
+ *
+ * @param src an array containing the coordinates of the curve to be
+ * subdivided. The <i>x</i> coordinate of the start point is
+ * located at <code>src[srcOff]</code>, its <i>y</i> at
+ * <code>src[srcOff + 1]</code>. The <i>x</i> coordinate of the
+ * control point is located at <code>src[srcOff + 2]</code>, its
+ * <i>y</i> at <code>src[srcOff + 3]</code>. The <i>x</i>
+ * coordinate of the end point is located at <code>src[srcOff +
+ * 4]</code>, its <i>y</i> at <code>src[srcOff + 5]</code>.
+ *
+ * @param srcOff an offset into <code>src</code>, specifying
+ * the index of the start point&#x2019;s <i>x</i> coordinate.
+ *
+ * @param left an array that will receive the coordinates of the
+ * left half of <code>src</code>. It is acceptable to pass
+ * <code>src</code>. A caller who is not interested in the left half
+ * can pass <code>null</code>.
+ *
+ * @param leftOff an offset into <code>left</code>, specifying the
+ * index where the start point&#x2019;s <i>x</i> coordinate will be
+ * stored.
+ *
+ * @param right an array that will receive the coordinates of the
+ * right half of <code>src</code>. It is acceptable to pass
+ * <code>src</code> or <code>left</code>. A caller who is not
+ * interested in the right half can pass <code>null</code>.
+ *
+ * @param rightOff an offset into <code>right</code>, specifying the
+ * index where the start point&#x2019;s <i>x</i> coordinate will be
+ * stored.
+ */
+ public static void subdivide(double[] src, int srcOff, double[] left,
+ int leftOff, double[] right, int rightOff)
+ {
+ double x1;
+ double y1;
+ double xc;
+ double yc;
+ double x2;
+ double y2;
+
+ x1 = src[srcOff];
+ y1 = src[srcOff + 1];
+ xc = src[srcOff + 2];
+ yc = src[srcOff + 3];
+ x2 = src[srcOff + 4];
+ y2 = src[srcOff + 5];
+
+ if (left != null)
+ {
+ left[leftOff] = x1;
+ left[leftOff + 1] = y1;
+ }
+
+ if (right != null)
+ {
+ right[rightOff + 4] = x2;
+ right[rightOff + 5] = y2;
+ }
+
+ x1 = (x1 + xc) / 2;
+ x2 = (xc + x2) / 2;
+ xc = (x1 + x2) / 2;
+ y1 = (y1 + yc) / 2;
+ y2 = (y2 + yc) / 2;
+ yc = (y1 + y2) / 2;
+
+ if (left != null)
+ {
+ left[leftOff + 2] = x1;
+ left[leftOff + 3] = y1;
+ left[leftOff + 4] = xc;
+ left[leftOff + 5] = yc;
+ }
+
+ if (right != null)
+ {
+ right[rightOff] = xc;
+ right[rightOff + 1] = yc;
+ right[rightOff + 2] = x2;
+ right[rightOff + 3] = y2;
+ }
+ }
+
+ /**
+ * Finds the non-complex roots of a quadratic equation, placing the
+ * results into the same array as the equation coefficients. The
+ * following equation is being solved:
+ *
+ * <blockquote><code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
+ * + <code>eqn[1]</code> &#xb7; <i>x</i>
+ * + <code>eqn[0]</code>
+ * = 0
+ * </blockquote>
+ *
+ * <p>For some background about solving quadratic equations, see the
+ * article <a href=
+ * "http://planetmath.org/encyclopedia/QuadraticFormula.html"
+ * >&#x201c;Quadratic Formula&#x201d;</a> in <a href=
+ * "http://planetmath.org/">PlanetMath</a>. For an extensive library
+ * of numerical algorithms written in the C programming language,
+ * see the <a href="http://www.gnu.org/software/gsl/">GNU Scientific
+ * Library</a>.
+ *
+ * @see #solveQuadratic(double[], double[])
+ * @see CubicCurve2D#solveCubic(double[], double[])
+ *
+ * @param eqn an array with the coefficients of the equation. When
+ * this procedure has returned, <code>eqn</code> will contain the
+ * non-complex solutions of the equation, in no particular order.
+ *
+ * @return the number of non-complex solutions. A result of 0
+ * indicates that the equation has no non-complex solutions. A
+ * result of -1 indicates that the equation is constant (i.e.,
+ * always or never zero).
+ *
+ * @author Brian Gough (bjg@network-theory.com)
+ * (original C implementation in the <a href=
+ * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * (adaptation to Java)
+ */
+ public static int solveQuadratic(double[] eqn)
+ {
+ return solveQuadratic(eqn, eqn);
+ }
+
+ /**
+ * Finds the non-complex roots of a quadratic equation. The
+ * following equation is being solved:
+ *
+ * <blockquote><code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
+ * + <code>eqn[1]</code> &#xb7; <i>x</i>
+ * + <code>eqn[0]</code>
+ * = 0
+ * </blockquote>
+ *
+ * <p>For some background about solving quadratic equations, see the
+ * article <a href=
+ * "http://planetmath.org/encyclopedia/QuadraticFormula.html"
+ * >&#x201c;Quadratic Formula&#x201d;</a> in <a href=
+ * "http://planetmath.org/">PlanetMath</a>. For an extensive library
+ * of numerical algorithms written in the C programming language,
+ * see the <a href="http://www.gnu.org/software/gsl/">GNU Scientific
+ * Library</a>.
+ *
+ * @see CubicCurve2D#solveCubic(double[],double[])
+ *
+ * @param eqn an array with the coefficients of the equation.
+ *
+ * @param res an array into which the non-complex roots will be
+ * stored. The results may be in an arbitrary order. It is safe to
+ * pass the same array object reference for both <code>eqn</code>
+ * and <code>res</code>.
+ *
+ * @return the number of non-complex solutions. A result of 0
+ * indicates that the equation has no non-complex solutions. A
+ * result of -1 indicates that the equation is constant (i.e.,
+ * always or never zero).
+ *
+ * @author Brian Gough (bjg@network-theory.com)
+ * (original C implementation in the <a href=
+ * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * (adaptation to Java)
+ */
+ public static int solveQuadratic(double[] eqn, double[] res)
+ {
+ // Taken from poly/solve_quadratic.c in the GNU Scientific Library
+ // (GSL), cvs revision 1.7 of 2003-07-26. For the original source,
+ // see http://www.gnu.org/software/gsl/
+ //
+ // Brian Gough, the author of that code, has granted the
+ // permission to use it in GNU Classpath under the GNU Classpath
+ // license, and has assigned the copyright to the Free Software
+ // Foundation.
+ //
+ // The Java implementation is very similar to the GSL code, but
+ // not a strict one-to-one copy. For example, GSL would sort the
+ // result.
+ double a;
+ double b;
+ double c;
+ double disc;
+
+ c = eqn[0];
+ b = eqn[1];
+ a = eqn[2];
+
+ // Check for linear or constant functions. This is not done by the
+ // GNU Scientific Library. Without this special check, we
+ // wouldn't return -1 for constant functions, and 2 instead of 1
+ // for linear functions.
+ if (a == 0)
+ {
+ if (b == 0)
+ return -1;
+
+ res[0] = -c / b;
+ return 1;
+ }
+
+ disc = b * b - 4 * a * c;
+
+ if (disc < 0)
+ return 0;
+
+ if (disc == 0)
+ {
+ // The GNU Scientific Library returns two identical results here.
+ // We just return one.
+ res[0] = -0.5 * b / a;
+ return 1;
+ }
+
+ // disc > 0
+ if (b == 0)
+ {
+ double r;
+
+ r = Math.abs(0.5 * Math.sqrt(disc) / a);
+ res[0] = -r;
+ res[1] = r;
+ }
+ else
+ {
+ double sgnb;
+ double temp;
+
+ sgnb = (b > 0 ? 1 : -1);
+ temp = -0.5 * (b + sgnb * Math.sqrt(disc));
+
+ // The GNU Scientific Library sorts the result here. We don't.
+ res[0] = temp / a;
+ res[1] = c / temp;
+ }
+ return 2;
+ }
+
+ /**
+ * Determines whether a point is inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; a QuadCurve2D.
+ */
+ public boolean contains(double x, double y)
+ {
+ if (! getBounds2D().contains(x, y))
+ return false;
+
+ return ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0);
+ }
+
+ /**
+ * Determines whether a point is inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; a QuadCurve2D.
+ */
+ public boolean contains(Point2D p)
+ {
+ return contains(p.getX(), p.getY());
+ }
+
+ /**
+ * Determines whether any part of a rectangle is inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; in a CubicCurve2D.
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ if (! getBounds2D().contains(x, y, w, h))
+ return false;
+
+ /* Does any edge intersect? */
+ if (getAxisIntersections(x, y, true, w) != 0 /* top */
+ || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
+ || getAxisIntersections(x + w, y, false, h) != 0 /* right */
+ || getAxisIntersections(x, y, false, h) != 0) /* left */
+ return true;
+
+ /* No intersections, is any point inside? */
+ if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Determines whether any part of a Rectangle2D is inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ * @see #intersects(double, double, double, double)
+ */
+ public boolean intersects(Rectangle2D r)
+ {
+ return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Determines whether a rectangle is entirely inside the area bounded
+ * by the curve and the straight line connecting its end points.
+ *
+ * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
+ * alt="A drawing of the area spanned by the curve" />
+ *
+ * <p>The above drawing illustrates in which area points are
+ * considered &#x201c;inside&#x201d; a QuadCurve2D.
+ * @see #contains(double, double)
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ if (! getBounds2D().intersects(x, y, w, h))
+ return false;
+
+ /* Does any edge intersect? */
+ if (getAxisIntersections(x, y, true, w) != 0 /* top */
+ || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
+ || getAxisIntersections(x + w, y, false, h) != 0 /* right */
+ || getAxisIntersections(x, y, false, h) != 0) /* left */
+ return false;
+
+ /* No intersections, is any point inside? */
+ if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Determines whether a Rectangle2D is entirely inside the area that is
+ * bounded by the curve and the straight line connecting its end points.
+ * @see #contains(double, double, double, double)
+ */
+ public boolean contains(Rectangle2D r)
+ {
+ return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Determines the smallest rectangle that encloses the
+ * curve&#x2019;s start, end and control point. As the illustration
+ * below shows, the invisible control point may cause the bounds to
+ * be much larger than the area that is actually covered by the
+ * curve.
+ *
+ * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
+ * alt="An illustration of the bounds of a QuadCurve2D" />
+ */
+ public Rectangle getBounds()
+ {
+ return getBounds2D().getBounds();
+ }
+
+ public PathIterator getPathIterator(final AffineTransform at)
+ {
+ return new PathIterator()
+ {
+ /** Current coordinate. */
+ private int current = 0;
+
+ public int getWindingRule()
+ {
+ return WIND_NON_ZERO;
+ }
+
+ public boolean isDone()
+ {
+ return current >= 2;
+ }
+
+ public void next()
+ {
+ current++;
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ int result;
+ switch (current)
+ {
+ case 0:
+ coords[0] = (float) getX1();
+ coords[1] = (float) getY1();
+ result = SEG_MOVETO;
+ break;
+ case 1:
+ coords[0] = (float) getCtrlX();
+ coords[1] = (float) getCtrlY();
+ coords[2] = (float) getX2();
+ coords[3] = (float) getY2();
+ result = SEG_QUADTO;
+ break;
+ default:
+ throw new NoSuchElementException("quad iterator out of bounds");
+ }
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 2);
+ return result;
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ int result;
+ switch (current)
+ {
+ case 0:
+ coords[0] = getX1();
+ coords[1] = getY1();
+ result = SEG_MOVETO;
+ break;
+ case 1:
+ coords[0] = getCtrlX();
+ coords[1] = getCtrlY();
+ coords[2] = getX2();
+ coords[3] = getY2();
+ result = SEG_QUADTO;
+ break;
+ default:
+ throw new NoSuchElementException("quad iterator out of bounds");
+ }
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 2);
+ return result;
+ }
+ };
+ }
+
+ public PathIterator getPathIterator(AffineTransform at, double flatness)
+ {
+ return new FlatteningPathIterator(getPathIterator(at), flatness);
+ }
+
+ /**
+ * Creates a new curve with the same contents as this one.
+ *
+ * @return the clone.
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+
+ /**
+ * Helper method used by contains() and intersects() methods
+ * Return the number of curve/line intersections on a given axis
+ * extending from a certain point. useYaxis is true for using the Y axis,
+ * @param x x coordinate of the origin point
+ * @param y y coordinate of the origin point
+ * @param useYaxis axis to follow, if true the positive Y axis is used,
+ * false uses the positive X axis.
+ *
+ * This is an implementation of the line-crossings algorithm,
+ * Detailed in an article on Eric Haines' page:
+ * http://www.acm.org/tog/editors/erich/ptinpoly/
+ */
+ private int getAxisIntersections(double x, double y, boolean useYaxis,
+ double distance)
+ {
+ int nCrossings = 0;
+ double a0;
+ double a1;
+ double a2;
+ double b0;
+ double b1;
+ double b2;
+ double[] r = new double[3];
+ int nRoots;
+
+ a0 = a2 = 0.0;
+
+ if (useYaxis)
+ {
+ a0 = getY1() - y;
+ a1 = getCtrlY() - y;
+ a2 = getY2() - y;
+ b0 = getX1() - x;
+ b1 = getCtrlX() - x;
+ b2 = getX2() - x;
+ }
+ else
+ {
+ a0 = getX1() - x;
+ a1 = getCtrlX() - x;
+ a2 = getX2() - x;
+ b0 = getY1() - y;
+ b1 = getCtrlY() - y;
+ b2 = getY2() - y;
+ }
+
+ /* If the axis intersects a start/endpoint, shift it up by some small
+ amount to guarantee the line is 'inside'
+ If this is not done,bad behaviour may result for points on that axis. */
+ if (a0 == 0.0 || a2 == 0.0)
+ {
+ double small = getFlatness() * EPSILON;
+ if (a0 == 0.0)
+ a0 -= small;
+
+ if (a2 == 0.0)
+ a2 -= small;
+ }
+
+ r[0] = a0;
+ r[1] = 2 * (a1 - a0);
+ r[2] = (a2 - 2 * a1 + a0);
+
+ nRoots = solveQuadratic(r);
+ for (int i = 0; i < nRoots; i++)
+ {
+ double t = r[i];
+ if (t >= 0.0 && t <= 1.0)
+ {
+ double crossing = t * t * (b2 - 2 * b1 + b0) + 2 * t * (b1 - b0)
+ + b0;
+ /* single root is always doubly degenerate in quads */
+ if (crossing > 0 && crossing < distance)
+ nCrossings += (nRoots == 1) ? 2 : 1;
+ }
+ }
+
+ if (useYaxis)
+ {
+ if (Line2D.linesIntersect(b0, a0, b2, a2, EPSILON, 0.0, distance, 0.0))
+ nCrossings++;
+ }
+ else
+ {
+ if (Line2D.linesIntersect(a0, b0, a2, b2, 0.0, EPSILON, 0.0, distance))
+ nCrossings++;
+ }
+
+ return (nCrossings);
+ }
+
+ /**
+ * A two-dimensional curve that is parameterized with a quadratic
+ * function and stores coordinate values in double-precision
+ * floating-point format.
+ *
+ * @see QuadCurve2D.Float
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ public static class Double extends QuadCurve2D
+ {
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s start point.
+ */
+ public double x1;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s start point.
+ */
+ public double y1;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s control point.
+ */
+ public double ctrlx;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s control point.
+ */
+ public double ctrly;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s end point.
+ */
+ public double x2;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s end point.
+ */
+ public double y2;
+
+ /**
+ * Constructs a new QuadCurve2D that stores its coordinate values
+ * in double-precision floating-point format. All points are
+ * initially at position (0, 0).
+ */
+ public Double()
+ {
+ }
+
+ /**
+ * Constructs a new QuadCurve2D that stores its coordinate values
+ * in double-precision floating-point format, specifying the
+ * initial position of each point.
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ *
+ * @param cx the <i>x</i> coordinate of the curve&#x2019;s control
+ * point.
+ *
+ * @param cy the <i>y</i> coordinate of the curve&#x2019;s control
+ * point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public Double(double x1, double y1, double cx, double cy, double x2,
+ double y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ ctrlx = cx;
+ ctrly = cy;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public double getX1()
+ {
+ return x1;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public double getY1()
+ {
+ return y1;
+ }
+
+ /**
+ * Returns the curve&#x2019;s start point.
+ */
+ public Point2D getP1()
+ {
+ return new Point2D.Double(x1, y1);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s control
+ * point.
+ */
+ public double getCtrlX()
+ {
+ return ctrlx;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s control
+ * point.
+ */
+ public double getCtrlY()
+ {
+ return ctrly;
+ }
+
+ /**
+ * Returns the curve&#x2019;s control point.
+ */
+ public Point2D getCtrlPt()
+ {
+ return new Point2D.Double(ctrlx, ctrly);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public double getX2()
+ {
+ return x2;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public double getY2()
+ {
+ return y2;
+ }
+
+ /**
+ * Returns the curve&#x2019;s end point.
+ */
+ public Point2D getP2()
+ {
+ return new Point2D.Double(x2, y2);
+ }
+
+ /**
+ * Changes the geometry of the curve.
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
+ * start point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
+ * start point.
+ *
+ * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
+ * control point.
+ *
+ * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
+ * control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
+ * end point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
+ * end point.
+ */
+ public void setCurve(double x1, double y1, double cx, double cy,
+ double x2, double y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ ctrlx = cx;
+ ctrly = cy;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Determines the smallest rectangle that encloses the
+ * curve&#x2019;s start, end and control point. As the
+ * illustration below shows, the invisible control point may cause
+ * the bounds to be much larger than the area that is actually
+ * covered by the curve.
+ *
+ * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
+ * alt="An illustration of the bounds of a QuadCurve2D" />
+ */
+ public Rectangle2D getBounds2D()
+ {
+ double nx1 = Math.min(Math.min(x1, ctrlx), x2);
+ double ny1 = Math.min(Math.min(y1, ctrly), y2);
+ double nx2 = Math.max(Math.max(x1, ctrlx), x2);
+ double ny2 = Math.max(Math.max(y1, ctrly), y2);
+ return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1);
+ }
+ }
+
+ /**
+ * A two-dimensional curve that is parameterized with a quadratic
+ * function and stores coordinate values in single-precision
+ * floating-point format.
+ *
+ * @see QuadCurve2D.Double
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ public static class Float extends QuadCurve2D
+ {
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s start point.
+ */
+ public float x1;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s start point.
+ */
+ public float y1;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s control point.
+ */
+ public float ctrlx;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s control point.
+ */
+ public float ctrly;
+
+ /**
+ * The <i>x</i> coordinate of the curve&#x2019;s end point.
+ */
+ public float x2;
+
+ /**
+ * The <i>y</i> coordinate of the curve&#x2019;s end point.
+ */
+ public float y2;
+
+ /**
+ * Constructs a new QuadCurve2D that stores its coordinate values
+ * in single-precision floating-point format. All points are
+ * initially at position (0, 0).
+ */
+ public Float()
+ {
+ }
+
+ /**
+ * Constructs a new QuadCurve2D that stores its coordinate values
+ * in single-precision floating-point format, specifying the
+ * initial position of each point.
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ *
+ * @param cx the <i>x</i> coordinate of the curve&#x2019;s control
+ * point.
+ *
+ * @param cy the <i>y</i> coordinate of the curve&#x2019;s control
+ * point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public Float(float x1, float y1, float cx, float cy, float x2, float y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ ctrlx = cx;
+ ctrly = cy;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public double getX1()
+ {
+ return x1;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s start
+ * point.
+ */
+ public double getY1()
+ {
+ return y1;
+ }
+
+ /**
+ * Returns the curve&#x2019;s start point.
+ */
+ public Point2D getP1()
+ {
+ return new Point2D.Float(x1, y1);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s control
+ * point.
+ */
+ public double getCtrlX()
+ {
+ return ctrlx;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s control
+ * point.
+ */
+ public double getCtrlY()
+ {
+ return ctrly;
+ }
+
+ /**
+ * Returns the curve&#x2019;s control point.
+ */
+ public Point2D getCtrlPt()
+ {
+ return new Point2D.Float(ctrlx, ctrly);
+ }
+
+ /**
+ * Returns the <i>x</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public double getX2()
+ {
+ return x2;
+ }
+
+ /**
+ * Returns the <i>y</i> coordinate of the curve&#x2019;s end
+ * point.
+ */
+ public double getY2()
+ {
+ return y2;
+ }
+
+ /**
+ * Returns the curve&#x2019;s end point.
+ */
+ public Point2D getP2()
+ {
+ return new Point2D.Float(x2, y2);
+ }
+
+ /**
+ * Changes the geometry of the curve, specifying coordinate values
+ * as double-precision floating-point numbers.
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
+ * start point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
+ * start point.
+ *
+ * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
+ * control point.
+ *
+ * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
+ * control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
+ * end point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
+ * end point.
+ */
+ public void setCurve(double x1, double y1, double cx, double cy,
+ double x2, double y2)
+ {
+ this.x1 = (float) x1;
+ this.y1 = (float) y1;
+ ctrlx = (float) cx;
+ ctrly = (float) cy;
+ this.x2 = (float) x2;
+ this.y2 = (float) y2;
+ }
+
+ /**
+ * Changes the geometry of the curve, specifying coordinate values
+ * as single-precision floating-point numbers.
+ *
+ * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
+ * start point.
+ *
+ * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
+ * start point.
+ *
+ * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
+ * control point.
+ *
+ * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
+ * control point.
+ *
+ * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
+ * end point.
+ *
+ * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
+ * end point.
+ */
+ public void setCurve(float x1, float y1, float cx, float cy, float x2,
+ float y2)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ ctrlx = cx;
+ ctrly = cy;
+ this.x2 = x2;
+ this.y2 = y2;
+ }
+
+ /**
+ * Determines the smallest rectangle that encloses the
+ * curve&#x2019;s start, end and control point. As the
+ * illustration below shows, the invisible control point may cause
+ * the bounds to be much larger than the area that is actually
+ * covered by the curve.
+ *
+ * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
+ * alt="An illustration of the bounds of a QuadCurve2D" />
+ */
+ public Rectangle2D getBounds2D()
+ {
+ float nx1 = (float) Math.min(Math.min(x1, ctrlx), x2);
+ float ny1 = (float) Math.min(Math.min(y1, ctrly), y2);
+ float nx2 = (float) Math.max(Math.max(x1, ctrlx), x2);
+ float ny2 = (float) Math.max(Math.max(y1, ctrly), y2);
+ return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1);
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/geom/Rectangle2D.java b/libjava/classpath/java/awt/geom/Rectangle2D.java
new file mode 100644
index 0000000..6a255f9
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/Rectangle2D.java
@@ -0,0 +1,992 @@
+/* Rectangle2D.java -- generic rectangles in 2-D space
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+/**
+ * This class describes a rectangle by a point (x,y) and dimension (w x h).
+ * The actual storage is left up to subclasses.
+ *
+ * <p>It is valid for a rectangle to have negative width or height; but it
+ * is considered to have no area or internal points. Therefore, the behavior
+ * in methods like <code>contains</code> or <code>intersects</code> is
+ * undefined unless the rectangle has positive width and height.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public abstract class Rectangle2D extends RectangularShape
+{
+ /**
+ * The point lies left of the rectangle (p.x &lt; r.x).
+ *
+ * @see #outcode(double, double)
+ */
+ public static final int OUT_LEFT = 1;
+
+ /**
+ * The point lies above the rectangle (p.y &lt; r.y).
+ *
+ * @see #outcode(double, double)
+ */
+ public static final int OUT_TOP = 2;
+
+ /**
+ * The point lies right of the rectangle (p.x &gt; r.maxX).
+ *
+ * @see #outcode(double, double)
+ */
+ public static final int OUT_RIGHT = 4;
+
+ /**
+ * The point lies below of the rectangle (p.y &gt; r.maxY).
+ *
+ * @see #outcode(double, double)
+ */
+ public static final int OUT_BOTTOM = 8;
+
+ /**
+ * Default constructor.
+ */
+ protected Rectangle2D()
+ {
+ }
+
+ /**
+ * Set the bounding box of this rectangle.
+ *
+ * @param x the new X coordinate
+ * @param y the new Y coordinate
+ * @param w the new width
+ * @param h the new height
+ */
+ public abstract void setRect(double x, double y, double w, double h);
+
+ /**
+ * Set the bounding box of this rectangle from the given one.
+ *
+ * @param r rectangle to copy
+ * @throws NullPointerException if r is null
+ */
+ public void setRect(Rectangle2D r)
+ {
+ setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Tests if the specified line intersects the interior of this rectangle.
+ *
+ * @param x1 the first x coordinate of line segment
+ * @param y1 the first y coordinate of line segment
+ * @param x2 the second x coordinate of line segment
+ * @param y2 the second y coordinate of line segment
+ * @return true if the line intersects the rectangle
+ */
+ public boolean intersectsLine(double x1, double y1, double x2, double y2)
+ {
+ double x = getX();
+ double y = getY();
+ double w = getWidth();
+ double h = getHeight();
+ if (w <= 0 || h <= 0)
+ return false;
+
+ if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h)
+ return true;
+ if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y + h)
+ return true;
+
+ double x3 = x + w;
+ double y3 = y + h;
+
+ return (Line2D.linesIntersect(x1, y1, x2, y2, x, y, x, y3)
+ || Line2D.linesIntersect(x1, y1, x2, y2, x, y3, x3, y3)
+ || Line2D.linesIntersect(x1, y1, x2, y2, x3, y3, x3, y)
+ || Line2D.linesIntersect(x1, y1, x2, y2, x3, y, x, y));
+ }
+
+ /**
+ * Tests if the specified line intersects the interior of this rectangle.
+ *
+ * @param l the line segment
+ * @return true if the line intersects the rectangle
+ * @throws NullPointerException if l is null
+ */
+ public boolean intersectsLine(Line2D l)
+ {
+ return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
+ }
+
+ /**
+ * Determine where the point lies with respect to this rectangle. The
+ * result will be the binary OR of the appropriate bit masks.
+ *
+ * @param x the x coordinate to check
+ * @param y the y coordinate to check
+ * @return the binary OR of the result
+ * @see #OUT_LEFT
+ * @see #OUT_TOP
+ * @see #OUT_RIGHT
+ * @see #OUT_BOTTOM
+ */
+ public abstract int outcode(double x, double y);
+
+ /**
+ * Determine where the point lies with respect to this rectangle. The
+ * result will be the binary OR of the appropriate bit masks.
+ *
+ * @param p the point to check
+ * @return the binary OR of the result
+ * @throws NullPointerException if p is null
+ * @see #OUT_LEFT
+ * @see #OUT_TOP
+ * @see #OUT_RIGHT
+ * @see #OUT_BOTTOM
+ */
+ public int outcode(Point2D p)
+ {
+ return outcode(p.getX(), p.getY());
+ }
+
+ /**
+ * Set the bounding box of this rectangle.
+ *
+ * @param x the new X coordinate
+ * @param y the new Y coordinate
+ * @param w the new width
+ * @param h the new height
+ */
+ public void setFrame(double x, double y, double w, double h)
+ {
+ setRect(x, y, w, h);
+ }
+
+ /**
+ * Returns the bounds of this rectangle. A pretty useless method, as this
+ * is already a rectangle.
+ *
+ * @return a copy of this rectangle
+ */
+ public Rectangle2D getBounds2D()
+ {
+ return (Rectangle2D) clone();
+ }
+
+ /**
+ * Test if the given point is contained in the rectangle.
+ *
+ * @param x the x coordinate of the point
+ * @param y the y coordinate of the point
+ * @return true if (x,y) is in the rectangle
+ */
+ public boolean contains(double x, double y)
+ {
+ double mx = getX();
+ double my = getY();
+ double w = getWidth();
+ double h = getHeight();
+ return w > 0 && h > 0 && x >= mx && x < mx + w && y >= my && y < my + h;
+ }
+
+ /**
+ * Tests if the given rectangle intersects this one. In other words, test if
+ * the two rectangles share at least one internal point.
+ *
+ * @param x the x coordinate of the other rectangle
+ * @param y the y coordinate of the other rectangle
+ * @param w the width of the other rectangle
+ * @param h the height of the other rectangle
+ * @return true if the rectangles intersect
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ double mx = getX();
+ double my = getY();
+ double mw = getWidth();
+ double mh = getHeight();
+ return w > 0 && h > 0 && mw > 0 && mh > 0
+ && x < mx + mw && x + w > mx && y < my + mh && y + h > my;
+ }
+
+ /**
+ * Tests if this rectangle contains the given one. In other words, test if
+ * this rectangle contains all points in the given one.
+ *
+ * @param x the x coordinate of the other rectangle
+ * @param y the y coordinate of the other rectangle
+ * @param w the width of the other rectangle
+ * @param h the height of the other rectangle
+ * @return true if this rectangle contains the other
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ double mx = getX();
+ double my = getY();
+ double mw = getWidth();
+ double mh = getHeight();
+ return w > 0 && h > 0 && mw > 0 && mh > 0
+ && x >= mx && x + w <= mx + mw && y >= my && y + h <= my + mh;
+ }
+
+ /**
+ * Return a new rectangle which is the intersection of this and the given
+ * one. The result will be empty if there is no intersection.
+ *
+ * @param r the rectangle to be intersected
+ * @return the intersection
+ * @throws NullPointerException if r is null
+ */
+ public abstract Rectangle2D createIntersection(Rectangle2D r);
+
+ /**
+ * Intersects a pair of rectangles, and places the result in the
+ * destination; this can be used to avoid object creation. This method
+ * even works when the destination is also a source, although you stand
+ * to lose the original data.
+ *
+ * @param src1 the first source
+ * @param src2 the second source
+ * @param dest the destination for the intersection
+ * @throws NullPointerException if any rectangle is null
+ */
+ public static void intersect(Rectangle2D src1, Rectangle2D src2,
+ Rectangle2D dest)
+ {
+ double x = Math.max(src1.getX(), src2.getX());
+ double y = Math.max(src1.getY(), src2.getY());
+ double maxx = Math.min(src1.getMaxX(), src2.getMaxX());
+ double maxy = Math.min(src1.getMaxY(), src2.getMaxY());
+ dest.setRect(x, y, maxx - x, maxy - y);
+ }
+
+ /**
+ * Return a new rectangle which is the union of this and the given one.
+ *
+ * @param r the rectangle to be merged
+ * @return the union
+ * @throws NullPointerException if r is null
+ */
+ public abstract Rectangle2D createUnion(Rectangle2D r);
+
+ /**
+ * Joins a pair of rectangles, and places the result in the destination;
+ * this can be used to avoid object creation. This method even works when
+ * the destination is also a source, although you stand to lose the
+ * original data.
+ *
+ * @param src1 the first source
+ * @param src2 the second source
+ * @param dest the destination for the union
+ * @throws NullPointerException if any rectangle is null
+ */
+ public static void union(Rectangle2D src1, Rectangle2D src2,
+ Rectangle2D dest)
+ {
+ double x = Math.min(src1.getX(), src2.getX());
+ double y = Math.min(src1.getY(), src2.getY());
+ double maxx = Math.max(src1.getMaxX(), src2.getMaxX());
+ double maxy = Math.max(src1.getMaxY(), src2.getMaxY());
+ dest.setRect(x, y, maxx - x, maxy - y);
+ }
+
+ /**
+ * Modifies this rectangle so that it represents the smallest rectangle
+ * that contains both the existing rectangle and the specified point.
+ * However, if the point falls on one of the two borders which are not
+ * inside the rectangle, a subsequent call to <code>contains</code> may
+ * return false.
+ *
+ * @param newx the X coordinate of the point to add to this rectangle
+ * @param newy the Y coordinate of the point to add to this rectangle
+ */
+ public void add(double newx, double newy)
+ {
+ double minx = Math.min(getX(), newx);
+ double maxx = Math.max(getMaxX(), newx);
+ double miny = Math.min(getY(), newy);
+ double maxy = Math.max(getMaxY(), newy);
+ setRect(minx, miny, maxx - minx, maxy - miny);
+ }
+
+ /**
+ * Modifies this rectangle so that it represents the smallest rectangle
+ * that contains both the existing rectangle and the specified point.
+ * However, if the point falls on one of the two borders which are not
+ * inside the rectangle, a subsequent call to <code>contains</code> may
+ * return false.
+ *
+ * @param p the point to add to this rectangle
+ * @throws NullPointerException if p is null
+ */
+ public void add(Point2D p)
+ {
+ add(p.getX(), p.getY());
+ }
+
+ /**
+ * Modifies this rectangle so that it represents the smallest rectangle
+ * that contains both the existing rectangle and the specified rectangle.
+ *
+ * @param r the rectangle to add to this rectangle
+ * @throws NullPointerException if r is null
+ * @see #union(Rectangle2D, Rectangle2D, Rectangle2D)
+ */
+ public void add(Rectangle2D r)
+ {
+ union(this, r, this);
+ }
+
+ /**
+ * Return an iterator along the shape boundary. If the optional transform
+ * is provided, the iterator is transformed accordingly. Each call returns
+ * a new object, independent from others in use. This iterator is thread
+ * safe; modifications to the rectangle do not affect the results of this
+ * path instance.
+ *
+ * @param at an optional transform to apply to the iterator
+ * @return a new iterator over the boundary
+ * @since 1.2
+ */
+ public PathIterator getPathIterator(final AffineTransform at)
+ {
+ final double minx = getX();
+ final double miny = getY();
+ final double maxx = minx + getWidth();
+ final double maxy = miny + getHeight();
+ return new PathIterator()
+ {
+ /** Current coordinate. */
+ private int current = (maxx <= minx && maxy <= miny) ? 6 : 0;
+
+ public int getWindingRule()
+ {
+ // A test program showed that Sun J2SE 1.3.1 and 1.4.1_01
+ // return WIND_NON_ZERO paths. While this does not really
+ // make any difference for rectangles (because they are not
+ // self-intersecting), it seems appropriate to behave
+ // identically.
+
+ return WIND_NON_ZERO;
+ }
+
+ public boolean isDone()
+ {
+ return current > 5;
+ }
+
+ public void next()
+ {
+ current++;
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ switch (current)
+ {
+ case 1:
+ coords[0] = (float) maxx;
+ coords[1] = (float) miny;
+ break;
+ case 2:
+ coords[0] = (float) maxx;
+ coords[1] = (float) maxy;
+ break;
+ case 3:
+ coords[0] = (float) minx;
+ coords[1] = (float) maxy;
+ break;
+ case 0:
+ case 4:
+ coords[0] = (float) minx;
+ coords[1] = (float) miny;
+ break;
+ case 5:
+ return SEG_CLOSE;
+ default:
+ throw new NoSuchElementException("rect iterator out of bounds");
+ }
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 1);
+ return current == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ switch (current)
+ {
+ case 1:
+ coords[0] = maxx;
+ coords[1] = miny;
+ break;
+ case 2:
+ coords[0] = maxx;
+ coords[1] = maxy;
+ break;
+ case 3:
+ coords[0] = minx;
+ coords[1] = maxy;
+ break;
+ case 0:
+ case 4:
+ coords[0] = minx;
+ coords[1] = miny;
+ break;
+ case 5:
+ return SEG_CLOSE;
+ default:
+ throw new NoSuchElementException("rect iterator out of bounds");
+ }
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 1);
+ return current == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+ };
+ }
+
+ /**
+ * Return an iterator along the shape boundary. If the optional transform
+ * is provided, the iterator is transformed accordingly. Each call returns
+ * a new object, independent from others in use. This iterator is thread
+ * safe; modifications to the rectangle do not affect the results of this
+ * path instance. As the rectangle is already flat, the flatness parameter
+ * is ignored.
+ *
+ * @param at an optional transform to apply to the iterator
+ * @param flatness the maximum distance for deviation from the real boundary
+ * @return a new iterator over the boundary
+ * @since 1.2
+ */
+ public PathIterator getPathIterator(AffineTransform at, double flatness)
+ {
+ return getPathIterator(at);
+ }
+
+ /**
+ * Return the hashcode for this rectangle. The formula is not documented, but
+ * appears to be the same as:
+ * <pre>
+ * long l = Double.doubleToLongBits(getX())
+ * + 37 * Double.doubleToLongBits(getY())
+ * + 43 * Double.doubleToLongBits(getWidth())
+ * + 47 * Double.doubleToLongBits(getHeight());
+ * return (int) ((l &gt;&gt; 32) ^ l);
+ * </pre>
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ // Talk about a fun time reverse engineering this one!
+ long l = java.lang.Double.doubleToLongBits(getX())
+ + 37 * java.lang.Double.doubleToLongBits(getY())
+ + 43 * java.lang.Double.doubleToLongBits(getWidth())
+ + 47 * java.lang.Double.doubleToLongBits(getHeight());
+ return (int) ((l >> 32) ^ l);
+ }
+
+ /**
+ * Tests this rectangle for equality against the specified object. This
+ * will be true if an only if the specified object is an instance of
+ * Rectangle2D with the same coordinates and dimensions.
+ *
+ * @param obj the object to test against for equality
+ * @return true if the specified object is equal to this one
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof Rectangle2D))
+ return false;
+ Rectangle2D r = (Rectangle2D) obj;
+ return r.getX() == getX() && r.getY() == getY()
+ && r.getWidth() == getWidth() && r.getHeight() == getHeight();
+ }
+
+ /**
+ * This class defines a rectangle in <code>double</code> precision.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+ public static class Double extends Rectangle2D
+ {
+ /** The x coordinate of the lower left corner. */
+ public double x;
+
+ /** The y coordinate of the lower left corner. */
+ public double y;
+
+ /** The width of the rectangle. */
+ public double width;
+
+ /** The height of the rectangle. */
+ public double height;
+
+ /**
+ * Create a rectangle at (0,0) with width 0 and height 0.
+ */
+ public Double()
+ {
+ }
+
+ /**
+ * Create a rectangle with the given values.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ public Double(double x, double y, double w, double h)
+ {
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ }
+
+ /**
+ * Return the X coordinate.
+ *
+ * @return the value of x
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Return the Y coordinate.
+ *
+ * @return the value of y
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Return the width.
+ *
+ * @return the value of width
+ */
+ public double getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Return the height.
+ *
+ * @return the value of height
+ */
+ public double getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Test if the rectangle is empty.
+ *
+ * @return true if width or height is not positive
+ */
+ public boolean isEmpty()
+ {
+ return width <= 0 || height <= 0;
+ }
+
+ /**
+ * Set the contents of this rectangle to those specified.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ public void setRect(double x, double y, double w, double h)
+ {
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ }
+
+ /**
+ * Set the contents of this rectangle to those specified.
+ *
+ * @param r the rectangle to copy
+ * @throws NullPointerException if r is null
+ */
+ public void setRect(Rectangle2D r)
+ {
+ x = r.getX();
+ y = r.getY();
+ width = r.getWidth();
+ height = r.getHeight();
+ }
+
+ /**
+ * Determine where the point lies with respect to this rectangle. The
+ * result will be the binary OR of the appropriate bit masks.
+ *
+ * @param x the x coordinate to check
+ * @param y the y coordinate to check
+ * @return the binary OR of the result
+ * @see #OUT_LEFT
+ * @see #OUT_TOP
+ * @see #OUT_RIGHT
+ * @see #OUT_BOTTOM
+ * @since 1.2
+ */
+ public int outcode(double x, double y)
+ {
+ int result = 0;
+ if (width <= 0)
+ result |= OUT_LEFT | OUT_RIGHT;
+ else if (x < this.x)
+ result |= OUT_LEFT;
+ else if (x > this.x + width)
+ result |= OUT_RIGHT;
+ if (height <= 0)
+ result |= OUT_BOTTOM | OUT_TOP;
+ else if (y < this.y) // Remember that +y heads top-to-bottom.
+ result |= OUT_TOP;
+ else if (y > this.y + height)
+ result |= OUT_BOTTOM;
+ return result;
+ }
+
+ /**
+ * Returns the bounds of this rectangle. A pretty useless method, as this
+ * is already a rectangle.
+ *
+ * @return a copy of this rectangle
+ */
+ public Rectangle2D getBounds2D()
+ {
+ return new Double(x, y, width, height);
+ }
+
+ /**
+ * Return a new rectangle which is the intersection of this and the given
+ * one. The result will be empty if there is no intersection.
+ *
+ * @param r the rectangle to be intersected
+ * @return the intersection
+ * @throws NullPointerException if r is null
+ */
+ public Rectangle2D createIntersection(Rectangle2D r)
+ {
+ Double res = new Double();
+ intersect(this, r, res);
+ return res;
+ }
+
+ /**
+ * Return a new rectangle which is the union of this and the given one.
+ *
+ * @param r the rectangle to be merged
+ * @return the union
+ * @throws NullPointerException if r is null
+ */
+ public Rectangle2D createUnion(Rectangle2D r)
+ {
+ Double res = new Double();
+ union(this, r, res);
+ return res;
+ }
+
+ /**
+ * Returns a string representation of this rectangle. This is in the form
+ * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
+ * + ",h=" + height + ']'</code>.
+ *
+ * @return a string representation of this rectangle
+ */
+ public String toString()
+ {
+ return getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
+ + ",h=" + height + ']';
+ }
+ }
+
+ /**
+ * This class defines a rectangle in <code>float</code> precision.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+ public static class Float extends Rectangle2D
+ {
+ /** The x coordinate of the lower left corner. */
+ public float x;
+
+ /** The y coordinate of the lower left corner. */
+ public float y;
+
+ /** The width of the rectangle. */
+ public float width;
+
+ /** The height of the rectangle. */
+ public float height;
+
+ /**
+ * Create a rectangle at (0,0) with width 0 and height 0.
+ */
+ public Float()
+ {
+ }
+
+ /**
+ * Create a rectangle with the given values.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ public Float(float x, float y, float w, float h)
+ {
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ }
+
+ /**
+ * Create a rectangle with the given values.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ Float(double x, double y, double w, double h)
+ {
+ this.x = (float) x;
+ this.y = (float) y;
+ width = (float) w;
+ height = (float) h;
+ }
+
+ /**
+ * Return the X coordinate.
+ *
+ * @return the value of x
+ */
+ public double getX()
+ {
+ return x;
+ }
+
+ /**
+ * Return the Y coordinate.
+ *
+ * @return the value of y
+ */
+ public double getY()
+ {
+ return y;
+ }
+
+ /**
+ * Return the width.
+ *
+ * @return the value of width
+ */
+ public double getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Return the height.
+ *
+ * @return the value of height
+ */
+ public double getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Test if the rectangle is empty.
+ *
+ * @return true if width or height is not positive
+ */
+ public boolean isEmpty()
+ {
+ return width <= 0 || height <= 0;
+ }
+
+ /**
+ * Set the contents of this rectangle to those specified.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ public void setRect(float x, float y, float w, float h)
+ {
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ }
+
+ /**
+ * Set the contents of this rectangle to those specified.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ public void setRect(double x, double y, double w, double h)
+ {
+ this.x = (float) x;
+ this.y = (float) y;
+ width = (float) w;
+ height = (float) h;
+ }
+
+ /**
+ * Set the contents of this rectangle to those specified.
+ *
+ * @param r the rectangle to copy
+ * @throws NullPointerException if r is null
+ */
+ public void setRect(Rectangle2D r)
+ {
+ x = (float) r.getX();
+ y = (float) r.getY();
+ width = (float) r.getWidth();
+ height = (float) r.getHeight();
+ }
+
+ /**
+ * Determine where the point lies with respect to this rectangle. The
+ * result will be the binary OR of the appropriate bit masks.
+ *
+ * @param x the x coordinate to check
+ * @param y the y coordinate to check
+ * @return the binary OR of the result
+ * @see #OUT_LEFT
+ * @see #OUT_TOP
+ * @see #OUT_RIGHT
+ * @see #OUT_BOTTOM
+ * @since 1.2
+ */
+ public int outcode(double x, double y)
+ {
+ int result = 0;
+ if (width <= 0)
+ result |= OUT_LEFT | OUT_RIGHT;
+ else if (x < this.x)
+ result |= OUT_LEFT;
+ else if (x > this.x + width)
+ result |= OUT_RIGHT;
+ if (height <= 0)
+ result |= OUT_BOTTOM | OUT_TOP;
+ else if (y < this.y) // Remember that +y heads top-to-bottom.
+ result |= OUT_TOP;
+ else if (y > this.y + height)
+ result |= OUT_BOTTOM;
+ return result;
+ }
+
+ /**
+ * Returns the bounds of this rectangle. A pretty useless method, as this
+ * is already a rectangle.
+ *
+ * @return a copy of this rectangle
+ */
+ public Rectangle2D getBounds2D()
+ {
+ return new Float(x, y, width, height);
+ }
+
+ /**
+ * Return a new rectangle which is the intersection of this and the given
+ * one. The result will be empty if there is no intersection.
+ *
+ * @param r the rectangle to be intersected
+ * @return the intersection
+ * @throws NullPointerException if r is null
+ */
+ public Rectangle2D createIntersection(Rectangle2D r)
+ {
+ Float res = new Float();
+ intersect(this, r, res);
+ return res;
+ }
+
+ /**
+ * Return a new rectangle which is the union of this and the given one.
+ *
+ * @param r the rectangle to be merged
+ * @return the union
+ * @throws NullPointerException if r is null
+ */
+ public Rectangle2D createUnion(Rectangle2D r)
+ {
+ Float res = new Float();
+ union(this, r, res);
+ return res;
+ }
+
+ /**
+ * Returns a string representation of this rectangle. This is in the form
+ * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
+ * + ",h=" + height + ']'</code>.
+ *
+ * @return a string representation of this rectangle
+ */
+ public String toString()
+ {
+ return getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
+ + ",h=" + height + ']';
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/geom/RectangularShape.java b/libjava/classpath/java/awt/geom/RectangularShape.java
new file mode 100644
index 0000000..8f66dab
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/RectangularShape.java
@@ -0,0 +1,385 @@
+/* RectangularShape.java -- a rectangular frame for several generic shapes
+ Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+/**
+ * This class provides a generic framework, and several helper methods, for
+ * subclasses which represent geometric objects inside a rectangular frame.
+ * This does not specify any geometry except for the bounding box.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @see Arc2D
+ * @see Ellipse2D
+ * @see Rectangle2D
+ * @see RoundRectangle2D
+ * @status updated to 1.4
+ */
+public abstract class RectangularShape implements Shape, Cloneable
+{
+ /**
+ * Default constructor.
+ */
+ protected RectangularShape()
+ {
+ }
+
+ /**
+ * Get the x coordinate of the upper-left corner of the framing rectangle.
+ *
+ * @return the x coordinate
+ */
+ public abstract double getX();
+
+ /**
+ * Get the y coordinate of the upper-left corner of the framing rectangle.
+ *
+ * @return the y coordinate
+ */
+ public abstract double getY();
+
+ /**
+ * Get the width of the framing rectangle.
+ *
+ * @return the width
+ */
+ public abstract double getWidth();
+
+ /**
+ * Get the height of the framing rectangle.
+ *
+ * @return the height
+ */
+ public abstract double getHeight();
+
+ /**
+ * Get the minimum x coordinate in the frame. This is misnamed, or else
+ * Sun has a bug, because the implementation returns getX() even when
+ * getWidth() is negative.
+ *
+ * @return the minimum x coordinate
+ */
+ public double getMinX()
+ {
+ return getX();
+ }
+
+ /**
+ * Get the minimum y coordinate in the frame. This is misnamed, or else
+ * Sun has a bug, because the implementation returns getY() even when
+ * getHeight() is negative.
+ *
+ * @return the minimum y coordinate
+ */
+ public double getMinY()
+ {
+ return getY();
+ }
+
+ /**
+ * Get the maximum x coordinate in the frame. This is misnamed, or else
+ * Sun has a bug, because the implementation returns getX()+getWidth() even
+ * when getWidth() is negative.
+ *
+ * @return the maximum x coordinate
+ */
+ public double getMaxX()
+ {
+ return getX() + getWidth();
+ }
+
+ /**
+ * Get the maximum y coordinate in the frame. This is misnamed, or else
+ * Sun has a bug, because the implementation returns getY()+getHeight() even
+ * when getHeight() is negative.
+ *
+ * @return the maximum y coordinate
+ */
+ public double getMaxY()
+ {
+ return getY() + getHeight();
+ }
+
+ /**
+ * Return the x coordinate of the center point of the framing rectangle.
+ *
+ * @return the central x coordinate
+ */
+ public double getCenterX()
+ {
+ return getX() + getWidth() / 2;
+ }
+
+ /**
+ * Return the y coordinate of the center point of the framing rectangle.
+ *
+ * @return the central y coordinate
+ */
+ public double getCenterY()
+ {
+ return getY() + getHeight() / 2;
+ }
+
+ /**
+ * Return the frame around this object. Note that this may be a looser
+ * bounding box than getBounds2D.
+ *
+ * @return the frame, in double precision
+ * @see #setFrame(double, double, double, double)
+ */
+ public Rectangle2D getFrame()
+ {
+ return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
+ }
+
+ /**
+ * Test if the shape is empty, meaning that no points are inside it.
+ *
+ * @return true if the shape is empty
+ */
+ public abstract boolean isEmpty();
+
+ /**
+ * Set the framing rectangle of this shape to the given coordinate and size.
+ *
+ * @param x the new x coordinate
+ * @param y the new y coordinate
+ * @param w the new width
+ * @param h the new height
+ * @see #getFrame()
+ */
+ public abstract void setFrame(double x, double y, double w, double h);
+
+ /**
+ * Set the framing rectangle of this shape to the given coordinate and size.
+ *
+ * @param p the new point
+ * @param d the new dimension
+ * @throws NullPointerException if p or d is null
+ * @see #getFrame()
+ */
+ public void setFrame(Point2D p, Dimension2D d)
+ {
+ setFrame(p.getX(), p.getY(), d.getWidth(), d.getHeight());
+ }
+
+ /**
+ * Set the framing rectangle of this shape to the given rectangle.
+ *
+ * @param r the new framing rectangle
+ * @throws NullPointerException if r is null
+ * @see #getFrame()
+ */
+ public void setFrame(Rectangle2D r)
+ {
+ setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Set the framing rectangle of this shape using two points on a diagonal.
+ * The area will be positive.
+ *
+ * @param x1 the first x coordinate
+ * @param y1 the first y coordinate
+ * @param x2 the second x coordinate
+ * @param y2 the second y coordinate
+ */
+ public void setFrameFromDiagonal(double x1, double y1, double x2, double y2)
+ {
+ if (x1 > x2)
+ {
+ double t = x2;
+ x2 = x1;
+ x1 = t;
+ }
+ if (y1 > y2)
+ {
+ double t = y2;
+ y2 = y1;
+ y1 = t;
+ }
+ setFrame(x1, y1, x2 - x1, y2 - y1);
+ }
+
+ /**
+ * Set the framing rectangle of this shape using two points on a diagonal.
+ * The area will be positive.
+ *
+ * @param p1 the first point
+ * @param p2 the second point
+ * @throws NullPointerException if either point is null
+ */
+ public void setFrameFromDiagonal(Point2D p1, Point2D p2)
+ {
+ setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+ }
+
+ /**
+ * Set the framing rectangle of this shape using the center of the frame,
+ * and one of the four corners. The area will be positive.
+ *
+ * @param centerX the x coordinate at the center
+ * @param centerY the y coordinate at the center
+ * @param cornerX the x coordinate at a corner
+ * @param cornerY the y coordinate at a corner
+ */
+ public void setFrameFromCenter(double centerX, double centerY,
+ double cornerX, double cornerY)
+ {
+ double halfw = Math.abs(cornerX - centerX);
+ double halfh = Math.abs(cornerY - centerY);
+ setFrame(centerX - halfw, centerY - halfh, halfw + halfw, halfh + halfh);
+ }
+
+ /**
+ * Set the framing rectangle of this shape using the center of the frame,
+ * and one of the four corners. The area will be positive.
+ *
+ * @param center the center point
+ * @param corner a corner point
+ * @throws NullPointerException if either point is null
+ */
+ public void setFrameFromCenter(Point2D center, Point2D corner)
+ {
+ setFrameFromCenter(center.getX(), center.getY(),
+ corner.getX(), corner.getY());
+ }
+
+ /**
+ * Tests if a point is inside the boundary of the shape.
+ *
+ * @param p the point to test
+ * @return true if the point is inside the shape
+ * @throws NullPointerException if p is null
+ * @see #contains(double, double)
+ */
+ public boolean contains(Point2D p)
+ {
+ return contains(p.getX(), p.getY());
+ }
+
+ /**
+ * Tests if a rectangle and this shape share common internal points.
+ *
+ * @param r the rectangle to test
+ * @return true if the rectangle intersects this shpae
+ * @throws NullPointerException if r is null
+ * @see #intersects(double, double, double, double)
+ */
+ public boolean intersects(Rectangle2D r)
+ {
+ return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Tests if the shape completely contains the given rectangle.
+ *
+ * @param r the rectangle to test
+ * @return true if r is contained in this shape
+ * @throws NullPointerException if r is null
+ * @see #contains(double, double, double, double)
+ */
+ public boolean contains(Rectangle2D r)
+ {
+ return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+
+ /**
+ * Returns a bounding box for this shape, in integer format. Notice that you
+ * may get a tighter bound with getBounds2D. If the frame is empty, the
+ * box is the default empty box at the origin.
+ *
+ * @return a bounding box
+ */
+ public Rectangle getBounds()
+ {
+ if (isEmpty())
+ return new Rectangle();
+ double x = getX();
+ double y = getY();
+ double maxx = Math.ceil(x + getWidth());
+ double maxy = Math.ceil(y + getHeight());
+ x = Math.floor(x);
+ y = Math.floor(y);
+ return new Rectangle((int) x, (int) y, (int) (maxx - x), (int) (maxy - y));
+ }
+
+ /**
+ * Return an iterator along the shape boundary. If the optional transform
+ * is provided, the iterator is transformed accordingly. The path is
+ * flattened until all segments differ from the curve by at most the value
+ * of the flatness parameter, within the limits of the default interpolation
+ * recursion limit of 1024 segments between actual points. Each call
+ * returns a new object, independent from others in use. The result is
+ * threadsafe if and only if the iterator returned by
+ * {@link #getPathIterator(AffineTransform)} is as well.
+ *
+ * @param at an optional transform to apply to the iterator
+ * @param flatness the desired flatness
+ * @return a new iterator over the boundary
+ * @throws IllegalArgumentException if flatness is invalid
+ * @since 1.2
+ */
+ public PathIterator getPathIterator(AffineTransform at, double flatness)
+ {
+ return new FlatteningPathIterator(getPathIterator(at), flatness);
+ }
+
+ /**
+ * Create a new shape of the same run-time type with the same contents as
+ * this one.
+ *
+ * @return the clone
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+} // class RectangularShape
diff --git a/libjava/classpath/java/awt/geom/RoundRectangle2D.java b/libjava/classpath/java/awt/geom/RoundRectangle2D.java
new file mode 100644
index 0000000..ac0e6f8
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/RoundRectangle2D.java
@@ -0,0 +1,533 @@
+/* RoundRectangle2D.java -- represents a rectangle with rounded corners
+ Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+
+/** This class implements a rectangle with rounded corners.
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @date December 3, 2000
+ */
+public abstract class RoundRectangle2D extends RectangularShape
+{
+ /** Return the arc height of this round rectangle. */
+ public abstract double getArcHeight();
+
+ /** Return the arc width of this round rectangle. */
+ public abstract double getArcWidth();
+
+ /** Set the values of this round rectangle
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param w The width
+ * @param h The height
+ * @param arcWidth The arc width
+ * @param arcHeight The arc height
+ */
+ public abstract void setRoundRect(double x, double y, double w, double h,
+ double arcWidth, double arcHeight);
+
+ /** Create a RoundRectangle2D. This is protected because this class
+ * is abstract and cannot be instantiated.
+ */
+ protected RoundRectangle2D()
+ {
+ }
+
+ /** Return true if this object contains the specified point.
+ * @param x The x coordinate
+ * @param y The y coordinate
+ */
+ public boolean contains(double x, double y)
+ {
+ double mx = getX();
+ double mw = getWidth();
+ if (x < mx || x >= mx + mw)
+ return false;
+ double my = getY();
+ double mh = getHeight();
+ if (y < my || y >= my + mh)
+ return false;
+
+ // Now check to see if the point is in range of an arc.
+ double dy = Math.min(Math.abs(my - y), Math.abs(my + mh - y));
+ double dx = Math.min(Math.abs(mx - x), Math.abs(mx + mw - x));
+
+ // The arc dimensions are that of the corresponding ellipse
+ // thus a 90 degree segment is half of that.
+ double aw = getArcWidth() / 2.0;
+ double ah = getArcHeight() / 2.0;
+ if (dx > aw || dy > ah)
+ return true;
+
+ // At this point DX represents the distance from the nearest edge
+ // of the rectangle. But we want to transform it to represent the
+ // scaled distance from the center of the ellipse that forms the
+ // arc. Hence this code:
+ dy = (ah - dy) / ah;
+ dx = (aw - dx) / aw;
+
+ return dx * dx + dy * dy <= 1.0;
+ }
+
+ /** Return true if this object contains the specified rectangle
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param w The width
+ * @param h The height
+ */
+ public boolean contains(double x, double y, double w, double h)
+ {
+ // We have to check all four points here (for ordinary rectangles
+ // we can just check opposing corners).
+ return (contains(x, y) && contains(x, y + h) && contains(x + w, y + h)
+ && contains(x + w, y));
+ }
+
+ /** Return a new path iterator which iterates over this rectangle.
+ * @param at An affine transform to apply to the object
+ */
+ public PathIterator getPathIterator(final AffineTransform at)
+ {
+ final double minx = getX();
+ final double miny = getY();
+ final double maxx = minx + getWidth();
+ final double maxy = miny + getHeight();
+ final double arcwidth = getArcWidth();
+ final double archeight = getArcHeight();
+ return new PathIterator()
+ {
+ /** We iterate counterclockwise around the rectangle, starting in the
+ * upper right. This variable tracks our current point, which
+ * can be on either side of a given corner. */
+ private int current = 0;
+
+ /** Child path iterator, used for corners. */
+ private PathIterator corner;
+
+ /** This is used when rendering the corners. We re-use the arc
+ * for each corner. */
+ private Arc2D arc = new Arc2D.Double();
+
+ /** Temporary array used by getPoint. */
+ private double[] temp = new double[2];
+
+ public int getWindingRule()
+ {
+ return WIND_NON_ZERO;
+ }
+
+ public boolean isDone()
+ {
+ return current > 9;
+ }
+
+ private void getPoint(int val)
+ {
+ switch (val)
+ {
+ case 0:
+ case 8:
+ temp[0] = maxx;
+ temp[1] = miny + archeight;
+ break;
+ case 7:
+ temp[0] = maxx;
+ temp[1] = maxy - archeight;
+ break;
+ case 6:
+ temp[0] = maxx - arcwidth;
+ temp[1] = maxy;
+ break;
+ case 5:
+ temp[0] = minx + arcwidth;
+ temp[1] = maxy;
+ break;
+ case 4:
+ temp[0] = minx;
+ temp[1] = maxy - archeight;
+ break;
+ case 3:
+ temp[0] = minx;
+ temp[1] = miny + archeight;
+ break;
+ case 2:
+ temp[0] = minx + arcwidth;
+ temp[1] = miny;
+ break;
+ case 1:
+ temp[0] = maxx - arcwidth;
+ temp[1] = miny;
+ break;
+ }
+ }
+
+ public void next()
+ {
+ if (current >= 8)
+ ++current;
+ else if (corner != null)
+ {
+ // We're iterating through the corner. Work on the child
+ // iterator; if it finishes, reset and move to the next
+ // point along the rectangle.
+ corner.next();
+ if (corner.isDone())
+ {
+ corner = null;
+ ++current;
+ }
+ }
+ else
+ {
+ // Make an arc between this point on the rectangle and
+ // the next one, and then iterate over this arc.
+ getPoint(current);
+ double x1 = temp[0];
+ double y1 = temp[1];
+ getPoint(current + 1);
+ Rectangle2D.Double r = new Rectangle2D.Double(Math.min(x1,
+ temp[0]),
+ Math.min(y1,
+ temp[1]),
+ Math.abs(x1
+ - temp[0]),
+ Math.abs(y1
+ - temp[1]));
+ arc.setArc(r, (current >> 1) * 90.0, 90.0, Arc2D.OPEN);
+ corner = arc.getPathIterator(at);
+ }
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ if (corner != null)
+ {
+ int r = corner.currentSegment(coords);
+ if (r == SEG_MOVETO)
+ r = SEG_LINETO;
+ return r;
+ }
+
+ if (current < 9)
+ {
+ getPoint(current);
+ coords[0] = (float) temp[0];
+ coords[1] = (float) temp[1];
+ }
+ else if (current == 9)
+ return SEG_CLOSE;
+ else
+ throw new NoSuchElementException("rect iterator out of bounds");
+
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 1);
+ return current == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ if (corner != null)
+ {
+ int r = corner.currentSegment(coords);
+ if (r == SEG_MOVETO)
+ r = SEG_LINETO;
+ return r;
+ }
+
+ if (current < 9)
+ {
+ getPoint(current);
+ coords[0] = temp[0];
+ coords[1] = temp[1];
+ }
+ else if (current == 9)
+ return SEG_CLOSE;
+ else
+ throw new NoSuchElementException("rect iterator out of bounds");
+
+ if (at != null)
+ at.transform(coords, 0, coords, 0, 1);
+ return current == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+ };
+ }
+
+ /** Return true if the given rectangle intersects this shape.
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param w The width
+ * @param h The height
+ */
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ // Check if any corner is within the rectangle
+ return (contains(x, y) || contains(x, y + h) || contains(x + w, y + h)
+ || contains(x + w, y));
+ }
+
+ /** Set the boundary of this round rectangle.
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param w The width
+ * @param h The height
+ */
+ public void setFrame(double x, double y, double w, double h)
+ {
+ // This is a bit lame.
+ setRoundRect(x, y, w, h, getArcWidth(), getArcHeight());
+ }
+
+ /** Set the values of this round rectangle to be the same as those
+ * of the argument.
+ * @param rr The round rectangle to copy
+ */
+ public void setRoundRect(RoundRectangle2D rr)
+ {
+ setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(),
+ rr.getArcWidth(), rr.getArcHeight());
+ }
+
+ /** A subclass of RoundRectangle which keeps its parameters as
+ * doubles. */
+ public static class Double extends RoundRectangle2D
+ {
+ /** The height of the corner arc. */
+ public double archeight;
+
+ /** The width of the corner arc. */
+ public double arcwidth;
+
+ /** The x coordinate of this object. */
+ public double x;
+
+ /** The y coordinate of this object. */
+ public double y;
+
+ /** The width of this object. */
+ public double width;
+
+ /** The height of this object. */
+ public double height;
+
+ /** Construct a new instance, with all parameters set to 0. */
+ public Double()
+ {
+ }
+
+ /** Construct a new instance with the given arguments.
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param w The width
+ * @param h The height
+ * @param arcWidth The arc width
+ * @param arcHeight The arc height
+ */
+ public Double(double x, double y, double w, double h, double arcWidth,
+ double arcHeight)
+ {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ this.arcwidth = arcWidth;
+ this.archeight = arcHeight;
+ }
+
+ public double getArcHeight()
+ {
+ return archeight;
+ }
+
+ public double getArcWidth()
+ {
+ return arcwidth;
+ }
+
+ public Rectangle2D getBounds2D()
+ {
+ return new Rectangle2D.Double(x, y, width, height);
+ }
+
+ public double getX()
+ {
+ return x;
+ }
+
+ public double getY()
+ {
+ return y;
+ }
+
+ public double getWidth()
+ {
+ return width;
+ }
+
+ public double getHeight()
+ {
+ return height;
+ }
+
+ public boolean isEmpty()
+ {
+ return width <= 0 || height <= 0;
+ }
+
+ public void setRoundRect(double x, double y, double w, double h,
+ double arcWidth, double arcHeight)
+ {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ this.arcwidth = arcWidth;
+ this.archeight = arcHeight;
+ }
+ } // class Double
+
+ /** A subclass of RoundRectangle which keeps its parameters as
+ * floats. */
+ public static class Float extends RoundRectangle2D
+ {
+ /** The height of the corner arc. */
+ public float archeight;
+
+ /** The width of the corner arc. */
+ public float arcwidth;
+
+ /** The x coordinate of this object. */
+ public float x;
+
+ /** The y coordinate of this object. */
+ public float y;
+
+ /** The width of this object. */
+ public float width;
+
+ /** The height of this object. */
+ public float height;
+
+ /** Construct a new instance, with all parameters set to 0. */
+ public Float()
+ {
+ }
+
+ /** Construct a new instance with the given arguments.
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param w The width
+ * @param h The height
+ * @param arcWidth The arc width
+ * @param arcHeight The arc height
+ */
+ public Float(float x, float y, float w, float h, float arcWidth,
+ float arcHeight)
+ {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ this.arcwidth = arcWidth;
+ this.archeight = arcHeight;
+ }
+
+ public double getArcHeight()
+ {
+ return archeight;
+ }
+
+ public double getArcWidth()
+ {
+ return arcwidth;
+ }
+
+ public Rectangle2D getBounds2D()
+ {
+ return new Rectangle2D.Float(x, y, width, height);
+ }
+
+ public double getX()
+ {
+ return x;
+ }
+
+ public double getY()
+ {
+ return y;
+ }
+
+ public double getWidth()
+ {
+ return width;
+ }
+
+ public double getHeight()
+ {
+ return height;
+ }
+
+ public boolean isEmpty()
+ {
+ return width <= 0 || height <= 0;
+ }
+
+ public void setRoundRect(float x, float y, float w, float h,
+ float arcWidth, float arcHeight)
+ {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ this.arcwidth = arcWidth;
+ this.archeight = arcHeight;
+ }
+
+ public void setRoundRect(double x, double y, double w, double h,
+ double arcWidth, double arcHeight)
+ {
+ this.x = (float) x;
+ this.y = (float) y;
+ this.width = (float) w;
+ this.height = (float) h;
+ this.arcwidth = (float) arcWidth;
+ this.archeight = (float) arcHeight;
+ }
+ } // class Float
+} // class RoundRectangle2D
diff --git a/libjava/classpath/java/awt/geom/doc-files/Area-1.png b/libjava/classpath/java/awt/geom/doc-files/Area-1.png
new file mode 100644
index 0000000..44650f2
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/Area-1.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-1.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-1.png
new file mode 100644
index 0000000..1784509
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-1.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-2.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-2.png
new file mode 100644
index 0000000..1ddae9f
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-2.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-3.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-3.png
new file mode 100644
index 0000000..b200dad
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-3.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-4.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-4.png
new file mode 100644
index 0000000..e57ffdc
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-4.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-5.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-5.png
new file mode 100644
index 0000000..701ab13
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-5.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/Ellipse-1.png b/libjava/classpath/java/awt/geom/doc-files/Ellipse-1.png
new file mode 100644
index 0000000..8317db6
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/Ellipse-1.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/FlatteningPathIterator-1.html b/libjava/classpath/java/awt/geom/doc-files/FlatteningPathIterator-1.html
new file mode 100644
index 0000000..5a52d69
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/FlatteningPathIterator-1.html
@@ -0,0 +1,481 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<!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" xml:lang="en" lang="en">
+<head>
+ <title>The GNU Implementation of java.awt.geom.FlatteningPathIterator</title>
+ <meta name="author" content="Sascha Brawer" />
+ <style type="text/css"><!--
+ td { white-space: nowrap; }
+ li { margin: 2mm 0; }
+ --></style>
+</head>
+<body>
+
+<h1>The GNU Implementation of FlatteningPathIterator</h1>
+
+<p><i><a href="http://www.dandelis.ch/people/brawer/">Sascha
+Brawer</a>, November 2003</i></p>
+
+<p>This document describes the GNU implementation of the class
+<code>java.awt.geom.FlatteningPathIterator</code>. It does
+<em>not</em> describe how a programmer should use this class; please
+refer to the generated API documentation for this purpose. Instead, it
+is intended for maintenance programmers who want to understand the
+implementation, for example because they want to extend the class or
+fix a bug.</p>
+
+
+<h2>Data Structures</h2>
+
+<p>The algorithm uses a stack. Its allocation is delayed to the time
+when the source path iterator actually returns the first curved
+segment (either <code>SEG_QUADTO</code> or <code>SEG_CUBICTO</code>).
+If the input path does not contain any curved segments, the value of
+the <code>stack</code> variable stays <code>null</code>. In this quite
+common case, the memory consumption is minimal.</p>
+
+<dl><dt><code>stack</code></dt><dd>The variable <code>stack</code> is
+a <code>double</code> array that holds the start, control and end
+points of individual sub-segments.</dd>
+
+<dt><code>recLevel</code></dt><dd>The variable <code>recLevel</code>
+holds how many recursive sub-divisions were needed to calculate a
+segment. The original curve has recursion level 0. For each
+sub-division, the corresponding recursion level is increased by
+one.</dd>
+
+<dt><code>stackSize</code></dt><dd>Finally, the variable
+<code>stackSize</code> indicates how many sub-segments are stored on
+the stack.</dd></dl>
+
+<h2>Algorithm</h2>
+
+<p>The implementation separately processes each segment that the
+base iterator returns.</p>
+
+<p>In the case of <code>SEG_CLOSE</code>,
+<code>SEG_MOVETO</code> and <code>SEG_LINETO</code> segments, the
+implementation simply hands the segment to the consumer, without actually
+doing anything.</p>
+
+<p>Any <code>SEG_QUADTO</code> and <code>SEG_CUBICTO</code> segments
+need to be flattened. Flattening is performed with a fixed-sized
+stack, holding the coordinates of subdivided segments. When the base
+iterator returns a <code>SEG_QUADTO</code> and
+<code>SEG_CUBICTO</code> segments, it is recursively flattened as
+follows:</p>
+
+<ol><li>Intialization: Allocate memory for the stack (unless a
+sufficiently large stack has been allocated previously). Push the
+original quadratic or cubic curve onto the stack. Mark that segment as
+having a <code>recLevel</code> of zero.</li>
+
+<li>If the stack is empty, flattening the segment is complete,
+and the next segment is fetched from the base iterator.</li>
+
+<li>If the stack is not empty, pop a curve segment from the
+stack.
+
+ <ul><li>If its <code>recLevel</code> exceeds the recursion limit,
+ hand the current segment to the consumer.</li>
+
+ <li>Calculate the squared flatness of the segment. If it smaller
+ than <code>flatnessSq</code>, hand the current segment to the
+ consumer.</li>
+
+ <li>Otherwise, split the segment in two halves. Push the right
+ half onto the stack. Then, push the left half onto the stack.
+ Continue with step two.</li></ul></li>
+</ol>
+
+<p>The implementation is slightly complicated by the fact that
+consumers <em>pull</em> the flattened segments from the
+<code>FlatteningPathIterator</code>. This means that we actually
+cannot &#x201c;hand the curent segment over to the consumer.&#x201d;
+But the algorithm is easier to understand if one assumes a
+<em>push</em> paradigm.</p>
+
+
+<h2>Example</h2>
+
+<p>The following example shows how a
+<code>FlatteningPathIterator</code> processes a
+<code>SEG_QUADTO</code> segment. It is (arbitrarily) assumed that the
+recursion limit was set to 2.</p>
+
+<blockquote>
+<table border="1" cellspacing="0" cellpadding="8">
+ <tr align="center" valign="baseline">
+ <th></th><th>A</th><th>B</th><th>C</th>
+ <th>D</th><th>E</th><th>F</th><th>G</th><th>H</th>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[0]</code></th>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td><i>S<sub>ll</sub>.x</i></td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[1]</code></th>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td><i>S<sub>ll</sub>.y</i></td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[2]</code></th>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td><i>C<sub>ll</sub>.x</i></td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[3]</code></th>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td><i>C<sub>ll</sub>.y</i></td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[4]</code></th>
+ <td>&#x2014;</td>
+ <td><i>S<sub>l</sub>.x</i></td>
+ <td><i>E<sub>ll</sub>.x</i>
+ = <i>S<sub>lr</sub>.x</i></td>
+ <td><i>S<sub>lr</sub>.x</i></td>
+ <td>&#x2014;</td>
+ <td><i>S<sub>rl</sub>.x</i></td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[5]</code></th>
+ <td>&#x2014;</td>
+ <td><i>S<sub>l</sub>.y</i></td>
+ <td><i>E<sub>ll</sub>.x</i>
+ = <i>S<sub>lr</sub>.y</i></td>
+ <td><i>S<sub>lr</sub>.y</i></td>
+ <td>&#x2014;</td>
+ <td><i>S<sub>rl</sub>.y</i></td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[6]</code></th>
+ <td>&#x2014;</td>
+ <td><i>C<sub>l</sub>.x</i></td>
+ <td><i>C<sub>lr</sub>.x</i></td>
+ <td><i>C<sub>lr</sub>.x</i></td>
+ <td>&#x2014;</td>
+ <td><i>C<sub>rl</sub>.x</i></td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[7]</code></th>
+ <td>&#x2014;</td>
+ <td><i>C<sub>l</sub>.y</i></td>
+ <td><i>C<sub>lr</sub>.y</i></td>
+ <td><i>C<sub>lr</sub>.y</i></td>
+ <td>&#x2014;</td>
+ <td><i>C<sub>rl</sub>.y</i></td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[8]</code></th>
+ <td><i>S.x</i></td>
+ <td><i>E<sub>l</sub>.x</i>
+ = <i>S<sub>r</sub>.x</i></td>
+ <td><i>E<sub>lr</sub>.x</i>
+ = <i>S<sub>r</sub>.x</i></td>
+ <td><i>E<sub>lr</sub>.x</i>
+ = <i>S<sub>r</sub>.x</i></td>
+ <td><i>S<sub>r</sub>.x</i></td>
+ <td><i>E<sub>rl</sub>.x</i>
+ = <i>S<sub>rr</sub>.x</i></td>
+ <td><i>S<sub>rr</sub>.x</i></td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[9]</code></th>
+ <td><i>S.y</i></td>
+ <td><i>E<sub>l</sub>.y</i>
+ = <i>S<sub>r</sub>.y</i></td>
+ <td><i>E<sub>lr</sub>.y</i>
+ = <i>S<sub>r</sub>.y</i></td>
+ <td><i>E<sub>lr</sub>.y</i>
+ = <i>S<sub>r</sub>.y</i></td>
+ <td><i>S<sub>r</sub>.y</i></td>
+ <td><i>E<sub>rl</sub>.y</i>
+ = <i>S<sub>rr</sub>.y</i></td>
+ <td><i>S<sub>rr</sub>.y</i></td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[10]</code></th>
+ <td><i>C.x</i></td>
+ <td><i>C<sub>r</sub>.x</i></td>
+ <td><i>C<sub>r</sub>.x</i></td>
+ <td><i>C<sub>r</sub>.x</i></td>
+ <td><i>C<sub>r</sub>.x</i></td>
+ <td><i>C<sub>rr</sub>.x</i></td>
+ <td><i>C<sub>rr</sub>.x</i></td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[11]</code></th>
+ <td><i>C.y</i></td>
+ <td><i>C<sub>r</sub>.y</i></td>
+ <td><i>C<sub>r</sub>.y</i></td>
+ <td><i>C<sub>r</sub>.y</i></td>
+ <td><i>C<sub>r</sub>.y</i></td>
+ <td><i>C<sub>rr</sub>.y</i></td>
+ <td><i>C<sub>rr</sub>.y</i></td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[12]</code></th>
+ <td><i>E.x</i></td>
+ <td><i>E<sub>r</sub>.x</i></td>
+ <td><i>E<sub>r</sub>.x</i></td>
+ <td><i>E<sub>r</sub>.x</i></td>
+ <td><i>E<sub>r</sub>.x</i></td>
+ <td><i>E<sub>rr</sub>.x</i></td>
+ <td><i>E<sub>rr</sub>.x</i></td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stack[13]</code></th>
+ <td><i>E.y</i></td>
+ <td><i>E<sub>r</sub>.y</i></td>
+ <td><i>E<sub>r</sub>.y</i></td>
+ <td><i>E<sub>r</sub>.y</i></td>
+ <td><i>E<sub>r</sub>.y</i></td>
+ <td><i>E<sub>rr</sub>.y</i></td>
+ <td><i>E<sub>rr</sub>.x</i></td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>stackSize</code></th>
+ <td>1</td>
+ <td>2</td>
+ <td>3</td>
+ <td>2</td>
+ <td>1</td>
+ <td>2</td>
+ <td>1</td>
+ <td>0</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>recLevel[2]</code></th>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>2</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>recLevel[1]</code></th>
+ <td>&#x2014;</td>
+ <td>1</td>
+ <td>2</td>
+ <td>2</td>
+ <td>&#x2014;</td>
+ <td>2</td>
+ <td>&#x2014;</td>
+ <td>&#x2014;</td>
+ </tr>
+ <tr align="center" valign="baseline">
+ <th><code>recLevel[0]</code></th>
+ <td>0</td>
+ <td>1</td>
+ <td>1</td>
+ <td>1</td>
+ <td>1</td>
+ <td>2</td>
+ <td>2</td>
+ <td>&#x2014;</td>
+ </tr>
+ </table>
+</blockquote>
+
+<ol>
+
+<li>The data structures are initialized as follows.
+
+<ul><li>The segment&#x2019;s end point <i>E</i>, control point
+<i>C</i>, and start point <i>S</i> are pushed onto the stack.</li>
+
+ <li>Currently, the curve in the stack would be approximated by one
+ single straight line segment (<i>S</i> &#x2013; <i>E</i>).
+ Therefore, <code>stackSize</code> is set to 1.</li>
+
+ <li>This single straight line segment is approximating the original
+ curve, which can be seen as the result of zero recursive
+ splits. Therefore, <code>recLevel[0]</code> is set to
+ zero.</li></ul>
+
+Column A shows the state after the initialization step.</li>
+
+<li>The algorithm proceeds by taking the topmost curve segment
+(<i>S</i> &#x2013; <i>C</i> &#x2013; <i>E</i>) from the stack.
+
+ <ul><li>The recursion level of this segment (stored in
+ <code>recLevel[0]</code>) is zero, which is smaller than
+ the limit 2.</li>
+
+ <li>The method <code>java.awt.geom.QuadCurve2D.getFlatnessSq</code>
+ is called to calculate the squared flatness.</li>
+
+ <li>For the sake of argument, we assume that the squared flatness is
+ exceeding the threshold stored in <code>flatnessSq</code>. Thus, the
+ curve segment <i>S</i> &#x2013; <i>C</i> &#x2013; <i>E</i> gets
+ subdivided into a left and a right half, namely
+ <i>S<sub>l</sub></i> &#x2013; <i>C<sub>l</sub></i> &#x2013;
+ <i>E<sub>l</sub></i> and <i>S<sub>r</sub></i> &#x2013;
+ <i>C<sub>r</sub></i> &#x2013; <i>E<sub>r</sub></i>. Both halves are
+ pushed onto the stack, so the left half is now on top.
+
+ <br />&nbsp;<br />The left half starts at the same point
+ as the original curve, so <i>S<sub>l</sub></i> has the same
+ coordinates as <i>S</i>. Similarly, the end point of the right
+ half and of the original curve are identical
+ (<i>E<sub>r</sub></i> = <i>E</i>). More interestingly, the left
+ half ends where the right half starts. Because
+ <i>E<sub>l</sub></i> = <i>S<sub>r</sub></i>, their coordinates need
+ to be stored only once, which amounts to saving 16 bytes (two
+ <code>double</code> values) for each iteration.</li></ul>
+
+Column B shows the state after the first iteration.</li>
+
+<li>Again, the topmost curve segment (<i>S<sub>l</sub></i>
+&#x2013; <i>C<sub>l</sub></i> &#x2013; <i>E<sub>l</sub></i>) is
+taken from the stack.
+
+ <ul><li>The recursion level of this segment (stored in
+ <code>recLevel[1]</code>) is 1, which is smaller than
+ the limit 2.</li>
+
+ <li>The method <code>java.awt.geom.QuadCurve2D.getFlatnessSq</code>
+ is called to calculate the squared flatness.</li>
+
+ <li>Assuming that the segment is still not considered
+ flat enough, it gets subdivided into a left
+ (<i>S<sub>ll</sub></i> &#x2013; <i>C<sub>ll</sub></i> &#x2013;
+ <i>E<sub>ll</sub></i>) and a right (<i>S<sub>lr</sub></i>
+ &#x2013; <i>C<sub>lr</sub></i> &#x2013; <i>E<sub>lr</sub></i>)
+ half.</li></ul>
+
+Column C shows the state after the second iteration.</li>
+
+<li>The topmost curve segment (<i>S<sub>ll</sub></i> &#x2013;
+<i>C<sub>ll</sub></i> &#x2013; <i>E<sub>ll</sub></i>) is popped from
+the stack.
+
+ <ul><li>The recursion level of this segment (stored in
+ <code>recLevel[2]</code>) is 2, which is <em>not</em> smaller than
+ the limit 2. Therefore, a <code>SEG_LINETO</code> (from
+ <i>S<sub>ll</sub></i> to <i>E<sub>ll</sub></i>) is passed to the
+ consumer.</li></ul>
+
+ The new state is shown in column D.</li>
+
+
+<li>The topmost curve segment (<i>S<sub>lr</sub></i> &#x2013;
+<i>C<sub>lr</sub></i> &#x2013; <i>E<sub>lr</sub></i>) is popped from
+the stack.
+
+ <ul><li>The recursion level of this segment (stored in
+ <code>recLevel[1]</code>) is 2, which is <em>not</em> smaller than
+ the limit 2. Therefore, a <code>SEG_LINETO</code> (from
+ <i>S<sub>lr</sub></i> to <i>E<sub>lr</sub></i>) is passed to the
+ consumer.</li></ul>
+
+ The new state is shown in column E.</li>
+
+<li>The algorithm proceeds by taking the topmost curve segment
+(<i>S<sub>r</sub></i> &#x2013; <i>C<sub>r</sub></i> &#x2013;
+<i>E<sub>r</sub></i>) from the stack.
+
+ <ul><li>The recursion level of this segment (stored in
+ <code>recLevel[0]</code>) is 1, which is smaller than
+ the limit 2.</li>
+
+ <li>The method <code>java.awt.geom.QuadCurve2D.getFlatnessSq</code>
+ is called to calculate the squared flatness.</li>
+
+ <li>For the sake of argument, we again assume that the squared
+ flatness is exceeding the threshold stored in
+ <code>flatnessSq</code>. Thus, the curve segment
+ (<i>S<sub>r</sub></i> &#x2013; <i>C<sub>r</sub></i> &#x2013;
+ <i>E<sub>r</sub></i>) is subdivided into a left and a right half,
+ namely
+ <i>S<sub>rl</sub></i> &#x2013; <i>C<sub>rl</sub></i> &#x2013;
+ <i>E<sub>rl</sub></i> and <i>S<sub>rr</sub></i> &#x2013;
+ <i>C<sub>rr</sub></i> &#x2013; <i>E<sub>rr</sub></i>. Both halves
+ are pushed onto the stack.</li></ul>
+
+ The new state is shown in column F.</li>
+
+<li>The topmost curve segment (<i>S<sub>rl</sub></i> &#x2013;
+<i>C<sub>rl</sub></i> &#x2013; <i>E<sub>rl</sub></i>) is popped from
+the stack.
+
+ <ul><li>The recursion level of this segment (stored in
+ <code>recLevel[2]</code>) is 2, which is <em>not</em> smaller than
+ the limit 2. Therefore, a <code>SEG_LINETO</code> (from
+ <i>S<sub>rl</sub></i> to <i>E<sub>rl</sub></i>) is passed to the
+ consumer.</li></ul>
+
+ The new state is shown in column G.</li>
+
+<li>The topmost curve segment (<i>S<sub>rr</sub></i> &#x2013;
+<i>C<sub>rr</sub></i> &#x2013; <i>E<sub>rr</sub></i>) is popped from
+the stack.
+
+ <ul><li>The recursion level of this segment (stored in
+ <code>recLevel[2]</code>) is 2, which is <em>not</em> smaller than
+ the limit 2. Therefore, a <code>SEG_LINETO</code> (from
+ <i>S<sub>rr</sub></i> to <i>E<sub>rr</sub></i>) is passed to the
+ consumer.</li></ul>
+
+ The new state is shown in column H.</li>
+
+<li>The stack is now empty. The FlatteningPathIterator will fetch the
+next segment from the base iterator, and process it.</li>
+
+</ol>
+
+<p>In order to split the most recently pushed segment, the
+<code>subdivideQuadratic()</code> method passes <code>stack</code>
+directly to
+<code>QuadCurve2D.subdivide(double[],int,double[],int,double[],int)</code>.
+Because the stack grows towards the beginning of the array, no data
+needs to be copied around: <code>subdivide</code> will directly store
+the result into the stack, which will have the contents shown to the
+right.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/geom/doc-files/GeneralPath-1.png b/libjava/classpath/java/awt/geom/doc-files/GeneralPath-1.png
new file mode 100644
index 0000000..d1d75d5
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/GeneralPath-1.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-1.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-1.png
new file mode 100644
index 0000000..7c2ec0e
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-1.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-2.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-2.png
new file mode 100644
index 0000000..496180c
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-2.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-3.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-3.png
new file mode 100644
index 0000000..a7557ba
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-3.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-4.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-4.png
new file mode 100644
index 0000000..835c064
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-4.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-5.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-5.png
new file mode 100644
index 0000000..72110cd
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-5.png
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/package.html b/libjava/classpath/java/awt/geom/package.html
new file mode 100644
index 0000000..c8ee827
--- /dev/null
+++ b/libjava/classpath/java/awt/geom/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.geom package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.geom</title></head>
+
+<body>
+<p>Classes to represent 2D objects and different path transformations.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/im/InputContext.java b/libjava/classpath/java/awt/im/InputContext.java
new file mode 100644
index 0000000..e289677
--- /dev/null
+++ b/libjava/classpath/java/awt/im/InputContext.java
@@ -0,0 +1,434 @@
+/* InputContext.java -- provides the context for text input
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.im;
+
+import gnu.java.util.EmptyEnumeration;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.im.spi.InputMethod;
+import java.awt.im.spi.InputMethodDescriptor;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+
+/**
+ * Provides a context for controlling input methods and keyboard layouts.
+ * This class provides the communication layer between the client component,
+ * and the various locale-dependent text entry input methods that can be used
+ * for the client. By default, there is one instance per Window, shared among
+ * all components, but this limits text entry to one component at a time.
+ * Thus, text components can create their own instance to allow text entry
+ * in multiple components at a time.
+ *
+ * <p>By using the interfaces of {@link java.awt.im.spi}, you can install
+ * extensions which allow additional input methods. Some of these may use
+ * platform native input methods, or keyboard layouts provided by the platform.
+ * Input methods are unavailable if none have been installed and the platform
+ * has no underlying native input methods. Extensions are installed as jar
+ * files, usually accessed in the default extension location or specified by
+ * the -extdir VM flag. The jar must contain a file named
+ * "META_INF/services/java.awt.im.spi.InputMethodDescriptor" which lists,
+ * one entry per line in UTF-8 encoding, each class in the jar that implements
+ * java.awt.im.spi.InputMethodDescriptor.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Component#getInputContext()
+ * @see Component#enableInputMethods(boolean)
+ * @since 1.2
+ * @status updated to 1.4, but unverified
+ */
+public class InputContext
+{
+ /**
+ * The list of installed input method descriptors.
+ */
+ private static final ArrayList descriptors = new ArrayList();
+ static
+ {
+ Enumeration e;
+ try
+ {
+ e = ClassLoader.getSystemResources
+ ("META_INF/services/java.awt.im.spi.InputMethodDescriptor");
+ }
+ catch (IOException ex)
+ {
+ // XXX Should we do something else?
+ e = EmptyEnumeration.getInstance();
+ }
+ while (e.hasMoreElements())
+ {
+ URL url = (URL) e.nextElement();
+ BufferedReader in;
+ String line;
+ try
+ {
+ in = new BufferedReader
+ (new InputStreamReader(url.openConnection().getInputStream(),
+ "UTF-8"));
+ line = in.readLine().trim();
+ }
+ catch (IOException ignored)
+ {
+ continue;
+ }
+ outer:
+ while (line != null)
+ {
+ try
+ {
+ if (line.charAt(0) != '#')
+ {
+ Class c = Class.forName(line);
+ descriptors.add((InputMethodDescriptor) c.newInstance());
+ }
+ line = in.readLine().trim();
+ }
+ catch (IOException ex)
+ {
+ continue outer;
+ }
+ catch (Exception ignored)
+ {
+ }
+ }
+ }
+ }
+
+ /** The current input method; null if no input methods are installed. */
+ private InputMethod im;
+
+ /** Map of locales to the most recently selected input method. */
+ private final HashMap recent = new HashMap();
+
+ /** The list of acceptable character subsets. */
+ private Character.Subset[] subsets;
+
+ /**
+ * Construct an InputContext. This is protected, so clients must use
+ * {@link #getInstance()} instead.
+ */
+ protected InputContext()
+ {
+ }
+
+ /**
+ * Returns a new InputContext.
+ *
+ * @return a new instance, initialized to the default locale if available
+ */
+ public static InputContext getInstance()
+ {
+ InputContext ic = new InputContext();
+ ic.selectInputMethod(Locale.getDefault());
+ return ic;
+ }
+
+ /**
+ * Attempts to select an input method or keyboard layout which supports the
+ * given locale. This returns true if a locale is available and was selected.
+ * The following steps are taken in choosing an input method:<ul>
+ * <li>If the currently selected input method or keyboard layout supports
+ * the requested locale, it remains selected.</li>
+ * <li>If there is no input method or keyboard layout available that
+ * supports the requested locale, the current input method or keyboard
+ * layout remains selected.</li>
+ * <li>If the user has previously selected an input method or keyboard
+ * layout for the requested locale from the user interface, then the most
+ * recently selected such input method or keyboard layout is reselected.</li>
+ * <li>Otherwise, an input method or keyboard layout that supports the
+ * requested locale is selected in an implementation dependent way. This
+ * implementation chooses the first input method which supports the requested
+ * locale based on the InputMethodDescriptors loaded from the extensions
+ * installed on the CLASSPATH.</li>
+ * </ul>
+ *
+ * <p>Before switching away from an input method, any currently uncommitted
+ * text is committed. Not all host operating systems provide API to
+ * determine the locale of the currently selected native input method or
+ * keyboard layout, and to select a native input method or keyboard layout
+ * by locale. For host operating systems that don't provide such API,
+ * selectInputMethod assumes that native input methods or keyboard layouts
+ * provided by the host operating system support only the system's default
+ * locale.
+ *
+ * <p>An example of where this may be called is in a multi-language document,
+ * when moving the insertion point between sections of different locale, so
+ * that the user may use the input method appropriate to that section of the
+ * document.
+ *
+ * @param locale the desired new locale
+ * @return true if the new locale is active
+ * @throws NullPointerException if locale is null
+ */
+ public boolean selectInputMethod(Locale locale)
+ {
+ if (im != null && im.setLocale(locale))
+ {
+ recent.put(locale, im);
+ return true;
+ }
+ InputMethod next = (InputMethod) recent.get(locale);
+ outer:
+ if (next != null)
+ for (int i = 0, limit = descriptors.size(); i < limit; i++)
+ {
+ InputMethodDescriptor d = (InputMethodDescriptor) descriptors.get(i);
+ Locale[] list;
+ try
+ {
+ list = d.getAvailableLocales();
+ }
+ catch (AWTException ignored)
+ {
+ continue;
+ }
+ for (int j = list.length; --j >= 0; )
+ if (locale.equals(list[j]))
+ {
+ try
+ {
+ next = d.createInputMethod();
+ recent.put(locale, next);
+ }
+ catch (Exception ignored)
+ {
+ continue;
+ }
+ }
+ }
+ if (next == null)
+ return false;
+ // XXX I'm not sure if this does all the necessary steps in the switch.
+ if (im != null)
+ {
+ try
+ {
+ next.setCompositionEnabled(im.isCompositionEnabled());
+ }
+ catch (UnsupportedOperationException ignored)
+ {
+ }
+ im.endComposition();
+ im.deactivate(false);
+ im.hideWindows();
+ }
+ im = next;
+ im.setLocale(locale);
+ im.setCharacterSubsets(subsets);
+ return true;
+ }
+
+ /**
+ * Returns the current locale of the current input method or keyboard
+ * layout. Returns null if the input context does not have a current input
+ * method or keyboard layout or if the current input method's
+ * {@link InputMethod#getLocale()} method returns null. Not all host
+ * operating systems provide API to determine the locale of the currently
+ * selected native input method or keyboard layout. For host operating
+ * systems that don't provide such API, getLocale assumes that the current
+ * locale of all native input methods or keyboard layouts provided by the
+ * host operating system is the system's default locale.
+ *
+ * @return the locale of the current input method, or null
+ * @since 1.3
+ */
+ public Locale getLocale()
+ {
+ return im == null ? null : im.getLocale();
+ }
+
+ /**
+ * Sets the subsets of Unicode characters allowed to be input by the current
+ * input method, as well as subsequent input methods. The value of null
+ * implies all characters are legal. Applications should not rely on this
+ * behavior, since native host input methods may not allow restrictions.
+ * If no current input method is available, this has no immediate effect.
+ *
+ * @param subsets the set of Unicode subsets to accept, or null
+ */
+ public void setCharacterSubsets(Character.Subset[] subsets)
+ {
+ this.subsets = subsets;
+ if (im != null)
+ im.setCharacterSubsets(subsets);
+ }
+
+ /**
+ * Changes the enabled status of the current input method. An input method
+ * that is enabled for composition interprets incoming events for both
+ * composition and control purposes, while a disabled input method only
+ * interprets control commands (including commands to enable itself).
+ *
+ * @param enable whether to enable the input method
+ * @throws UnsupportedOperationException if there is no current input method,
+ * or the input method does not support enabling
+ * @see #isCompositionEnabled()
+ * @since 1.3
+ */
+ public void setCompositionEnabled(boolean enable)
+ {
+ if (im == null)
+ throw new UnsupportedOperationException();
+ im.setCompositionEnabled(enable);
+ }
+
+ /**
+ * Find out if the current input method is enabled.
+ *
+ * @return true if the current input method is enabled
+ * @throws UnsupportedOperationException if there is no current input method,
+ * or the input method does not support enabling
+ * @see #setCompositionEnabled(boolean)
+ * @since 1.3
+ */
+ public boolean isCompositionEnabled()
+ {
+ if (im == null)
+ throw new UnsupportedOperationException();
+ return im.isCompositionEnabled();
+ }
+
+ /**
+ * Starts a reconversion operation in the current input method. The input
+ * method gets theh text to reconvert from the client component, using
+ * {@link InputMethodRequests#getSelectedText(Attribute[])}. Then the
+ * composed and committed text produced by the operation is sent back to
+ * the client using a sequence of InputMethodRequests.
+ *
+ * @throws UnsupportedOperationException if there is no current input method,
+ * or the input method does not support reconversion
+ * @since 1.3
+ */
+ public void reconvert()
+ {
+ if (im == null)
+ throw new UnsupportedOperationException();
+ im.reconvert();
+ }
+
+ /**
+ * Dispatches an event to the current input method. This is called
+ * automatically by AWT. If no input method is available, then the event
+ * will never be consumed.
+ *
+ * @param event the event to dispatch
+ * @throws NullPointerException if event is null
+ */
+ public void dispatchEvent(AWTEvent event)
+ {
+ if (im != null)
+ im.dispatchEvent(event);
+ }
+
+ /**
+ * Notifies the input context that a client component has been removed from
+ * its containment hierarchy, or that input method support has been disabled
+ * for the component. This method is usually called from the client
+ * component's {@link Component#removeNotify()} method. Potentially pending
+ * input from input methods for this component is discarded. If no input
+ * methods are available, then this method has no effect.
+ *
+ * @param client the client component
+ * @throws NullPointerException if client is null
+ */
+ public void removeNotify(Component client)
+ {
+ // XXX What to do with client information?
+ if (im != null)
+ {
+ im.deactivate(false);
+ im.removeNotify();
+ }
+ }
+
+ /**
+ * Ends any input composition that may currently be going on in this
+ * context. Depending on the platform and possibly user preferences, this
+ * may commit or delete uncommitted text. Any changes to the text are
+ * communicated to the active component using an input method event. If no
+ * input methods are available, then this method has no effect. This may
+ * be called for a variety of reasons, such as when the user moves the
+ * insertion point in the client text outside the range of the composed text,
+ * or when text is saved to file.
+ */
+ public void endComposition()
+ {
+ if (im != null)
+ im.endComposition();
+ }
+
+ /**
+ * Disposes of the input context and release the resources used by it.
+ * Called automatically by AWT for the default input context of each
+ * Window. If no input methods are available, then this method has no
+ * effect.
+ */
+ public void dispose()
+ {
+ if (im != null)
+ {
+ im.deactivate(false);
+ im.dispose();
+ }
+ }
+
+ /**
+ * Returns a control object from the current input method, or null. A
+ * control object provides implementation-dependent methods that control
+ * the behavior of the input method or obtain information from the input
+ * method. Clients have to compare the result against known input method
+ * control object types. If no input methods are available or the current
+ * input method does not provide an input method control object, then null
+ * is returned.
+ *
+ * @return the control object, or null
+ */
+ public Object getInputMethodControlObject()
+ {
+ return im == null ? null : im.getControlObject();
+ }
+} // class InputContext
diff --git a/libjava/classpath/java/awt/im/InputMethodHighlight.java b/libjava/classpath/java/awt/im/InputMethodHighlight.java
new file mode 100644
index 0000000..0d664b1
--- /dev/null
+++ b/libjava/classpath/java/awt/im/InputMethodHighlight.java
@@ -0,0 +1,185 @@
+/* InputMethodHighlight.java -- highlights the current text selection
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.im;
+
+import java.util.Map;
+
+/**
+ * This describes the highlight attributes of text composed in an input method.
+ * The description includes an abstract level (whether text has been converted
+ * yet, and whether it is selected), and a concrete level (which style
+ * attributes are used in rendering). If no concrete level is defined, the
+ * renderer should use
+ * {@link Toolkit#mapInputMethodHighlight(InputMethodHighlight)}. An example
+ * of conversion state is kana -&gt; kanji.
+ *
+ * <p>Instances of this class are typically used in
+ * AttributedCharacterIterators, and may be wrapped in Annotations to separate
+ * text segments.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see AttributedCharacterIterators
+ * @see Annotation
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public class InputMethodHighlight
+{
+ /** Raw text state (before conversion). */
+ public static final int RAW_TEXT = 0;
+
+ /** Converted text state (after conversion). */
+ public static final int CONVERTED_TEXT = 1;
+
+ /** Default do-nothing highlighting for unselected raw text. */
+ public static final InputMethodHighlight UNSELECTED_RAW_TEXT_HIGHLIGHT
+ = new InputMethodHighlight(false, RAW_TEXT);
+
+ /** Default do-nothing highlighting for selected raw text. */
+ public static final InputMethodHighlight SELECTED_RAW_TEXT_HIGHLIGHT
+ = new InputMethodHighlight(true, RAW_TEXT);
+
+ /** Default do-nothing highlighting for unselected converted text. */
+ public static final InputMethodHighlight UNSELECTED_CONVERTED_TEXT_HIGHLIGHT
+ = new InputMethodHighlight(false, CONVERTED_TEXT);
+
+ /** Default do-nothing highlighting for selected converted text. */
+ public static final InputMethodHighlight SELECTED_CONVERTED_TEXT_HIGHLIGHT
+ = new InputMethodHighlight(true, CONVERTED_TEXT);
+
+ /** Whether the highlighting applies to selected text. */
+ private final boolean selected;
+
+ /** The state of highlighted text. */
+ private final int state;
+
+ /** Any variation on the highlighting style. */
+ private final int variation;
+
+ /** The unmodifiable map of rendering styles. */
+ private final Map style;
+
+ /**
+ * Create an input method highlight style, with variation 0 and null style
+ * mapping.
+ *
+ * @param selected whether the text range is selected
+ * @param state either {@link #RAW_TEXT} or {@link #CONVERTED_TEXT}
+ * @throws IllegalArgumentException if state is invalid
+ */
+ public InputMethodHighlight(boolean selected, int state)
+ {
+ this(selected, state, 0, null);
+ }
+
+ /**
+ * Create an input method highlight style, with null style mapping.
+ *
+ * @param selected whether the text range is selected
+ * @param state either {@link #RAW_TEXT} or {@link #CONVERTED_TEXT}
+ * @param variation the style variation
+ * @throws IllegalArgumentException if state is invalid
+ */
+ public InputMethodHighlight(boolean selected, int state, int variation)
+ {
+ this(selected, state, variation, null);
+ }
+
+ /**
+ * Create an input method highlight style.
+ *
+ * @param selected whether the text range is selected
+ * @param state either {@link #RAW_TEXT} or {@link #CONVERTED_TEXT}
+ * @param variation the style variation
+ * @param style an unmodifiable map of rendering styles, or null
+ * @throws IllegalArgumentException if state is invalid
+ * @since 1.3
+ */
+ public InputMethodHighlight(boolean selected, int state, int variation,
+ Map style)
+ {
+ if (state != RAW_TEXT && state != CONVERTED_TEXT)
+ throw new IllegalArgumentException();
+ this.selected = selected;
+ this.state = state;
+ this.variation = variation;
+ this.style = style;
+ }
+
+ /**
+ * Return whether the highlighting applies to selected text.
+ *
+ * @return the selection status
+ */
+ public boolean isSelected()
+ {
+ return selected;
+ }
+
+ /**
+ * Return the conversion state of the highlighted text.
+ *
+ * @return one of {@link #RAW_TEXT} or {@link #CONVERTED_TEXT}
+ */
+ public int getState()
+ {
+ return state;
+ }
+
+ /**
+ * Return the highlighting style variation.
+ *
+ * @return the variation
+ */
+ public int getVariation()
+ {
+ return variation;
+ }
+
+ /**
+ * Return the rendering style attributes map, or null if it should be the
+ * default mapping.
+ *
+ * @return the style map
+ * @since 1.3
+ */
+ public Map getStyle()
+ {
+ return style;
+ }
+} // class InputMethodHighlight
diff --git a/libjava/classpath/java/awt/im/InputMethodRequests.java b/libjava/classpath/java/awt/im/InputMethodRequests.java
new file mode 100644
index 0000000..d50ec33
--- /dev/null
+++ b/libjava/classpath/java/awt/im/InputMethodRequests.java
@@ -0,0 +1,153 @@
+/* InputMethodRequests.java -- handles text insertion via input methods
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.im;
+
+import java.awt.Rectangle;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+
+/**
+ * This interface handles requests made by input methods on text editing
+ * components. A component must specify a handler for input methods that
+ * implements this interface, and which supports one of two user interfaces:
+ * <ul><li><em>on-the-spot</em>: composed text is shown in place</li>
+ * <li><em>below-the-spot</em>: composed text is in a separate window,
+ * usually below the main text window, until it is committed into place at
+ * the insertion point, overwriting any selected text</li></ul>
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Component#getInputMethodRequests()
+ * @see InputMethodListener
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public interface InputMethodRequests
+{
+ /**
+ * Gets the location of a given offset of the text. This can be used to
+ * position a composition window near the location of where the composed
+ * text will be inserted.
+ *
+ * <p>If the component has composed text (from the most recent
+ * InputMethodEvent), then offset 0 indicates the location of the first
+ * character of this composed text. Otherwise, the offset is ignored, and
+ * the location should be the beginning of the final line of selected
+ * text (in horizontal left-to-right text, like English, this would be the
+ * lower left corner of the selction; in vertical top-to-bottom text, like
+ * Chinese, this would be the top right corner of the selection).
+ *
+ * <p>The location returned is a 0-thickness caret (either horizontal or
+ * vertical, depending on text flow), mapped to absolute screen coordinates.
+ *
+ * @param offset offset within composed text, or null
+ * @return the screen location of the caret at the offset
+ */
+ Rectangle getTextLocation(TextHitInfo offset);
+
+ /**
+ * Get the text offset for the given screen coordinate. The offset is
+ * relative to the composed text, and the return is null if it is outside
+ * the range of composed text. For example, this can be used to find
+ * where a mouse click should pop up a text composition window.
+ *
+ * @param x the x screen coordinate
+ * @param y the y screen coordinate
+ * @return a text hit info describing the composed text offset
+ */
+ TextHitInfo getLocationOffset(int x, int y);
+
+ /**
+ * Gets the offset where the committed text exists in the text editing
+ * component. This can be used to examine the text surrounding the insert
+ * position.
+ *
+ * @return the offset of the insert position
+ */
+ int getInsertPositionOffset();
+
+ /**
+ * Gets an interator which provides access to the text and its attributes,
+ * except for the uncommitted text. The input method may provide a list of
+ * attributes it is interested in; and the iterator need not provide
+ * information on the remaining attributes. If the attribute list is null,
+ * the iterator must list all attributes.
+ *
+ * @param beginIndex the index of the first character in the iteration
+ * @param endIndex the index of the last character in the iteration
+ * @param attributes a list of attributes interested in, or null
+ * @return an iterator over the region of text with its attributes
+ */
+ AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex,
+ Attribute[] attributes);
+
+ /**
+ * Gets the length of committed text.
+ *
+ * @return the number of committed characters
+ */
+ int getCommittedTextLength();
+
+ /**
+ * Gets the latest committed text, and removes it from the component's text
+ * body. This allows an input method to provide an "Undo" command. In
+ * general, this should only be supported immediately after a commit, and
+ * not when other actions intervene; if not supported, simply return null.
+ * The input method may provide a list of attributes it is interested in;
+ * and the iterator need not provide information on the remaining attributes.
+ * If the attribute list is null, the iterator must list all attributes.
+ *
+ * @param attributes a list of attributes interested in, or null
+ * @return the latest committed text, or null
+ */
+ AttributedCharacterIterator cancelLatestCommittedText
+ (Attribute[] attributes);
+
+ /**
+ * Gets the currently selected text. One use of this is to implement a
+ * "Reconvert" feature in an input method, which modifies the selection
+ * based on the text in the composition window. The input method may
+ * provide a list of attributes it is interested in; and the iterator need
+ * not provide information on the remaining attributes. If the attribute
+ * list is null, the iterator must list all attributes.
+ *
+ * @param attributes a list of attributes interested in, or null
+ * @return the current selection
+ */
+ AttributedCharacterIterator getSelectedText(Attribute[] attributes);
+} // interface InputMethodRequests
diff --git a/libjava/classpath/java/awt/im/InputSubset.java b/libjava/classpath/java/awt/im/InputSubset.java
new file mode 100644
index 0000000..5e7d58e
--- /dev/null
+++ b/libjava/classpath/java/awt/im/InputSubset.java
@@ -0,0 +1,129 @@
+/* InputSubset.java -- subsets of Unicode important in text input
+ Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.im;
+
+/**
+ * Defines additional Unicode character blocks for use by input methods.
+ * These constants encompass several Unicode blocks, or portions thereof, for
+ * simplification over {@link Character.UnicodeBlock}.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public final class InputSubset extends Character.Subset
+{
+ /**
+ * Constant for all Latin characters, including the characters in the
+ * BASIC_LATIN, LATIN_1_SUPPLEMENT, LATIN_EXTENDED_A, LATIN_EXTENDED_B
+ * Unicode character blocks.
+ */
+ public static final InputSubset LATIN = new InputSubset("LATIN");
+
+ /**
+ * Constant for the digits included in the BASIC_LATIN Unicode character
+ * block.
+ */
+ public static final InputSubset LATIN_DIGITS
+ = new InputSubset("LATIN_DIGITS");
+
+ /**
+ * Constant for all Han characters used in writing Traditional Chinese,
+ * including a subset of the CJK unified ideographs as well as Traditional
+ * Chinese Han characters that may be defined as surrogate characters.
+ */
+ public static final InputSubset TRADITIONAL_HANZI
+ = new InputSubset("TRADITIONAL_HANZI");
+
+ /**
+ * Constant for all Han characters used in writing Simplified Chinese,
+ * including a subset of the CJK unified ideographs as well as Simplified
+ * Chinese Han characters that may be defined as surrogate characters.
+ */
+ public static final InputSubset SIMPLIFIED_HANZI
+ = new InputSubset("SIMPLIFIED_HANZI");
+
+ /**
+ * Constant for all Han characters used in writing Japanese, including a
+ * subset of the CJK unified ideographs as well as Japanese Han characters
+ * that may be defined as surrogate characters.
+ */
+ public static final InputSubset KANJI = new InputSubset("KANJI");
+
+ /**
+ * Constant for all Han characters used in writing Korean, including a
+ * subset of the CJK unified ideographs as well as Korean Han characters
+ * that may be defined as surrogate characters.
+ */
+ public static final InputSubset HANJA = new InputSubset("HANJA");
+
+ /**
+ * Constant for the halfwidth katakana subset of the Unicode halfwidth and
+ * fullwidth forms character block.
+ */
+ public static final InputSubset HALFWIDTH_KATAKANA
+ = new InputSubset("HALFWIDTH_KATAKANA");
+
+ /**
+ * Constant for the fullwidth ASCII variants subset of the Unicode
+ * halfwidth and fullwidth forms character block.
+ *
+ * @since 1.3
+ */
+ public static final InputSubset FULLWIDTH_LATIN
+ = new InputSubset("FULLWIDTH_LATIN");
+
+ /**
+ * Constant for the fullwidth digits included in the Unicode halfwidth and
+ * fullwidth forms character block.
+ *
+ * @since 1.3
+ */
+ public static final InputSubset FULLWIDTH_DIGITS
+ = new InputSubset("FULLWIDTH_DIGITS");
+
+ /**
+ * Construct a subset.
+ *
+ * @param name the subset name
+ */
+ private InputSubset(String name)
+ {
+ super(name);
+ }
+} // class InputSubset
diff --git a/libjava/classpath/java/awt/im/package.html b/libjava/classpath/java/awt/im/package.html
new file mode 100644
index 0000000..895da66
--- /dev/null
+++ b/libjava/classpath/java/awt/im/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.im package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.im</title></head>
+
+<body>
+<p>Support for text input methods.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/im/spi/InputMethod.java b/libjava/classpath/java/awt/im/spi/InputMethod.java
new file mode 100644
index 0000000..840d193
--- /dev/null
+++ b/libjava/classpath/java/awt/im/spi/InputMethod.java
@@ -0,0 +1,240 @@
+/* InputMethod.java -- defines an interface for complex text input
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.im.spi;
+
+import java.awt.AWTEvent;
+import java.awt.Rectangle;
+import java.util.Locale;
+
+/**
+ * This interface supports complex text input, often for situations where
+ * the text is more complex than a keyboard will accomodate. For example,
+ * this can be used for Chinese, Japanese, and Korean, where multiple
+ * keystrokes are necessary to compose text. This could also support things
+ * like phonetic English, or reordering Thai.
+ *
+ * <p>These contexts can be loaded by the input method framework, using
+ * {@link InputContext#selectInputMethod(Locale)}.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public interface InputMethod
+{
+ /**
+ * Set the input method context, which ties the input method to a client
+ * component. This is called once automatically when creating the input
+ * method.
+ *
+ * @param context the context for this input method
+ * @throws NullPointerException if context is null
+ */
+ void setInputMethodContext(InputMethodContext context);
+
+ /**
+ * Sets the input locale. If the input method supports that locale, it
+ * changes its behavior to be consistent with the locale and returns true.
+ * Otherwise, it returns false. This is called by
+ * {@link InputContext#selectInputMethod(Locale)} when the user specifies
+ * a locale, or when the previously selected input method had a locale.
+ *
+ * @param locale the locale to use for input
+ * @return true if the change is successful
+ * @throws NullPointerException if locale is null
+ */
+ boolean setLocale(Locale locale);
+
+ /**
+ * Returns the current input locale, or null if none is defined. This is
+ * called by {@link InputContext#getLocale()}, or before switching input
+ * methods.
+ *
+ * @return the current input locale, or null
+ */
+ Locale getLocale();
+
+ /**
+ * Sets the allowed Unicode subsets that this input method can use. Null
+ * indicates that all characters are allowed. This is called after creation,
+ * or when switching to this input method, by
+ * {@link InputContext#setCharacterSubsets(Character.Subset[])}.
+ *
+ * @param subsets the accepted subsets for this input method, or null for all
+ */
+ void setCharacterSubsets(Character.Subset[] subsets);
+
+ /**
+ * Changes the enabled status of this input method. An enabled input method
+ * accepts incoming events for composition and control purposes, while a
+ * disabled input method ignores events (except for control purposes). This
+ * is called by {@link InputContext#setCompositionEnabled(boolean)} or when
+ * switching from an input method if the previous input method returned
+ * without exception on {@link #isCompositionEnabled()}.
+ *
+ * @param enable whether to enable this input method
+ * @throws UnsupportedOperationException if enabling/disabling is unsupported
+ * @see #isCompositionEnabled()
+ */
+ void setCompositionEnabled(boolean enable);
+
+ /**
+ * Find out if this input method is enabled. This is called by
+ * {@link InputContext#isCompositionEnabled()}, or when switching input
+ * methods via {@link InputContext#selectInputMethod(Locale)}.
+ *
+ * @return true if this input method is enabled
+ * @throws UnsupportedOperationException if enabling/disabling is unsupported
+ * @see #setCompositionEnabled(boolean)
+ */
+ boolean isCompositionEnabled();
+
+ /**
+ * Starts a reconversion operation. The input method gets its text from the
+ * client, using {@link InputMethodRequests#getSelectedText(Attribute[])}.
+ * Then the composed and committed text produced by the operation is sent
+ * back to the client using a sequence of InputMethodEvents. This is called
+ * by {@link InputContext#reconvert()}.
+ *
+ * @throws UnsupportedOperationException if reconversion is unsupported
+ */
+ void reconvert();
+
+ /**
+ * Dispatch an event to the input method. If input method support is enabled,
+ * certain events are dispatched to the input method before the client
+ * component or event listeners. The input method must either consume the
+ * event or pass it on to the component. Instances of InputEvent, including
+ * KeyEvent and MouseEvent, are given to this input method. This method is
+ * called by {@link InputContext#dispatchEvent(AWTEvent)}.
+ *
+ * @param event the event to dispatch
+ * @throws NullPointerException if event is null
+ */
+ void dispatchEvent(AWTEvent event);
+
+ /**
+ * Notify this input method of changes in the client window. This is called
+ * when notifications are enabled (see {@link
+ * InputMethodContext#enableClientWindowNotification(InputMethod, boolean)},
+ * if {@link #removeNotify(Component)} has not been called. The following
+ * situations trigger a notification:<ul>
+ * <li>The client window changes in location, size, visibility,
+ * iconification, or is closed.</li>
+ * <li>When enabling client notification (or on the first activation after
+ * enabling if no client existed at the time).</li>
+ * <li>When activating a new client after <code>removeNotify</code> was
+ * called on a previous client.</li>
+ * </ul>
+ *
+ * @param bounds the client window's current bounds, or null
+ */
+ void notifyClientWindowChange(Rectangle bounds);
+
+ /**
+ * Activate this input method for input processing. If the input method
+ * provides its own windows, it should make them open and visible at this
+ * time. This method is called when a client component receives a
+ * FOCUS_GAINED event, or when switching to this input method from another
+ * one. It is only called when the input method is inactive, assuming that
+ * new instances begin in an inactive state.
+ */
+ void activate();
+
+ /**
+ * Deactivate this input method, either temporarily or permanently for the
+ * given client. If the input method provides its own windows, it should
+ * only close those related to the current composition (such as a lookup
+ * choice panel), while leaving more persistant windows (like a control
+ * panel) open to avoid screen flicker. Before control is given to another
+ * input method, {@link #hideWindows()} will be called on this instance.
+ * This method is called when a client component receives a
+ * FOCUS_LOST event, when switching to another input method, or before
+ * {@link #removeNotify()} when the client is removed.
+ *
+ * @param isTemporary true if the focus change is temporary
+ */
+ void deactivate(boolean isTemporary);
+
+ /**
+ * Close or hide all windows opened by this input method. This is called
+ * before activating a different input method, and before calling
+ * {@link #dispose()} on this instance. It is only called when the input
+ * method is inactive.
+ */
+ void hideWindows();
+
+ /**
+ * Notify the input method that a client component has been removed from its
+ * hierarchy, or that input method support has been disabled. This is
+ * called by {@link InputContext#removeNotify()}, and only when the input
+ * method is inactive.
+ */
+ void removeNotify();
+
+ /**
+ * End any input composition currently taking place. Depending on the
+ * platform and user preferences, this may commit or delete uncommitted text,
+ * using input method events. This may be called for a variety of reasons,
+ * such as when the user moves the insertion point in the client text outside
+ * the range of the composed text, or when text is saved to file. This is
+ * called by {@link InputContext#endComposition()}, when switching to a
+ * new input method, or by {@link InputContext#selectInputMethod(Locale)}.
+ */
+ void endComposition();
+
+ /**
+ * Disposes the input method and release any resources it is using. In
+ * particular, the input method should dispose windows and close files. This
+ * is called by {@link InputContext#dispose()}, when the input method is
+ * inactive; and nothing will be called on this instance afterwards.
+ */
+ void dispose();
+
+ /**
+ * Returns a control object from this input method, or null. A control object
+ * provides method to control the behavior of this input method, as well as
+ * query information about it. The object is implementation dependent, so
+ * clients must compare the result against known input method control
+ * object types. This is called by
+ * {@link InputContext#getInputMethodControlObject()}.
+ *
+ * @return the control object, or null
+ */
+ Object getControlObject();
+} // interface InputMethod
diff --git a/libjava/classpath/java/awt/im/spi/InputMethodContext.java b/libjava/classpath/java/awt/im/spi/InputMethodContext.java
new file mode 100644
index 0000000..43bee8d
--- /dev/null
+++ b/libjava/classpath/java/awt/im/spi/InputMethodContext.java
@@ -0,0 +1,123 @@
+/* InputMethodContext.java -- communication between an input method and client
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.im.spi;
+
+import java.awt.Window;
+import java.awt.font.TextHitInfo;
+import java.awt.im.InputMethodRequests;
+import java.text.AttributedCharacterIterator;
+
+import javax.swing.JFrame;
+
+/**
+ * Provides methods for the communication context between an input method
+ * and the client component. This should be passed to
+ * {@link InputMethod#setInputMethodContext(InputMethodContext)}.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public interface InputMethodContext extends InputMethodRequests
+{
+ /**
+ * Create an input method event and dispatch it to the client.
+ *
+ * @param id the event type
+ * @param text an iterator over the text to be committed
+ * @param count the count of characters to be committed
+ * @param caret the insertion point of the commit, or null
+ * @param visiblePosition the best location to make visible, or null
+ */
+ void dispatchInputMethodEvent(int id, AttributedCharacterIterator text,
+ int count, TextHitInfo caret,
+ TextHitInfo visiblePosition);
+
+ /**
+ * Creates a top-level window for use by the input method. This window should
+ * float above all document windows and dialogs, not receive focus, and have
+ * lightweight decorations (such as no title, reduced drag regions). But
+ * this behavior may be modified to meet the platform style. The title may
+ * or may not be displayed, depending on the platform.
+ *
+ * <p>If attachToInputContext is true, the new window will share the input
+ * context of the input method, so that events in the new window are
+ * dispatched to the input method. Also, this supresses deactivate and
+ * activate calls to the input method caused by setVisible.
+ *
+ * @param title the window title, if one is displayed; null becomes ""
+ * @param attachToInputContext true for the window to share context with
+ * the input method
+ * @return the new window for use by the input method
+ * @throws HeadlessException if GraphicsEnvironment.isHeadless is true
+ */
+ Window createInputMethodWindow(String title, boolean attachToInputContext);
+
+ /**
+ * Creates a top-level Swing JFrame for use by the input method. This frame
+ * should float above all document windows and dialogs, not receive focus,
+ * and have lightweight decorations (such as no title, reduced drag
+ * regions). But this behavior may be modified to meet the platform style.
+ * The title may or may not be displayed, depending on the platform.
+ *
+ * <p>If attachToInputContext is true, the new window will share the input
+ * context of the input method, so that events in the new window are
+ * dispatched to the input method. Also, this supresses deactivate and
+ * activate calls to the input method caused by setVisible.
+ *
+ * @param title the window title, if one is displayed; null becomes ""
+ * @param attachToInputContext true for the window to share context with
+ * the input method
+ * @return the new window for use by the input method
+ * @throws HeadlessException if GraphicsEnvironment.isHeadless is true
+ * @since 1.4
+ */
+ JFrame createInputMethodJFrame(String title, boolean attachToInputContext);
+
+ /**
+ * Sets whether notification of the client window's location and state should
+ * be enabled for the input method. When enabled, the input method's
+ * {@link #notifyClientWindowChange(Rectangle)} method is called.
+ * Notification is automatically disabled when the input method is disposed.
+ *
+ * @param inputMethod the method to change status of
+ * @param enable true to enable notification
+ */
+ void enableClientWindowNotification(InputMethod inputMethod, boolean enable);
+} // interface InputMethodContext
diff --git a/libjava/classpath/java/awt/im/spi/InputMethodDescriptor.java b/libjava/classpath/java/awt/im/spi/InputMethodDescriptor.java
new file mode 100644
index 0000000..093d731
--- /dev/null
+++ b/libjava/classpath/java/awt/im/spi/InputMethodDescriptor.java
@@ -0,0 +1,113 @@
+/* InputMethodDescriptor.java -- enables loading and use of an input method
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.im.spi;
+
+import java.awt.AWTException;
+import java.awt.Image;
+import java.util.Locale;
+
+/**
+ * This interface provides information about an InputMethod before it is
+ * loaded.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.3
+ * @status updated to 1.4
+ */
+public interface InputMethodDescriptor
+{
+ /**
+ * Returns the locales supported by the input method this describes. This
+ * allows the selection of input methods by locale (by language only, or
+ * also by country and variant), via
+ * {@link InputContext#selectInputMethod(Locale)}. The returned list should
+ * ignore pass-through locales, so it is usually a subset of locales for
+ * which {@link InputMethod#setContext(Locale)} returns true. If
+ * {@link #hasDynamicLocaleList()} returns true, this is called each time
+ * information is needed, allowing dynamic addition or removal of supported
+ * locales.
+ *
+ * @return the list of supported locales
+ * @throws AWTException if the input method is not available
+ */
+ Locale[] getAvailableLocales() throws AWTException;
+
+ /**
+ * Test whether the input method this describes has a static or dynamic
+ * locale list. For example, this would return true if the list of supported
+ * locales depends on adapters currently loaded over a network.
+ *
+ * @return true if the locale list is dynamic
+ */
+ boolean hasDynamicLocaleList();
+
+ /**
+ * Returns a user visible name of the input locale, displayed in the
+ * specified locale. The inputLocale parameter must be one obtained from
+ * the list in {@link #getAvailableLocales()}, or null for a
+ * locale-independent description of the input method. If a translation to
+ * the desired display language is not available, another language may be
+ * used.
+ *
+ * @param inputLocale the locale of the input method, or null
+ * @param displayLanguage the language of the result
+ * @return the name of the input method when using the given inputLocale
+ */
+ String getInputMethodDisplayName(Locale inputLocale,
+ Locale displayLanguage);
+
+ /**
+ * Returns a 16x16 icon for the input locale. The inputLocale parameter
+ * must be one obtained from the list in {@link #getAvailableLocales()}, or
+ * null for a locale-independent icon for the input method.
+ *
+ * @param inputLocale the locale of the input method, or null
+ * @return a 16x16 icon for the input method when using the given inputLocale
+ */
+ Image getInputMethodIcon(Locale inputLocale);
+
+ /**
+ * Creates a new instance of the input method.
+ *
+ * @return the newly created input method
+ * @throws Exception if anything goes wrong
+ */
+ InputMethod createInputMethod() throws Exception;
+
+} // interface InputMethodDescriptor
+
diff --git a/libjava/classpath/java/awt/im/spi/package.html b/libjava/classpath/java/awt/im/spi/package.html
new file mode 100644
index 0000000..c526ee1
--- /dev/null
+++ b/libjava/classpath/java/awt/im/spi/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.im.spi package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.im.spi</title></head>
+
+<body>
+<p>Interfaces for implementation of text input methods.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/image/AffineTransformOp.java b/libjava/classpath/java/awt/image/AffineTransformOp.java
new file mode 100644
index 0000000..f11066e
--- /dev/null
+++ b/libjava/classpath/java/awt/image/AffineTransformOp.java
@@ -0,0 +1,375 @@
+/* AffineTransformOp.java -- This class performs affine
+ transformation between two images or rasters in 2 dimensions.
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+/**
+ * This class performs affine transformation between two images or
+ * rasters in 2 dimensions.
+ *
+ * @author Olga Rodimina (rodimina@redhat.com)
+ */
+public class AffineTransformOp implements BufferedImageOp, RasterOp
+{
+ public static final int TYPE_NEAREST_NEIGHBOR = 1;
+
+ public static final int TYPE_BILINEAR = 2;
+
+ /**
+ * @since 1.5.0
+ */
+ public static final int TYPE_BICUBIC = 3;
+
+ private AffineTransform transform;
+ private RenderingHints hints;
+
+ /**
+ * Construct AffineTransformOp with the given xform and interpolationType.
+ * Interpolation type can be TYPE_BILINEAR, TYPE_BICUBIC or
+ * TYPE_NEAREST_NEIGHBOR.
+ *
+ * @param xform AffineTransform that will applied to the source image
+ * @param interpolationType type of interpolation used
+ */
+ public AffineTransformOp (AffineTransform xform, int interpolationType)
+ {
+ this.transform = xform;
+ if (xform.getDeterminant() == 0)
+ throw new ImagingOpException(null);
+
+ switch (interpolationType)
+ {
+ case TYPE_BILINEAR:
+ hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ break;
+ case TYPE_BICUBIC:
+ hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+ break;
+ default:
+ hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+ }
+ }
+
+ /**
+ * Construct AffineTransformOp with the given xform and rendering hints.
+ *
+ * @param xform AffineTransform that will applied to the source image
+ * @param hints rendering hints that will be used during transformation
+ */
+ public AffineTransformOp (AffineTransform xform, RenderingHints hints)
+ {
+ this.transform = xform;
+ this.hints = hints;
+ if (xform.getDeterminant() == 0)
+ throw new ImagingOpException(null);
+ }
+
+ /**
+ * Creates empty BufferedImage with the size equal to that of the
+ * transformed image and correct number of bands. The newly created
+ * image is created with the specified ColorModel.
+ * If the ColorModel is equal to null, then image is created
+ * with the ColorModel of the source image.
+ *
+ * @param src source image
+ * @param destCM color model for the destination image
+ * @return new compatible destination image
+ */
+ public BufferedImage createCompatibleDestImage (BufferedImage src,
+ ColorModel destCM)
+ {
+
+ // if destCm is not specified, use color model of the source image
+
+ if (destCM == null)
+ destCM = src.getColorModel ();
+
+ return new BufferedImage (destCM,
+ createCompatibleDestRaster (src.getRaster ()),
+ src.isAlphaPremultiplied (),
+ null);
+
+ }
+
+ /**
+ * Creates empty WritableRaster with the size equal to the transformed
+ * source raster and correct number of bands
+ *
+ * @param src source raster
+ * @throws RasterFormatException if resulting width or height of raster is 0
+ * @return new compatible raster
+ */
+ public WritableRaster createCompatibleDestRaster (Raster src)
+ {
+ Rectangle rect = (Rectangle) getBounds2D (src);
+
+ // throw RasterFormatException if resulting width or height of the
+ // transformed raster is 0
+
+ if (rect.getWidth () == 0 || rect.getHeight () == 0)
+ throw new RasterFormatException("width or height is 0");
+
+ return src.createCompatibleWritableRaster ((int) rect.getWidth (),
+ (int) rect.getHeight ());
+ }
+
+ /**
+ * Transforms source image using transform specified at the constructor.
+ * The resulting transformed image is stored in the destination image.
+ *
+ * @param src source image
+ * @param dst destination image
+ * @return transformed source image
+ */
+ public final BufferedImage filter (BufferedImage src, BufferedImage dst)
+ {
+
+ if (dst == src)
+ throw new IllegalArgumentException ("src image cannot be the same as the dst image");
+
+ // If the destination image is null, then BufferedImage is
+ // created with ColorModel of the source image
+
+ if (dst == null)
+ dst = createCompatibleDestImage(src, src.getColorModel ());
+
+ // FIXME: Must check if color models of src and dst images are the same.
+ // If it is not, then source image should be converted to color model
+ // of the destination image
+
+ Graphics2D gr = (Graphics2D) dst.createGraphics ();
+ gr.setRenderingHints (hints);
+ gr.drawImage (src, transform, null);
+ return dst;
+
+ }
+
+ /**
+ * Transforms source raster using transform specified at the constructor.
+ * The resulting raster is stored in the destination raster.
+ *
+ * @param src source raster
+ * @param dst destination raster
+ * @return transformed raster
+ */
+ public final WritableRaster filter (Raster src, WritableRaster dst)
+ {
+ if (dst == src)
+ throw new IllegalArgumentException("src image cannot be the same as"
+ + " the dst image");
+
+ if (dst == null)
+ dst = createCompatibleDestRaster(src);
+
+ if (src.getNumBands() != dst.getNumBands())
+ throw new IllegalArgumentException("src and dst must have same number"
+ + " of bands");
+
+ double[] dpts = new double[dst.getWidth() * 2];
+ double[] pts = new double[dst.getWidth() * 2];
+ for (int x = 0; x < dst.getWidth(); x++)
+ {
+ dpts[2 * x] = x + dst.getMinX();
+ dpts[2 * x + 1] = x;
+ }
+ Rectangle srcbounds = src.getBounds();
+ if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
+ {
+ for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
+ {
+ try {
+ transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
+ } catch (NoninvertibleTransformException e) {
+ // Can't happen since the constructor traps this
+ e.printStackTrace();
+ }
+
+ for (int x = 0; x < dst.getWidth(); x++)
+ {
+ if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
+ continue;
+ dst.setDataElements(x + dst.getMinX(), y,
+ src.getDataElements((int)pts[2 * x],
+ (int)pts[2 * x + 1],
+ null));
+ }
+ }
+ }
+ else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+ {
+ double[] tmp = new double[4 * src.getNumBands()];
+ for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
+ {
+ try {
+ transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
+ } catch (NoninvertibleTransformException e) {
+ // Can't happen since the constructor traps this
+ e.printStackTrace();
+ }
+
+ for (int x = 0; x < dst.getWidth(); x++)
+ {
+ if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
+ continue;
+ int xx = (int)pts[2 * x];
+ int yy = (int)pts[2 * x + 1];
+ double dx = (pts[2 * x] - xx);
+ double dy = (pts[2 * x + 1] - yy);
+
+ // TODO write this more intelligently
+ if (xx == src.getMinX() + src.getWidth() - 1 ||
+ yy == src.getMinY() + src.getHeight() - 1)
+ {
+ // bottom or right edge
+ Arrays.fill(tmp, 0);
+ src.getPixel(xx, yy, tmp);
+ }
+ else
+ {
+ // Normal case
+ src.getPixels(xx, yy, 2, 2, tmp);
+ for (int b = 0; b < src.getNumBands(); b++)
+ tmp[b] = dx * dy * tmp[b]
+ + (1 - dx) * dy * tmp[b + src.getNumBands()]
+ + dx * (1 - dy) * tmp[b + 2 * src.getNumBands()]
+ + (1 - dx) * (1 - dy) * tmp[b + 3 * src.getNumBands()];
+ }
+ dst.setPixel(x, y, tmp);
+ }
+ }
+ }
+ else
+ {
+ // Bicubic
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ return dst;
+ }
+
+ /**
+ * Transforms source image using transform specified at the constructor and
+ * returns bounds of the transformed image.
+ *
+ * @param src image to be transformed
+ * @return bounds of the transformed image.
+ */
+ public final Rectangle2D getBounds2D (BufferedImage src)
+ {
+ return getBounds2D (src.getRaster());
+ }
+
+ /**
+ * Returns bounds of the transformed raster.
+ *
+ * @param src raster to be transformed
+ * @return bounds of the transformed raster.
+ */
+ public final Rectangle2D getBounds2D (Raster src)
+ {
+ // determine new size for the transformed raster.
+ // Need to calculate transformed coordinates of the lower right
+ // corner of the raster. The upper left corner is always (0,0)
+
+ double x2 = (double) src.getWidth () + src.getMinX ();
+ double y2 = (double) src.getHeight () + src.getMinY ();
+ Point2D p2 = getPoint2D (new Point2D.Double (x2,y2), null);
+
+ Rectangle2D rect = new Rectangle (0, 0, (int) p2.getX (), (int) p2.getY ());
+ return rect.getBounds ();
+ }
+
+ /**
+ * Returns interpolation type used during transformations
+ *
+ * @return interpolation type
+ */
+ public final int getInterpolationType ()
+ {
+ if(hints.containsValue (RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+ return TYPE_BILINEAR;
+ else
+ return TYPE_NEAREST_NEIGHBOR;
+ }
+
+ /**
+ * Returns location of the transformed source point. The resulting point
+ * is stored in the dstPt if one is specified.
+ *
+ * @param srcPt point to be transformed
+ * @param dstPt destination point
+ * @return the location of the transformed source point.
+ */
+ public Point2D getPoint2D (Point2D srcPt, Point2D dstPt)
+ {
+ return transform.transform (srcPt, dstPt);
+ }
+
+ /**
+ * Returns rendering hints that are used during transformation.
+ *
+ * @return rendering hints
+ */
+ public final RenderingHints getRenderingHints ()
+ {
+ return hints;
+ }
+
+ /**
+ * Returns transform used in transformation between source and destination
+ * image.
+ *
+ * @return transform
+ */
+ public final AffineTransform getTransform ()
+ {
+ return transform;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/AreaAveragingScaleFilter.java b/libjava/classpath/java/awt/image/AreaAveragingScaleFilter.java
new file mode 100644
index 0000000..b9ca1b7
--- /dev/null
+++ b/libjava/classpath/java/awt/image/AreaAveragingScaleFilter.java
@@ -0,0 +1,127 @@
+/* AreaAveragingScaleFilter.java -- Java class for filtering images
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * This filter should produce images which do not have image artifacts
+ * like broken lines which were originally unbroken. The cost is of
+ * course speed. Using bi-linear interpolation here against 4 pixel
+ * points should give the desired results although Sun does not
+ * specify what the exact algorithm should be.
+ * <br>
+ * Currently this filter does nothing and needs to be implemented.
+ *
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public class AreaAveragingScaleFilter extends ReplicateScaleFilter
+{
+ /**
+ * Construct an instance of <code>AreaAveragingScaleFilter</code> which
+ * should be used in conjunction with a <code>FilteredImageSource</code>
+ * object.
+ *
+ * @param width the width of the destination image
+ * @param height the height of the destination image
+ */
+ public AreaAveragingScaleFilter(int width, int height) {
+ super(width, height);
+ }
+
+ /**
+ * The <code>ImageProducer</code> should call this method with a
+ * bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
+ * <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
+ * <code>SINGLEPASS</code>, <code>SINGLEFRAME</code> from the
+ * <code>ImageConsumer</code> interface.
+ * <br>
+ * FIXME - more than likely Sun's implementation desires
+ * <code>TOPDOWNLEFTRIGHT</code> order and this method is overloaded here
+ * in order to assure that mask is part of the hints added to
+ * the consumer.
+ *
+ * @param flags a bit mask of hints
+ * @see ImageConsumer
+ */
+ public void setHints(int flags)
+ {
+ consumer.setHints(flags);
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as a <code>byte</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels, int offset, int scansize)
+ {
+ consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as an <code>int</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels, int offset, int scansize)
+ {
+ consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
+ }
+
+}
+
diff --git a/libjava/classpath/java/awt/image/BandCombineOp.java b/libjava/classpath/java/awt/image/BandCombineOp.java
new file mode 100644
index 0000000..79efb02
--- /dev/null
+++ b/libjava/classpath/java/awt/image/BandCombineOp.java
@@ -0,0 +1,168 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Filter Raster pixels by applying a matrix.
+ *
+ * BandCombineOp applies a matrix to each pixel to produce new pixel values.
+ * The width of the matrix must be the same or one more than the number of
+ * bands in the source Raster. If one more, the pixels in the source are
+ * assumed to contain an implicit 1.0 at the end.
+ *
+ * The rows of the matrix are multiplied by the pixel to produce the values
+ * for the destination. Therefore the destination Raster must contain the
+ * same number of bands as the number of rows in the filter matrix.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ */
+public class BandCombineOp implements RasterOp
+{
+ private RenderingHints hints;
+ private float[][] matrix;
+
+ /**
+ * Construct a BandCombineOp.
+ *
+ * @param matrix The matrix to filter pixels with.
+ * @param hints Rendering hints to apply. Ignored.
+ */
+ public BandCombineOp(float[][] matrix, RenderingHints hints)
+ {
+ this.matrix = matrix;
+ this.hints = hints;
+ }
+
+ /**
+ * Filter Raster pixels through a matrix.
+ *
+ * Applies the Op matrix to source pixes to produce dest pixels. Each row
+ * of the matrix is multiplied by the src pixel components to produce the
+ * dest pixel. If matrix is one more than the number of bands in the src,
+ * the last element is implicitly multiplied by 1, i.e. added to the sum
+ * for that dest component.
+ *
+ * If dest is null, a suitable Raster is created. This implementation uses
+ * createCompatibleDestRaster.
+ *
+ * @param src The source Raster.
+ * @param dest The destination Raster, or null.
+ * @returns The destination Raster or an allocated Raster.
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster,
+ *java.awt.image.WritableRaster)
+ */
+ public WritableRaster filter(Raster src, WritableRaster dest) {
+ if (dest == null)
+ dest = createCompatibleDestRaster(src);
+
+ // Filter the pixels
+ float[] spix = new float[matrix[0].length];
+ float[] dpix = new float[matrix.length];
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ {
+ // In case matrix rows have implicit translation
+ spix[spix.length - 1] = 1.0f;
+ src.getPixel(x, y, spix);
+ for (int i = 0; i < matrix.length; i++)
+ {
+ dpix[i] = 0;
+ for (int j = 0; j < matrix[0].length; j++)
+ dpix[i] += spix[j] * matrix[i][j];
+ }
+ dest.setPixel(x, y, dpix);
+ }
+
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ /**
+ * Creates a new WritableRaster that can be used as the destination for this
+ * Op. This implementation creates a Banded Raster with data type FLOAT.
+ * @see
+ *java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return Raster.createBandedRaster(DataBuffer.TYPE_FLOAT, src.getWidth(),
+ src.getHeight(), matrix.length,
+ new Point(src.getMinX(), src.getMinY()));
+ }
+
+ /** Return corresponding destination point for source point.
+ *
+ * LookupOp will return the value of src unchanged.
+ * @param src The source point.
+ * @param dst The destination point.
+ * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D,
+ *java.awt.geom.Point2D)
+ */
+ public Point2D getPoint2D(Point2D src, Point2D dst)
+ {
+ if (dst == null) return (Point2D)src.clone();
+ dst.setLocation(src);
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getRenderingHints()
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /** Return the matrix for this Op. */
+ public float[][] getMatrix()
+ {
+ return matrix;
+ }
+
+}
diff --git a/libjava/classpath/java/awt/image/BandedSampleModel.java b/libjava/classpath/java/awt/image/BandedSampleModel.java
new file mode 100644
index 0000000..24d315a
--- /dev/null
+++ b/libjava/classpath/java/awt/image/BandedSampleModel.java
@@ -0,0 +1,548 @@
+/* Copyright (C) 2004, 2005, Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/**
+ * MultiPixelPackedSampleModel provides a single band model that supports
+ * multiple pixels in a single unit. Pixels have 2^n bits and 2^k pixels fit
+ * per data element.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ */
+public final class BandedSampleModel extends ComponentSampleModel
+{
+ private int[] bitMasks;
+ private int[] bitOffsets;
+ private int[] sampleSize;
+ private int dataBitOffset;
+ private int elemBits;
+ private int numberOfBits;
+ private int numElems;
+
+ private static int[] createBankArray(int size)
+ {
+ int[] result = new int[size];
+ for (int i = 0; i < size; i++)
+ result[i] = i;
+ return result;
+ }
+
+ public BandedSampleModel(int dataType, int w, int h, int numBands)
+ {
+ this(dataType, w, h, w, createBankArray(numBands), new int[numBands]);
+ }
+
+ public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
+ int[] bankIndices, int[] bandOffsets)
+ {
+ super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
+ }
+
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ // NOTE: blackdown 1.4.1 sets all offsets to 0. Sun's 1.4.2 docs
+ // disagree.
+
+ // Compress offsets so minimum is 0, others w*scanlineStride
+ int[] newoffsets = new int[bandOffsets.length];
+ int[] order = new int[bandOffsets.length];
+ for (int i=0; i < bandOffsets.length; i++)
+ order[i] = i;
+ // FIXME: This is N^2, but not a big issue, unless there's a lot of
+ // bands...
+ for (int i=0; i < bandOffsets.length; i++)
+ for (int j=i+1; j < bandOffsets.length; i++)
+ if (bankIndices[order[i]] > bankIndices[order[j]]
+ || (bankIndices[order[i]] == bankIndices[order[j]]
+ && bandOffsets[order[i]] > bandOffsets[order[j]]))
+ {
+ int t = order[i]; order[i] = order[j]; order[j] = t;
+ }
+ int bank = 0;
+ int offset = 0;
+ for (int i=0; i < bandOffsets.length; i++)
+ {
+ if (bankIndices[order[i]] != bank)
+ {
+ bank = bankIndices[order[i]];
+ offset = 0;
+ }
+ newoffsets[order[i]] = offset;
+ offset += w * scanlineStride;
+ }
+
+ return new BandedSampleModel(dataType, w, h, scanlineStride, bankIndices, newoffsets);
+ }
+
+
+ public SampleModel createSubsetSampleModel(int[] bands)
+ {
+ if (bands.length > bankIndices.length)
+ throw new
+ RasterFormatException("BandedSampleModel createSubsetSampleModel too"
+ +" many bands");
+ int[] newoff = new int[bands.length];
+ int[] newbanks = new int[bands.length];
+ for (int i=0; i < bands.length; i++)
+ {
+ int b = bands[i];
+ newoff[i] = bandOffsets[b];
+ newbanks[i] = bankIndices[b];
+ }
+
+ return new BandedSampleModel(dataType, width, height, scanlineStride,
+ newbanks, newoff);
+ }
+
+ /**
+ * Extract all samples of one pixel and return in an array of transfer type.
+ *
+ * Extracts the pixel at x, y from data and stores samples into the array
+ * obj. If obj is null, a new array of getTransferType() is created.
+ *
+ * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ * @see java.awt.image.SampleModel#getDataElements(int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public Object getDataElements(int x, int y, Object obj,
+ DataBuffer data)
+ {
+ int pixel = getSample(x, y, 0, data);
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ byte[] b = (byte[])obj;
+ if (b == null) b = new byte[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = (byte)getSample(x, y, i, data);
+ return b;
+ }
+ case DataBuffer.TYPE_SHORT:
+ case DataBuffer.TYPE_USHORT:
+ {
+ short[] b = (short[])obj;
+ if (b == null) b = new short[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = (short)getSample(x, y, i, data);
+ return b;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ int[] b = (int[])obj;
+ if (b == null) b = new int[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = getSample(x, y, i, data);
+ return b;
+ }
+ case DataBuffer.TYPE_FLOAT:
+ {
+ float[] b = (float[])obj;
+ if (b == null) b = new float[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = getSampleFloat(x, y, i, data);
+ return b;
+ }
+ case DataBuffer.TYPE_DOUBLE:
+ {
+ double[] b = (double[])obj;
+ if (b == null) b = new double[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = getSample(x, y, i, data);
+ return b;
+ }
+
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+ }
+
+ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[numBands];
+ for (int i=0; i < numBands; i++)
+ iArray[i] = getSample(x, y, i, data);
+
+ return iArray;
+ }
+
+ /**
+ * Copy pixels from a region into an array.
+ *
+ * Copies the samples of the pixels in the rectangle starting at x, y that
+ * is w pixels wide and h scanlines high. When there is more than one band,
+ * the samples stored in order before the next pixel. This ordering isn't
+ * well specified in Sun's docs as of 1.4.2.
+ *
+ * If iArray is null, a new array is allocated, filled, and returned.
+ *
+ * @param x The x-coordinate of the pixel rectangle to store in
+ * <code>iArray</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in
+ * <code>iArray</code>.
+ * @param w The width in pixels of the rectangle.
+ * @param h The height in pixels of the rectangle.
+ * @param iArray The int array to store the pixels into or null to force
+ * creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ */
+ public int[] getPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[w*h*numBands];
+ int outOffset = 0;
+ int maxX = x + w;
+ int maxY = y + h;
+ for (int yy = x; yy < maxY; yy++)
+ {
+ for (int xx = x; xx < maxX; xx++)
+ {
+ for (int b = 0; b < numBands; b++)
+ {
+ int offset = bandOffsets[b] + yy * scanlineStride + xx;
+ iArray[outOffset++] =
+ data.getElem(bankIndices[b], offset);
+ }
+ }
+ }
+ return iArray;
+ }
+
+ public int getSample(int x, int y, int b, DataBuffer data)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + x;
+ return data.getElem(bankIndices[b], offset);
+ }
+
+ public float getSampleFloat(int x, int y, int b, DataBuffer data)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + x;
+ return data.getElemFloat(bankIndices[b], offset);
+ }
+
+ public double getSampleDouble(int x, int y, int b, DataBuffer data)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + x;
+ return data.getElemDouble(bankIndices[b], offset);
+ }
+
+ /**
+ * Copy one band's samples from a region into an array.
+ *
+ * Copies from one band the samples of the pixels in the rectangle starting
+ * at x, y that is w pixels wide and h scanlines high.
+ *
+ * If iArray is null, a new array is allocated, filled, and returned.
+ *
+ * @param x The x-coordinate of the pixel rectangle to store in
+ * <code>iArray</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in
+ * <code>iArray</code>.
+ * @param w The width in pixels of the rectangle.
+ * @param h The height in pixels of the rectangle.
+ * @param b The band to retrieve.
+ * @param iArray The int array to store the pixels into or null to force
+ * creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ */
+ public int[] getSamples(int x, int y, int w, int h, int b, int[] iArray,
+ DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[w*h];
+ int outOffset = 0;
+ int maxX = x + w;
+ int maxY = y + h;
+ for (int yy = y; yy < maxY; yy++)
+ {
+ for (int xx = x; xx < maxX; xx++)
+ {
+ int offset = bandOffsets[b] + yy * scanlineStride + xx;
+ iArray[outOffset++] =
+ data.getElem(bankIndices[b], offset);
+ }
+ }
+ return iArray;
+ }
+
+
+ /**
+ * Set the pixel at x, y to the value in the first element of the primitive
+ * array obj.
+ *
+ * @param x The x-coordinate of the data elements in <code>obj</code>.
+ * @param y The y-coordinate of the data elements in <code>obj</code>.
+ * @param obj The primitive array containing the data elements to set.
+ * @param data The DataBuffer to store the data elements into.
+ * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public void setDataElements(int x, int y, Object obj, DataBuffer data)
+ {
+ int transferType = getTransferType();
+ if (getTransferType() != data.getDataType())
+ {
+ throw new IllegalArgumentException("transfer type ("+
+ getTransferType()+"), "+
+ "does not match data "+
+ "buffer type (" +
+ data.getDataType() +
+ ").");
+ }
+
+ int offset = y * scanlineStride + x;
+
+ try
+ {
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ DataBufferByte out = (DataBufferByte) data;
+ byte[] in = (byte[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
+ return;
+ }
+ case DataBuffer.TYPE_SHORT:
+ {
+ DataBufferShort out = (DataBufferShort) data;
+ short[] in = (short[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ DataBufferUShort out = (DataBufferUShort) data;
+ short[] in = (short[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ DataBufferInt out = (DataBufferInt) data;
+ int[] in = (int[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
+ return;
+ }
+ case DataBuffer.TYPE_FLOAT:
+ {
+ DataBufferFloat out = (DataBufferFloat) data;
+ float[] in = (float[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
+ return;
+ }
+ case DataBuffer.TYPE_DOUBLE:
+ {
+ DataBufferDouble out = (DataBufferDouble) data;
+ double[] in = (double[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
+ return;
+ }
+ default:
+ throw new ClassCastException("Unsupported data type");
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException aioobe)
+ {
+ String msg = "While writing data elements" +
+ ", x="+x+", y="+y+
+ ", width="+width+", height="+height+
+ ", scanlineStride="+scanlineStride+
+ ", offset="+offset+
+ ", data.getSize()="+data.getSize()+
+ ", data.getOffset()="+data.getOffset()+
+ ": " +
+ aioobe;
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+ }
+
+ public void setPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ for (int b=0; b < numBands; b++)
+ data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x,
+ iArray[b]);
+ }
+
+ public void setPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = y * scanlineStride + (x + ww);
+ for (int b=0; b < numBands; b++)
+ data.setElem(bankIndices[b], bandOffsets[b] + offset,
+ iArray[inOffset++]);
+ }
+ y++;
+ }
+ }
+
+ public void setSample(int x, int y, int b, int s, DataBuffer data)
+ {
+ data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
+ }
+
+ public void setSample(int x, int y, int b, float s, DataBuffer data)
+ {
+ data.setElemFloat(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
+ }
+
+ public void setSample(int x, int y, int b, double s, DataBuffer data)
+ {
+ data.setElemDouble(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
+ }
+
+ public void setSamples(int x, int y, int w, int h, int b, int[] iArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ DataBufferByte out = (DataBufferByte) data;
+ byte[] bank = out.getData(bankIndices[b]);
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ bank[offset] = (byte)iArray[inOffset++];
+ }
+ y++;
+ }
+ return;
+ }
+ case DataBuffer.TYPE_SHORT:
+ {
+ DataBufferShort out = (DataBufferShort) data;
+ short[] bank = out.getData(bankIndices[b]);
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ bank[offset] = (short)iArray[inOffset++];
+ }
+ y++;
+ }
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ DataBufferShort out = (DataBufferShort) data;
+ short[] bank = out.getData(bankIndices[b]);
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ bank[offset] = (short)iArray[inOffset++];
+ }
+ y++;
+ }
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ DataBufferInt out = (DataBufferInt) data;
+ int[] bank = out.getData(bankIndices[b]);
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ bank[offset] = iArray[inOffset++];
+ }
+ y++;
+ }
+ return;
+ }
+ case DataBuffer.TYPE_FLOAT:
+ case DataBuffer.TYPE_DOUBLE:
+ break;
+ default:
+ throw new ClassCastException("Unsupported data type");
+ }
+
+ // Default implementation probably slower for float and double
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ data.setElem(bankIndices[b], offset, iArray[inOffset++]);
+ }
+ y++;
+ }
+ }
+
+ /**
+ * Creates a String with some information about this SampleModel.
+ * @return A String describing this SampleModel.
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+ result.append(getClass().getName());
+ result.append("[");
+ result.append("scanlineStride=").append(scanlineStride);
+ for(int i=0; i < bitMasks.length; i+=1)
+ {
+ result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+ }
+
+ result.append("]");
+ return result.toString();
+ }
+}
diff --git a/libjava/classpath/java/awt/image/BufferStrategy.java b/libjava/classpath/java/awt/image/BufferStrategy.java
new file mode 100644
index 0000000..e86aad6
--- /dev/null
+++ b/libjava/classpath/java/awt/image/BufferStrategy.java
@@ -0,0 +1,124 @@
+/* BufferStrategy.java -- describes image buffering resources
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.BufferCapabilities;
+import java.awt.Graphics;
+
+/**
+ * This class describes a strategy for managing image buffering
+ * resources on a Canvas or Window. A given buffer strategy may make
+ * use of hardware acceleration or take advantage of features of the
+ * native graphics system. Examples of buffering strategies are
+ * double or triple buffering using either flipping or blitting. For
+ * the details of these algorithms see BufferCapabilities.
+ *
+ * To use a buffer strategy, you retrieve it from either the current
+ * GraphicsConfiguration or from the Component on which you'd like to
+ * draw. Then you can query the strategy's capabilities to make sure
+ * they're suitable.
+ *
+ * If the strategy's capabilities are suitable, you can obtain a
+ * graphics object and use it to draw with this strategy. Drawing
+ * with a buffer strategy requires extra care, however. You'll need
+ * to manually cause the next buffer to be shown on the output device.
+ * And since buffer strategies are usually implemented with a
+ * VolatileImage, you must frequently check that the contents of the
+ * buffer are valid and that the buffer still exists.
+ *
+ * A buffer strategy is usually implemented using a VolatileImage.
+ *
+ * @see VolatileImage
+ * @since 1.4
+ */
+public abstract class BufferStrategy
+{
+ /**
+ * Creates a new buffer strategy.
+ */
+ public BufferStrategy()
+ {
+ }
+
+ /**
+ * Retrieves the capabilities of this buffer strategy.
+ *
+ * @return this buffer strategy's capabilities
+ */
+ public abstract BufferCapabilities getCapabilities();
+
+ /**
+ * Retrieves a graphics object that can be used to draw using this
+ * buffer strategy. This method may not be synchronized so be
+ * careful when calling it from multiple threads. You also must
+ * manually dispose of this graphics object.
+ *
+ * @return a graphics object that can be used to draw using this
+ * buffer strategy
+ */
+ public abstract Graphics getDrawGraphics();
+
+ /**
+ * Returns whether or not the buffer's resources have been reclaimed
+ * by the native graphics system. If the buffer resources have been
+ * lost then you'll need to obtain new resources before drawing
+ * again. For details, see the documentation for VolatileImage.
+ *
+ * @return true if the contents were lost, false otherwise
+ */
+ public abstract boolean contentsLost();
+
+ /**
+ * Returns whether or not the buffer's resources were re-created and
+ * cleared to the default background color. If the buffer's
+ * resources have recently been re-created and initialized then the
+ * buffer's image may need to be re-rendered. For details, see the
+ * documentation for VolatileImage.
+ *
+ * @return true if the contents were restored, false otherwise
+ */
+ public abstract boolean contentsRestored();
+
+ /**
+ * Applies this buffer strategy. In other words, this method brings
+ * the contents of the back or intermediate buffers to the front
+ * buffer.
+ */
+ public abstract void show();
+}
diff --git a/libjava/classpath/java/awt/image/BufferedImage.java b/libjava/classpath/java/awt/image/BufferedImage.java
new file mode 100644
index 0000000..124b813
--- /dev/null
+++ b/libjava/classpath/java/awt/image/BufferedImage.java
@@ -0,0 +1,693 @@
+/* BufferedImage.java --
+ Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import gnu.java.awt.ComponentDataBlitOp;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+
+/**
+ * A buffered image always starts at coordinates (0, 0).
+ *
+ * The buffered image is not subdivided into multiple tiles. Instead,
+ * the image consists of one large tile (0,0) with the width and
+ * height of the image. This tile is always considered to be checked
+ * out.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public class BufferedImage extends Image
+ implements WritableRenderedImage
+{
+ public static final int TYPE_CUSTOM = 0,
+ TYPE_INT_RGB = 1,
+ TYPE_INT_ARGB = 2,
+ TYPE_INT_ARGB_PRE = 3,
+ TYPE_INT_BGR = 4,
+ TYPE_3BYTE_BGR = 5,
+ TYPE_4BYTE_ABGR = 6,
+ TYPE_4BYTE_ABGR_PRE = 7,
+ TYPE_USHORT_565_RGB = 8,
+ TYPE_USHORT_555_RGB = 9,
+ TYPE_BYTE_GRAY = 10,
+ TYPE_USHORT_GRAY = 11,
+ TYPE_BYTE_BINARY = 12,
+ TYPE_BYTE_INDEXED = 13;
+
+ static final int[] bits3 = { 8, 8, 8 };
+ static final int[] bits4 = { 8, 8, 8 };
+ static final int[] bits1byte = { 8 };
+ static final int[] bits1ushort = { 16 };
+
+ static final int[] masks_int = { 0x00ff0000,
+ 0x0000ff00,
+ 0x000000ff,
+ DataBuffer.TYPE_INT };
+ static final int[] masks_565 = { 0xf800,
+ 0x07e0,
+ 0x001f,
+ DataBuffer.TYPE_USHORT};
+ static final int[] masks_555 = { 0x7c00,
+ 0x03e0,
+ 0x001f,
+ DataBuffer.TYPE_USHORT};
+
+ Vector observers;
+
+ public BufferedImage(int w, int h, int type)
+ {
+ ColorModel cm = null;
+
+ boolean alpha = false;
+ boolean premultiplied = false;
+ switch (type)
+ {
+ case TYPE_4BYTE_ABGR_PRE:
+ case TYPE_INT_ARGB_PRE:
+ premultiplied = true;
+ // fall through
+ case TYPE_INT_ARGB:
+ case TYPE_4BYTE_ABGR:
+ alpha = true;
+ }
+
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ switch (type)
+ {
+ case TYPE_INT_RGB:
+ case TYPE_INT_ARGB:
+ case TYPE_INT_ARGB_PRE:
+ case TYPE_USHORT_565_RGB:
+ case TYPE_USHORT_555_RGB:
+ int[] masks = null;
+ switch (type)
+ {
+ case TYPE_INT_RGB:
+ case TYPE_INT_ARGB:
+ case TYPE_INT_ARGB_PRE:
+ masks = masks_int;
+ break;
+ case TYPE_USHORT_565_RGB:
+ masks = masks_565;
+ break;
+ case TYPE_USHORT_555_RGB:
+ masks = masks_555;
+ break;
+ }
+
+ cm = new DirectColorModel(cs,
+ 32, // 32 bits in an int
+ masks[0], // r
+ masks[1], // g
+ masks[2], // b
+ alpha ? 0xff000000 : 0,
+ premultiplied,
+ masks[3] // data type
+ );
+ break;
+
+ case TYPE_INT_BGR:
+ String msg =
+ "FIXME: Programmer is confused. Why (and how) does a " +
+ "TYPE_INT_BGR image use ComponentColorModel to store " +
+ "8-bit values? Is data type TYPE_INT or TYPE_BYTE. What " +
+ "is the difference between TYPE_INT_BGR and TYPE_3BYTE_BGR?";
+ throw new UnsupportedOperationException(msg);
+
+ case TYPE_3BYTE_BGR:
+ case TYPE_4BYTE_ABGR:
+ case TYPE_4BYTE_ABGR_PRE:
+ case TYPE_BYTE_GRAY:
+ case TYPE_USHORT_GRAY:
+ int[] bits = null;
+ int dataType = DataBuffer.TYPE_BYTE;
+ switch (type) {
+ case TYPE_3BYTE_BGR:
+ bits = bits3;
+ break;
+ case TYPE_4BYTE_ABGR:
+ case TYPE_4BYTE_ABGR_PRE:
+ bits = bits4;
+ break;
+ case TYPE_BYTE_GRAY:
+ bits = bits1byte;
+ break;
+ case TYPE_USHORT_GRAY:
+ bits = bits1ushort;
+ dataType = DataBuffer.TYPE_USHORT;
+ break;
+ }
+ cm = new ComponentColorModel(cs, bits, alpha, premultiplied,
+ alpha ?
+ Transparency.TRANSLUCENT:
+ Transparency.OPAQUE,
+ dataType);
+ break;
+ case TYPE_BYTE_BINARY:
+ byte[] vals = { 0, (byte) 0xff };
+ cm = new IndexColorModel(8, 2, vals, vals, vals);
+ break;
+ case TYPE_BYTE_INDEXED:
+ String msg2 = "type not implemented yet";
+ throw new UnsupportedOperationException(msg2);
+ // FIXME: build color-cube and create color model
+ }
+
+ init(cm,
+ cm.createCompatibleWritableRaster(w, h),
+ premultiplied,
+ null, // no properties
+ type
+ );
+ }
+
+ public BufferedImage(int w, int h, int type,
+ IndexColorModel indexcolormodel)
+ {
+ if ((type != TYPE_BYTE_BINARY) && (type != TYPE_BYTE_INDEXED))
+ throw new IllegalArgumentException("type must be binary or indexed");
+
+ init(indexcolormodel,
+ indexcolormodel.createCompatibleWritableRaster(w, h),
+ false, // not premultiplied (guess)
+ null, // no properties
+ type);
+ }
+
+ public BufferedImage(ColorModel colormodel,
+ WritableRaster writableraster,
+ boolean premultiplied,
+ Hashtable properties)
+ {
+ init(colormodel, writableraster, premultiplied, properties,
+ TYPE_CUSTOM);
+ // TODO: perhaps try to identify type?
+ }
+
+ WritableRaster raster;
+ ColorModel colorModel;
+ Hashtable properties;
+ boolean isPremultiplied;
+ int type;
+
+ private void init(ColorModel cm,
+ WritableRaster writableraster,
+ boolean premultiplied,
+ Hashtable properties,
+ int type)
+ {
+ raster = writableraster;
+ colorModel = cm;
+ this.properties = properties;
+ isPremultiplied = premultiplied;
+ this.type = type;
+ }
+
+ //public void addTileObserver(TileObserver tileobserver) {}
+
+ public void coerceData(boolean premultiplied)
+ {
+ colorModel = colorModel.coerceData(raster, premultiplied);
+ }
+
+ public WritableRaster copyData(WritableRaster dest)
+ {
+ if (dest == null)
+ dest = raster.createCompatibleWritableRaster(getMinX(), getMinY(),
+ getWidth(),getHeight());
+
+ int x = dest.getMinX();
+ int y = dest.getMinY();
+ int w = dest.getWidth();
+ int h = dest.getHeight();
+
+ // create a src child that has the right bounds...
+ WritableRaster src =
+ raster.createWritableChild(x, y, w, h, x, y,
+ null // same bands
+ );
+ if (src.getSampleModel () instanceof ComponentSampleModel
+ && dest.getSampleModel () instanceof ComponentSampleModel)
+ // Refer to ComponentDataBlitOp for optimized data blitting:
+ ComponentDataBlitOp.INSTANCE.filter(src, dest);
+ else
+ {
+ // slower path
+ int samples[] = src.getPixels (x, y, w, h, (int [])null);
+ dest.setPixels (x, y, w, h, samples);
+ }
+ return dest;
+ }
+
+ public Graphics2D createGraphics()
+ {
+ GraphicsEnvironment env;
+ env = GraphicsEnvironment.getLocalGraphicsEnvironment ();
+ return env.createGraphics (this);
+ }
+
+ public void flush() {
+ }
+
+ public WritableRaster getAlphaRaster()
+ {
+ return colorModel.getAlphaRaster(raster);
+ }
+
+ public ColorModel getColorModel()
+ {
+ return colorModel;
+ }
+
+ public Raster getData()
+ {
+ return copyData(null);
+ /* TODO: this might be optimized by returning the same
+ raster (not writable) as long as image data doesn't change. */
+ }
+
+ public Raster getData(Rectangle rectangle)
+ {
+ WritableRaster dest =
+ raster.createCompatibleWritableRaster(rectangle);
+ return copyData(dest);
+ }
+
+ public Graphics getGraphics()
+ {
+ return createGraphics();
+ }
+
+ public int getHeight()
+ {
+ return raster.getHeight();
+ }
+
+ public int getHeight(ImageObserver imageobserver)
+ {
+ return getHeight();
+ }
+
+ public int getMinTileX()
+ {
+ return 0;
+ }
+
+ public int getMinTileY()
+ {
+ return 0;
+ }
+
+ public int getMinX()
+ {
+ return 0;
+ }
+
+ public int getMinY()
+ {
+ return 0;
+ }
+
+ public int getNumXTiles()
+ {
+ return 1;
+ }
+
+ public int getNumYTiles()
+ {
+ return 1;
+ }
+
+ public Object getProperty(String string)
+ {
+ if (properties == null)
+ return null;
+ return properties.get(string);
+ }
+
+ public Object getProperty(String string, ImageObserver imageobserver)
+ {
+ return getProperty(string);
+ }
+
+
+ public String[] getPropertyNames()
+ {
+ // FIXME: implement
+ return null;
+ }
+
+ public int getRGB(int x, int y)
+ {
+ Object rgbElem = raster.getDataElements(x, y,
+ null // create as needed
+ );
+ return colorModel.getRGB(rgbElem);
+ }
+
+ public int[] getRGB(int startX, int startY, int w, int h,
+ int[] rgbArray,
+ int offset, int scanlineStride)
+ {
+ if (rgbArray == null)
+ {
+ /*
+ 000000000000000000
+ 00000[#######----- [ = start
+ -----########----- ] = end
+ -----#######]00000
+ 000000000000000000 */
+ int size = (h-1)*scanlineStride + w;
+ rgbArray = new int[size];
+ }
+
+ int endX = startX + w;
+ int endY = startY + h;
+
+ /* *TODO*:
+ Opportunity for optimization by examining color models...
+
+ Perhaps wrap the rgbArray up in a WritableRaster with packed
+ sRGB color model and perform optimized rendering into the
+ array. */
+
+ Object rgbElem = null;
+ for (int y=startY; y<endY; y++)
+ {
+ int xoffset = offset;
+ for (int x=startX; x<endX; x++)
+ {
+ int rgb;
+ rgbElem = raster.getDataElements(x, y, rgbElem);
+ rgb = colorModel.getRGB(rgbElem);
+ rgbArray[xoffset++] = rgb;
+ }
+ offset += scanlineStride;
+ }
+ return rgbArray;
+ }
+
+ public WritableRaster getRaster()
+ {
+ return raster;
+ }
+
+ public SampleModel getSampleModel()
+ {
+ return raster.getSampleModel();
+ }
+
+ public ImageProducer getSource()
+ {
+ return new ImageProducer() {
+
+ Vector consumers = new Vector();
+
+ public void addConsumer(ImageConsumer ic)
+ {
+ if(!consumers.contains(ic))
+ consumers.add(ic);
+ }
+
+ public boolean isConsumer(ImageConsumer ic)
+ {
+ return consumers.contains(ic);
+ }
+
+ public void removeConsumer(ImageConsumer ic)
+ {
+ consumers.remove(ic);
+ }
+
+ public void startProduction(ImageConsumer ic)
+ {
+ int x = 0;
+ int y = 0;
+ int width = getWidth();
+ int height = getHeight();
+ int stride = width;
+ int offset = 0;
+ int[] pixels = getRGB(x, y,
+ width, height,
+ (int[])null, offset, stride);
+ ColorModel model = getColorModel();
+
+ consumers.add(ic);
+
+ for(int i=0;i<consumers.size();i++)
+ {
+ ImageConsumer c = (ImageConsumer) consumers.elementAt(i);
+ c.setHints(ImageConsumer.SINGLEPASS);
+ c.setDimensions(getWidth(), getHeight());
+ c.setPixels(x, y, width, height, model, pixels, offset, stride);
+ c.imageComplete(ImageConsumer.STATICIMAGEDONE);
+ }
+ }
+
+ public void requestTopDownLeftRightResend(ImageConsumer ic)
+ {
+ startProduction(ic);
+ }
+
+ };
+ }
+
+ public Vector getSources()
+ {
+ return null;
+ }
+
+ public BufferedImage getSubimage(int x, int y, int w, int h)
+ {
+ WritableRaster subRaster =
+ getRaster().createWritableChild(x, y, w, h, 0, 0, null);
+
+ return new BufferedImage(getColorModel(),
+ subRaster,
+ isPremultiplied,
+ properties);
+ }
+
+ public Raster getTile(int tileX, int tileY)
+ {
+ return getWritableTile(tileX, tileY);
+ }
+
+ public int getTileGridXOffset()
+ {
+ return 0; // according to javadocs
+ }
+
+ public int getTileGridYOffset()
+ {
+ return 0; // according to javadocs
+ }
+
+ public int getTileHeight()
+ {
+ return getHeight(); // image is one big tile
+ }
+
+ public int getTileWidth()
+ {
+ return getWidth(); // image is one big tile
+ }
+
+ public int getType()
+ {
+ return type;
+ }
+
+ public int getWidth()
+ {
+ return raster.getWidth();
+ }
+
+ public int getWidth(ImageObserver imageobserver)
+ {
+ return getWidth();
+ }
+
+ public WritableRaster getWritableTile(int tileX, int tileY)
+ {
+ isTileWritable(tileX, tileY); // for exception
+ return raster;
+ }
+
+ private static final Point[] tileIndices = { new Point() };
+
+ public Point[] getWritableTileIndices()
+ {
+ return tileIndices;
+ }
+
+ public boolean hasTileWriters()
+ {
+ return true;
+ }
+
+ public boolean isAlphaPremultiplied()
+ {
+ return isPremultiplied;
+ }
+
+ public boolean isTileWritable(int tileX, int tileY)
+ {
+ if ((tileX != 0) || (tileY != 0))
+ throw new ArrayIndexOutOfBoundsException("only tile is (0,0)");
+ return true;
+ }
+
+ public void releaseWritableTile(int tileX, int tileY)
+ {
+ isTileWritable(tileX, tileY); // for exception
+ }
+
+ //public void removeTileObserver(TileObserver tileobserver) {}
+
+ public void setData(Raster src)
+ {
+ int x = src.getMinX();
+ int y = src.getMinY();
+ int w = src.getWidth();
+ int h = src.getHeight();
+
+ // create a dest child that has the right bounds...
+ WritableRaster dest =
+ raster.createWritableChild(x, y, w, h, x, y,
+ null // same bands
+ );
+
+ if (src.getSampleModel () instanceof ComponentSampleModel
+ && dest.getSampleModel () instanceof ComponentSampleModel)
+
+ // Refer to ComponentDataBlitOp for optimized data blitting:
+ ComponentDataBlitOp.INSTANCE.filter(src, dest);
+ else
+ {
+ // slower path
+ int samples[] = src.getPixels (x, y, w, h, (int [])null);
+ dest.setPixels (x, y, w, h, samples);
+ }
+ }
+
+ public void setRGB(int x, int y, int argb)
+ {
+ Object rgbElem = colorModel.getDataElements(argb, null);
+ raster.setDataElements(x, y, rgbElem);
+ }
+
+ public void setRGB(int startX, int startY, int w, int h,
+ int[] argbArray, int offset, int scanlineStride)
+ {
+ int endX = startX + w;
+ int endY = startY + h;
+
+ Object rgbElem = null;
+ for (int y=startY; y<endY; y++)
+ {
+ int xoffset = offset;
+ for (int x=startX; x<endX; x++)
+ {
+ int argb = argbArray[xoffset++];
+ rgbElem = colorModel.getDataElements(argb, rgbElem);
+ raster.setDataElements(x, y, rgbElem);
+ }
+ offset += scanlineStride;
+ }
+ }
+
+ public String toString()
+ {
+ StringBuffer buf;
+
+ buf = new StringBuffer(/* estimated length */ 120);
+ buf.append("BufferedImage@");
+ buf.append(Integer.toHexString(hashCode()));
+ buf.append(": type=");
+ buf.append(type);
+ buf.append(' ');
+ buf.append(colorModel);
+ buf.append(' ');
+ buf.append(raster);
+
+ return buf.toString();
+ }
+
+
+ /**
+ * Adds a tile observer. If the observer is already present, it receives
+ * multiple notifications.
+ *
+ * @param to The TileObserver to add.
+ */
+ public void addTileObserver (TileObserver to)
+ {
+ if (observers == null)
+ observers = new Vector ();
+
+ observers.add (to);
+ }
+
+ /**
+ * Removes a tile observer. If the observer was not registered,
+ * nothing happens. If the observer was registered for multiple
+ * notifications, it is now registered for one fewer notification.
+ *
+ * @param to The TileObserver to remove.
+ */
+ public void removeTileObserver (TileObserver to)
+ {
+ if (observers == null)
+ return;
+
+ observers.remove (to);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/BufferedImageFilter.java b/libjava/classpath/java/awt/image/BufferedImageFilter.java
new file mode 100644
index 0000000..50d627d
--- /dev/null
+++ b/libjava/classpath/java/awt/image/BufferedImageFilter.java
@@ -0,0 +1,110 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+import java.awt.Point;
+
+/**
+ * The BufferedImageFilter class wraps BufferedImageOp objects in a Filter.
+ *
+ * When pixels are pushed through the filter, we create a BufferedImage,
+ * apply the BufferedImageOp, and pass the filtered pixels to the base class.
+ *
+ * @author jlquinn@optonline.net
+ */
+public class BufferedImageFilter extends ImageFilter implements Cloneable
+{
+ private BufferedImageOp op;
+
+ /**
+ *
+ */
+ public BufferedImageFilter(BufferedImageOp op)
+ {
+ super();
+ if (op == null)
+ throw new NullPointerException("BufferedImageFilter null"
+ + " op in constructor");
+ this.op = op;
+ }
+
+ /**
+ * @return Returns the contained BufferedImageOp.
+ */
+ public BufferedImageOp getBufferedImageOp()
+ {
+ return op;
+ }
+
+ // FIXME: Definitely not sure this is the right thing. I'm not sure how to
+ // create a compatible sample model that incorporates scansize != w. I
+ // asume off is handled by the db itself.
+ public void setPixels(int x, int y, int w, int h, ColorModel model,
+ byte[] pixels, int off, int scansize)
+ {
+ // Create an input BufferedImage
+ DataBufferByte db = new DataBufferByte(pixels, scansize * h + off, off);
+ SampleModel sm = model.createCompatibleSampleModel(scansize, h);
+ WritableRaster wr = new WritableRaster(sm, db, new Point(0, 0));
+ BufferedImage in =
+ new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
+ BufferedImage out = op.createCompatibleDestImage(in, model);
+ op.filter(in, out);
+ DataBuffer dbout = out.getRaster().getDataBuffer();
+ super.setPixels(0, 0, w, h, model, ((DataBufferByte)dbout).getData(), 0,
+ scansize);
+ }
+
+ // FIXME: Definitely not sure this is the right thing. I'm not sure how
+ // to create a compatible sample model that incorporates
+ // scansize != w. I asume off is handled by the db itself.
+ public void setPixels(int x, int y, int w, int h, ColorModel model,
+ int[] pixels, int off, int scansize)
+ {
+ // Create an input BufferedImage
+ DataBufferInt db = new DataBufferInt(pixels, scansize * h + off, off);
+ SampleModel sm = model.createCompatibleSampleModel(scansize, h);
+ WritableRaster wr = new WritableRaster(sm, db, new Point(0, 0));
+ BufferedImage in =
+ new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
+ BufferedImage out = op.createCompatibleDestImage(in, model);
+ op.filter(in, out);
+ DataBuffer dbout = out.getRaster().getDataBuffer();
+ super.setPixels(0, 0, w, h, model, ((DataBufferInt)dbout).getData(), 0,
+ scansize);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/BufferedImageOp.java b/libjava/classpath/java/awt/image/BufferedImageOp.java
new file mode 100644
index 0000000..2ecbec0
--- /dev/null
+++ b/libjava/classpath/java/awt/image/BufferedImageOp.java
@@ -0,0 +1,55 @@
+/* BufferedImageOp.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * NEEDS DOCUMENTATION
+ */
+public interface BufferedImageOp
+{
+ BufferedImage filter(BufferedImage src, BufferedImage dst);
+ Rectangle2D getBounds2D(BufferedImage src);
+ BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM);
+ Point2D getPoint2D(Point2D src, Point2D dst);
+ RenderingHints getRenderingHints();
+} // interface BufferedImageOp
diff --git a/libjava/classpath/java/awt/image/ByteLookupTable.java b/libjava/classpath/java/awt/image/ByteLookupTable.java
new file mode 100644
index 0000000..df02d0a
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ByteLookupTable.java
@@ -0,0 +1,166 @@
+/* ByteLookupTable.java -- Java class for a pixel translation table.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * ByteLookupTable represents translation arrays for pixel values. It wraps
+ * one or more data arrays for each layer (or component) in an image, such as
+ * Alpha, R, G, and B. When doing translation, the offset is subtracted from
+ * the pixel values to allow a subset of an array to be used.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ * @version 1.0
+ */
+public class ByteLookupTable extends LookupTable
+{
+ // Array of translation tables.
+ private byte data[][];
+
+ /**
+ * Creates a new <code>ByteLookupTable</code> instance.
+ *
+ * Offset is subtracted from pixel values when looking up in the translation
+ * tables. If data.length is one, the same table is applied to all pixel
+ * components.
+ *
+ * @param offset Offset to be subtracted.
+ * @param data Array of lookup tables.
+ * @exception IllegalArgumentException if offset &lt; 0 or data.length &lt; 1.
+ */
+ public ByteLookupTable(int offset, byte[][] data)
+ throws IllegalArgumentException
+ {
+ super(offset, data.length);
+ this.data = data;
+ }
+
+ /**
+ * Creates a new <code>ByteLookupTable</code> instance.
+ *
+ * Offset is subtracted from pixel values when looking up in the translation
+ * table. The same table is applied to all pixel components.
+ *
+ * @param offset Offset to be subtracted.
+ * @param data Lookup table for all components.
+ * @exception IllegalArgumentException if offset &lt; 0.
+ */
+ public ByteLookupTable(int offset, byte[] data)
+ throws IllegalArgumentException
+ {
+ super(offset, 1);
+ this.data = new byte[][] {data};
+ }
+
+ /**
+ * Return the lookup tables.
+ *
+ * @return the tables
+ */
+ public final byte[][] getTable()
+ {
+ return data;
+ }
+
+ /**
+ * Return translated values for a pixel.
+ *
+ * For each value in the pixel src, use the value minus offset as an index
+ * in the component array and copy the value there to the output for the
+ * component. If dest is null, the output is a new array, otherwise the
+ * translated values are written to dest. Dest can be the same array as
+ * src.
+ *
+ * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+ * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+ * translation arrays.
+ *
+ * @param src Component values of a pixel.
+ * @param dst Destination array for values, or null.
+ * @return Translated values for the pixel.
+ */
+ public int[] lookupPixel(int[] src, int[] dst)
+ throws ArrayIndexOutOfBoundsException
+ {
+ if (dst == null)
+ dst = new int[src.length];
+
+ if (data.length == 1)
+ for (int i=0; i < src.length; i++)
+ dst[i] = data[0][src[i] - offset];
+ else
+ for (int i=0; i < src.length; i++)
+ dst[i] = data[i][src[i] - offset];
+
+ return dst;
+ }
+
+ /**
+ * Return translated values for a pixel.
+ *
+ * For each value in the pixel src, use the value minus offset as an index
+ * in the component array and copy the value there to the output for the
+ * component. If dest is null, the output is a new array, otherwise the
+ * translated values are written to dest. Dest can be the same array as
+ * src.
+ *
+ * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+ * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+ * translation arrays.
+ *
+ * @param src Component values of a pixel.
+ * @param dst Destination array for values, or null.
+ * @return Translated values for the pixel.
+ */
+ public byte[] lookupPixel(byte[] src, byte[] dst)
+ throws ArrayIndexOutOfBoundsException
+ {
+ if (dst == null)
+ dst = new byte[src.length];
+
+ if (data.length == 1)
+ for (int i=0; i < src.length; i++)
+ dst[i] = data[0][((int)src[i]) - offset];
+ else
+ for (int i=0; i < src.length; i++)
+ dst[i] = data[i][((int)src[i]) - offset];
+
+ return dst;
+
+ }
+}
diff --git a/libjava/classpath/java/awt/image/ColorConvertOp.java b/libjava/classpath/java/awt/image/ColorConvertOp.java
new file mode 100644
index 0000000..18609e0
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ColorConvertOp.java
@@ -0,0 +1,319 @@
+/* ColorModel.java --
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * ColorConvertOp is a filter for converting an image from one colorspace to
+ * another colorspace. The filter can convert the image through a sequence
+ * of colorspaces or just from source to destination.
+ *
+ * Color conversion is done on the color components without alpha. Thus
+ * if a BufferedImage has alpha premultiplied, this is divided out before
+ * color conversion, and premultiplication applied if the destination
+ * requires it.
+ *
+ * Color rendering and dithering hints may be applied if specified. This is
+ * likely platform-dependent.
+ *
+ * @author jlquinn@optonline.net
+ */
+public class ColorConvertOp implements BufferedImageOp, RasterOp
+{
+ private ColorSpace srccs;
+ private ColorSpace dstcs;
+ private RenderingHints hints;
+ private ICC_Profile[] profiles;
+ private ColorSpace[] spaces;
+ private boolean rasterValid;
+
+
+ /**
+ * Convert BufferedImage through a ColorSpace.
+ *
+ * This filter version is only valid for BufferedImages. The source image
+ * is converted to cspace. If the destination is not null, it is then
+ * converted to the destination colorspace. Normally this filter will only
+ * be used with a null destination.
+ *
+ * @param cspace The target color space.
+ * @param hints Rendering hints to use in conversion, or null.
+ */
+ public ColorConvertOp(ColorSpace cspace, RenderingHints hints)
+ {
+ if (cspace == null)
+ throw new NullPointerException();
+ spaces = new ColorSpace[]{cspace};
+ this.hints = hints;
+ rasterValid = false;
+ }
+
+ public ColorConvertOp(ColorSpace srcCspace, ColorSpace dstCspace,
+ RenderingHints hints)
+ {
+ if (srcCspace == null || dstCspace == null)
+ throw new NullPointerException();
+ spaces = new ColorSpace[]{srcCspace, dstCspace};
+ this.hints = hints;
+ }
+
+ /**
+ * Convert from a source image destination image color space.
+ *
+ * This constructor builds a ColorConvertOp from an array of ICC_Profiles.
+ * The source image will be converted through the sequence of color spaces
+ * defined by the profiles. If the sequence of profiles doesn't give a
+ * well-defined conversion, throws IllegalArgumentException.
+ *
+ * NOTE: Sun's docs don't clearly define what a well-defined conversion is
+ * - or perhaps someone smarter can come along and sort it out.
+ *
+ * For BufferedImages, when the first and last profiles match the
+ * requirements of the source and destination color space respectively, the
+ * corresponding conversion is unnecessary. TODO: code this up. I don't
+ * yet understand how you determine this.
+ *
+ * For Rasters, the first and last profiles must have the same number of
+ * bands as the source and destination Rasters, respectively. If this is
+ * not the case, or there fewer than 2 profiles, an IllegalArgumentException
+ * will be thrown.
+ *
+ * @param profiles
+ * @param hints
+ */
+ public ColorConvertOp(ICC_Profile[] profiles, RenderingHints hints)
+ {
+ if (profiles == null)
+ throw new NullPointerException();
+ this.hints = hints;
+ this.profiles = profiles;
+ // TODO: Determine if this is well-defined.
+ // Create colorspace array with space for src and dest colorspace
+ spaces = new ColorSpace[profiles.length];
+ for (int i = 0; i < profiles.length; i++)
+ spaces[i] = new ICC_ColorSpace(profiles[i]);
+ }
+
+ /** Convert from source image color space to destination image color space.
+ *
+ * Only valid for BufferedImage objects, this Op converts from the source
+ * color space to the destination color space. The destination can't be
+ * null for this operation.
+ *
+ * @param hints Rendering hints to use during conversion, or null.
+ */
+ public ColorConvertOp(RenderingHints hints)
+ {
+ this.hints = hints;
+ srccs = null;
+ dstcs = null;
+ rasterValid = false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage,
+ java.awt.image.BufferedImage)
+ */
+ public final BufferedImage filter(BufferedImage src, BufferedImage dst)
+ {
+ // TODO: The plan is to create a scanline buffer for intermediate buffers.
+ // For now we just suck it up and create intermediate buffers.
+
+ if (dst == null && spaces.length == 0)
+ throw new IllegalArgumentException();
+
+ // Make sure input isn't premultiplied by alpha
+ if (src.isAlphaPremultiplied())
+ {
+ BufferedImage tmp = createCompatibleDestImage(src, src.getColorModel());
+ copyimage(src, tmp);
+ tmp.coerceData(false);
+ src = tmp;
+ }
+
+ ColorModel scm = src.getColorModel();
+ for (int i = 0; i < spaces.length; i++)
+ {
+ ColorModel cm = scm.cloneColorModel(spaces[i]);
+ BufferedImage tmp = createCompatibleDestImage(src, cm);
+ copyimage(src, tmp);
+ src = tmp;
+ }
+
+ // Intermediate conversions leave result in src
+ if (dst == null)
+ return src;
+
+ // Apply final conversion
+ copyimage(src, dst);
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
+ */
+ public BufferedImage createCompatibleDestImage(BufferedImage src,
+ ColorModel dstCM)
+ {
+ // FIXME: set properties to those in src
+ return new BufferedImage(dstCM,
+ src.getRaster().createCompatibleWritableRaster(),
+ src.isPremultiplied,
+ null);
+ }
+
+ public final ICC_Profile[] getICC_Profiles()
+ {
+ return profiles;
+ }
+
+ /** Return the rendering hints for this op. */
+ public final RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
+ */
+ public final WritableRaster filter(Raster src, WritableRaster dest)
+ {
+ if (!rasterValid)
+ throw new IllegalArgumentException();
+
+ // Need to iterate through each color space - there must be at least 2
+ for (int i = 1; i < spaces.length - 1; i++)
+ {
+ // FIXME: this is wrong. tmp needs to have the same number of bands as
+ // spaces[i] has.
+ WritableRaster tmp = createCompatibleDestRaster(src);
+ copyraster(src, spaces[i - 1], tmp, spaces[i]);
+ src = tmp;
+ }
+
+ // FIXME: this is wrong. dst needs to have the same number of bands as
+ // spaces[i] has.
+ if (dest == null)
+ dest = createCompatibleDestRaster(src);
+ copyraster(src, spaces[spaces.length - 2],
+ dest, spaces[spaces.length - 1]);
+
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return src.createCompatibleWritableRaster();
+ }
+
+ /** Return corresponding destination point for source point.
+ *
+ * LookupOp will return the value of src unchanged.
+ * @param src The source point.
+ * @param dst The destination point.
+ * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
+ */
+ public final Point2D getPoint2D(Point2D src, Point2D dst)
+ {
+ if (dst == null) return (Point2D)src.clone();
+ dst.setLocation(src);
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
+ */
+ public final Rectangle2D getBounds2D(BufferedImage src)
+ {
+ return src.getRaster().getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public final Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ // According to Sven de Marothy, we need to copy the src into the dest
+ // using Graphics2D, in order to use the rendering hints.
+ private void copyimage(BufferedImage src, BufferedImage dst)
+ {
+ Graphics2D gg = dst.createGraphics();
+ gg.setRenderingHints(hints);
+ gg.drawImage(src, 0, 0, null);
+ gg.dispose();
+ }
+
+ private void copyraster(Raster src, ColorSpace scs, WritableRaster dst,
+ ColorSpace dcs)
+ {
+ float[] sbuf = new float[src.getNumBands()];
+
+ if (hints.get(RenderingHints.KEY_COLOR_RENDERING) ==
+ RenderingHints.VALUE_COLOR_RENDER_QUALITY)
+ {
+ // use cie for accuracy
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ dst.setPixel(x, y,
+ dcs.fromCIEXYZ(scs.toCIEXYZ(src.getPixel(x, y, sbuf))));
+ }
+ else
+ {
+ // use rgb - it's probably faster
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ dst.setPixel(x, y,
+ dcs.fromRGB(scs.toRGB(src.getPixel(x, y, sbuf))));
+ }
+ }
+
+}
diff --git a/libjava/classpath/java/awt/image/ColorModel.java b/libjava/classpath/java/awt/image/ColorModel.java
new file mode 100644
index 0000000..1ebcb98
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ColorModel.java
@@ -0,0 +1,758 @@
+/* ColorModel.java --
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import gnu.java.awt.Buffers;
+
+import java.awt.Point;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+
+/**
+ * A color model operates with colors in several formats:
+ *
+ * <ul>
+ * <li>normalized: component samples are in range [0.0, 1.0].</li>
+ *
+ * <li>color model pixel value: all the color component samples for a
+ * sigle pixel packed/encoded in a way natural for the color
+ * model.</li>
+ *
+ * <li>color model pixel int value: only makes sense if the natural
+ * encoding of a single pixel can fit in a single int value.</li>
+ *
+ * <li>array of transferType containing a single pixel: the pixel is
+ * encoded in the natural way of the color model, taking up as many
+ * array elements as needed.</li>
+ *
+ * <li>sRGB pixel int value: a pixel in sRGB color space, encoded in
+ * default 0xAARRGGBB format, assumed not alpha premultiplied.</li>
+ *
+ * <li>single [0, 255] scaled int samples from default sRGB color
+ * space. These are always assumed to be alpha non-premultiplied.</li>
+ *
+ * <li>arrays of unnormalized component samples of single pixel: these
+ * samples are scaled and multiplied according to the color model, but
+ * is otherwise not packed or encoded. Each element of the array is one
+ * separate component sample. The color model only operate on the
+ * components from one pixel at a time, but using offsets, allows
+ * manipulation of arrays that contain the components of more than one
+ * pixel.</li>
+ *
+ * </ul>
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public abstract class ColorModel implements Transparency
+{
+ protected int pixel_bits;
+ protected int transferType;
+
+ int[] bits;
+ ColorSpace cspace;
+ int transparency;
+ boolean hasAlpha;
+ boolean isAlphaPremultiplied;
+
+ static int[] nArray(int value, int times)
+ {
+ int[] array = new int[times];
+ java.util.Arrays.fill(array, value);
+ return array;
+ }
+
+ static byte[] nArray(byte value, int times)
+ {
+ byte[] array = new byte[times];
+ java.util.Arrays.fill(array, value);
+ return array;
+ }
+
+ /**
+ * Constructs the default color model. The default color model
+ * can be obtained by calling <code>getRGBdefault</code> of this
+ * class.
+ * @param bits the number of bits wide used for bit size of pixel values
+ */
+ public ColorModel(int bits)
+ {
+ this(bits * 4, // total bits, sRGB, four channels
+ nArray(bits, 4), // bits for each channel
+ ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
+ true, // has alpha
+ false, // not premultiplied
+ TRANSLUCENT,
+ Buffers.smallestAppropriateTransferType(bits * 4));
+ }
+
+ /**
+ * Constructs a ColorModel that translates pixel values to
+ * color/alpha components.
+ *
+ * @exception IllegalArgumentException If the length of the bit array is less
+ * than the number of color or alpha components in this ColorModel, or if the
+ * transparency is not a valid value, or if the sum of the number of bits in
+ * bits is less than 1 or if any of the elements in bits is less than 0.
+ */
+ protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace,
+ boolean hasAlpha, boolean isAlphaPremultiplied,
+ int transparency, int transferType)
+ {
+ int bits_sum = 0;
+ for (int i = 0; i < bits.length; i++)
+ {
+ if (bits [i] < 0)
+ throw new IllegalArgumentException ();
+
+ bits_sum |= bits [i];
+ }
+
+ if ((bits.length < cspace.getNumComponents())
+ || (bits_sum < 1))
+ throw new IllegalArgumentException ();
+
+ this.pixel_bits = pixel_bits;
+ this.bits = bits;
+ this.cspace = cspace;
+ this.hasAlpha = hasAlpha;
+ this.isAlphaPremultiplied = isAlphaPremultiplied;
+ this.transparency = transparency;
+ this.transferType = transferType;
+ }
+
+ // This is a hook for ColorConvertOp to create a colormodel with
+ // a new colorspace
+ ColorModel cloneColorModel(ColorSpace cspace)
+ {
+ Class cls = this.getClass();
+ ColorModel cm;
+ try {
+ // This constructor will exist.
+ Constructor ctor =
+ cls.getConstructor(new Class[]{int.class, int[].class,
+ ColorSpace.class, boolean.class,
+ boolean.class, int.class, int.class});
+ cm = (ColorModel)ctor.
+ newInstance(new Object[]{new Integer(pixel_bits),
+ bits, cspace, Boolean.valueOf(hasAlpha),
+ Boolean.valueOf(isAlphaPremultiplied),
+ new Integer(transparency),
+ new Integer(transferType)});
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException();
+ }
+ return cm;
+ }
+
+ public void finalize()
+ {
+ // Do nothing here.
+ }
+
+ /**
+ * Returns the default color model which in Sun's case is an instance
+ * of <code>DirectColorModel</code>.
+ */
+ public static ColorModel getRGBdefault()
+ {
+ return new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
+ }
+
+ public final boolean hasAlpha()
+ {
+ return hasAlpha;
+ }
+
+ public final boolean isAlphaPremultiplied()
+ {
+ return isAlphaPremultiplied;
+ }
+
+ /**
+ * Get get number of bits wide used for the bit size of pixel values
+ */
+ public int getPixelSize()
+ {
+ return pixel_bits;
+ }
+
+ public int getComponentSize(int componentIdx)
+ {
+ return bits[componentIdx];
+ }
+
+ public int[] getComponentSize()
+ {
+ return bits;
+ }
+
+ public int getTransparency()
+ {
+ return transparency;
+ }
+
+ public int getNumComponents()
+ {
+ return getNumColorComponents() + (hasAlpha ? 1 : 0);
+ }
+
+ public int getNumColorComponents()
+ {
+ return cspace.getNumComponents();
+ }
+
+ /**
+ * Converts pixel value to sRGB and extract red int sample scaled
+ * to range [0, 255].
+ *
+ * @param pixel pixel value that will be interpreted according to
+ * the color model, (assumed alpha premultiplied if color model says
+ * so.)
+ *
+ * @return red sample scaled to range [0, 255], from default color
+ * space sRGB, alpha non-premultiplied.
+ */
+ public abstract int getRed(int pixel);
+
+ /**
+ * Converts pixel value to sRGB and extract green int sample
+ * scaled to range [0, 255].
+ *
+ * @see #getRed(int)
+ */
+ public abstract int getGreen(int pixel);
+
+ /**
+ * Converts pixel value to sRGB and extract blue int sample
+ * scaled to range [0, 255].
+ *
+ * @see #getRed(int)
+ */
+ public abstract int getBlue(int pixel);
+
+ /**
+ * Extract alpha int sample from pixel value, scaled to [0, 255].
+ *
+ * @param pixel pixel value that will be interpreted according to
+ * the color model.
+ *
+ * @return alpha sample, scaled to range [0, 255].
+ */
+ public abstract int getAlpha(int pixel);
+
+ /**
+ * Converts a pixel int value of the color space of the color
+ * model to a sRGB pixel int value.
+ *
+ * This method is typically overriden in subclasses to provide a
+ * more efficient implementation.
+ *
+ * @param pixel pixel value that will be interpreted according to
+ * the color model.
+ *
+ * @return a pixel in sRGB color space, encoded in default
+ * 0xAARRGGBB format. */
+ public int getRGB(int pixel)
+ {
+ return
+ ((getAlpha(pixel) & 0xff) << 24) |
+ (( getRed(pixel) & 0xff) << 16) |
+ ((getGreen(pixel) & 0xff) << 8) |
+ (( getBlue(pixel) & 0xff) << 0);
+ }
+
+
+ /**
+ * In this color model we know that the whole pixel value will
+ * always be contained within the first element of the pixel
+ * array.
+ */
+ final int getPixelFromArray(Object inData) {
+ DataBuffer data =
+ Buffers.createBufferFromData(transferType, inData, 1);
+ Object da = Buffers.getData(data);
+
+ return data.getElem(0);
+ }
+
+ /**
+ * Converts pixel in the given array to sRGB and extract blue int
+ * sample scaled to range [0-255].
+ *
+ * This method is typically overriden in subclasses to provide a
+ * more efficient implementation.
+ *
+ * @param inData array of transferType containing a single pixel. The
+ * pixel should be encoded in the natural way of the color model.
+ */
+ public int getRed(Object inData)
+ {
+ return getRed(getPixelFromArray(inData));
+ }
+
+ /**
+ * @see #getRed(Object)
+ */
+ public int getGreen(Object inData)
+ {
+ return getGreen(getPixelFromArray(inData));
+ }
+
+ /**
+ * @see #getRed(Object)
+ */
+ public int getBlue(Object inData) {
+ return getBlue(getPixelFromArray(inData));
+ }
+
+ /**
+ * @see #getRed(Object)
+ */
+ public int getAlpha(Object inData) {
+ return getAlpha(getPixelFromArray(inData));
+ }
+
+ /**
+ * Converts a pixel in the given array of the color space of the
+ * color model to an sRGB pixel int value.
+ *
+ * <p>This method performs the inverse function of
+ * <code>getDataElements(int rgb, Object pixel)</code>.
+ * I.e. <code>(rgb == cm.getRGB(cm.getDataElements(rgb,
+ * null)))</code>.
+ *
+ * @param inData array of transferType containing a single pixel. The
+ * pixel should be encoded in the natural way of the color model.
+ *
+ * @return a pixel in sRGB color space, encoded in default
+ * 0xAARRGGBB format.
+ *
+ * @see #getDataElements(int, Object)
+ */
+ public int getRGB(Object inData)
+ {
+ return
+ ((getAlpha(inData) & 0xff) << 24) |
+ (( getRed(inData) & 0xff) << 16) |
+ ((getGreen(inData) & 0xff) << 8) |
+ (( getBlue(inData) & 0xff) << 0);
+ }
+
+ /**
+ * Converts an sRGB pixel int value to an array containing a
+ * single pixel of the color space of the color model.
+ *
+ * <p>This method performs the inverse function of
+ * <code>getRGB(Object inData)</code>.
+ *
+ * Outline of conversion process:
+ *
+ * <ol>
+ *
+ * <li>Convert rgb to normalized [0.0, 1.0] sRGB values.</li>
+ *
+ * <li>Convert to color space components using fromRGB in
+ * ColorSpace.</li>
+ *
+ * <li>If color model has alpha and should be premultiplied,
+ * multiply color space components with alpha value</li>
+ *
+ * <li>Scale the components to the correct number of bits.</li>
+ *
+ * <li>Arrange the components in the output array</li>
+ *
+ * </ol>
+ *
+ * @param rgb The color to be converted to dataElements. A pixel
+ * in sRGB color space, encoded in default 0xAARRGGBB format,
+ * assumed not alpha premultiplied.
+ *
+ * @param pixel to avoid needless creation of arrays, an array to
+ * use to return the pixel can be given. If null, a suitable array
+ * will be created.
+ *
+ * @return An array of transferType values representing the color,
+ * in the color model format. The color model defines whether the
+ *
+ * @see #getRGB(Object)
+ */
+ public Object getDataElements(int rgb, Object pixel)
+ {
+ // subclasses has to implement this method.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Fills an array with the unnormalized component samples from a
+ * pixel value. I.e. decompose the pixel, but not perform any
+ * color conversion.
+ *
+ * This method is typically overriden in subclasses to provide a
+ * more efficient implementation.
+ *
+ * @param pixel pixel value encoded according to the color model.
+ *
+ * @return arrays of unnormalized component samples of single
+ * pixel. The scale and multiplication state of the samples are
+ * according to the color model. Each component sample is stored
+ * as a separate element in the array.
+ */
+ public int[] getComponents(int pixel, int[] components, int offset)
+ {
+ // subclasses has to implement this method.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Fills an array with the unnormalized component samples from an
+ * array of transferType containing a single pixel. I.e. decompose
+ * the pixel, but not perform any color conversion.
+ *
+ * This method is typically overriden in subclasses to provide a
+ * more efficient implementation.
+ *
+ * @param array of transferType containing a single pixel. The
+ * pixel should be encoded in the natural way of the color model.
+ *
+ * @return arrays of unnormalized component samples of single
+ * pixel. The scale and multiplication state of the samples are
+ * according to the color model. Each component sample is stored
+ * as a separate element in the array.
+ */
+ public int[] getComponents(Object pixel, int[] components, int offset)
+ {
+ // subclasses has to implement this method.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Convert normalized components to unnormalized components.
+ */
+ public int[] getUnnormalizedComponents(float[] normComponents,
+ int normOffset,
+ int[] components,
+ int offset)
+ {
+ int numComponents = getNumComponents();
+ if (components == null)
+ {
+ components = new int[offset + numComponents];
+ }
+
+ for (int i=0; i<numComponents; i++)
+ {
+ float in = normComponents[normOffset++];
+ int out = (int) (in * ((1<<getComponentSize(i)) - 1));
+ components[offset++] = out;
+ }
+ return components;
+ }
+
+ /**
+ * Convert unnormalized components to normalized components.
+ */
+ public float[] getNormalizedComponents(int[] components,
+ int offset,
+ float[] normComponents,
+ int normOffset)
+ {
+ int numComponents = getNumComponents();
+ if (normComponents == null)
+ {
+ normComponents = new float[normOffset + numComponents];
+ }
+
+ for (int i=0; i<numComponents; i++)
+ {
+ float in = components[offset++];
+ float out = in / ((1<<getComponentSize(i)) - 1);
+ normComponents[normOffset++] = out;
+ }
+ return normComponents;
+ }
+
+ /**
+ * Convert unnormalized components to normalized components.
+ *
+ * @since 1.4
+ */
+ public float[] getNormalizedComponents (Object pixel,
+ float[] normComponents,
+ int normOffset)
+ {
+ // subclasses has to implement this method.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Converts the unnormalized component samples from an array to a
+ * pixel value. I.e. composes the pixel from component samples, but
+ * does not perform any color conversion or scaling of the samples.
+ *
+ * This method performs the inverse function of
+ * <code>getComponents(int pixel, int[] components,
+ * int offset)</code>. I.e.
+ *
+ * <code>(pixel == cm.getDataElement(cm.getComponents(pixel, null,
+ * 0), 0))</code>.
+ *
+ * This method is overriden in subclasses since this abstract class throws
+ * UnsupportedOperationException().
+ *
+ * @param components Array of unnormalized component samples of single
+ * pixel. The scale and multiplication state of the samples are according
+ * to the color model. Each component sample is stored as a separate element
+ * in the array.
+ * @param offset Position of the first value of the pixel in components.
+ *
+ * @return pixel value encoded according to the color model.
+ */
+ public int getDataElement(int[] components, int offset)
+ {
+ // subclasses have to implement this method.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Converts the normalized component samples from an array to a pixel
+ * value. I.e. composes the pixel from component samples, but does not
+ * perform any color conversion or scaling of the samples.
+ *
+ * This method is typically overriden in subclasses to provide a
+ * more efficient implementation. The method provided by this abstract
+ * class converts the components to unnormalized form and returns
+ * getDataElement(int[], int).
+ *
+ * @param components Array of normalized component samples of single pixel.
+ * The scale and multiplication state of the samples are according to the
+ * color model. Each component sample is stored as a separate element in the
+ * array.
+ * @param offset Position of the first value of the pixel in components.
+ *
+ * @return pixel value encoded according to the color model.
+ * @since 1.4
+ */
+ public int getDataElement (float[] components, int offset)
+ {
+ return
+ getDataElement(getUnnormalizedComponents(components, offset, null, 0),
+ 0);
+ }
+
+ public Object getDataElements(int[] components, int offset, Object obj)
+ {
+ // subclasses have to implement this method.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Converts the normalized component samples from an array to an array of
+ * TransferType values. I.e. composes the pixel from component samples, but
+ * does not perform any color conversion or scaling of the samples.
+ *
+ * If obj is null, a new array of TransferType is allocated and returned.
+ * Otherwise the results are stored in obj and obj is returned. If obj is
+ * not long enough, ArrayIndexOutOfBounds is thrown. If obj is not an array
+ * of primitives, ClassCastException is thrown.
+ *
+ * This method is typically overriden in subclasses to provide a
+ * more efficient implementation. The method provided by this abstract
+ * class converts the components to unnormalized form and returns
+ * getDataElement(int[], int, Object).
+ *
+ * @param components Array of normalized component samples of single pixel.
+ * The scale and multiplication state of the samples are according to the
+ * color model. Each component sample is stored as a separate element in the
+ * array.
+ * @param offset Position of the first value of the pixel in components.
+ * @param obj Array of TransferType or null.
+ *
+ * @return pixel value encoded according to the color model.
+ * @throws ArrayIndexOutOfBounds
+ * @throws ClassCastException
+ * @since 1.4
+ */
+ public Object getDataElements(float[] components, int offset, Object obj)
+ {
+ return
+ getDataElements(getUnnormalizedComponents(components, offset, null, 0),
+ 0, obj);
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof ColorModel)) return false;
+
+ ColorModel o = (ColorModel) obj;
+ return
+ (pixel_bits == o.pixel_bits) &&
+ (transferType == o.transferType) &&
+ (transparency == o.transparency) &&
+ (hasAlpha == o.hasAlpha) &&
+ (isAlphaPremultiplied == o.isAlphaPremultiplied) &&
+ Arrays.equals(bits, o.bits) &&
+ (cspace.equals(o.cspace));
+ }
+
+ public final ColorSpace getColorSpace()
+ {
+ return cspace;
+ }
+
+ // Typically overridden
+ public ColorModel coerceData(WritableRaster raster,
+ boolean isAlphaPremultiplied)
+ {
+ if (this.isAlphaPremultiplied == isAlphaPremultiplied)
+ return this;
+
+ int w = raster.getWidth();
+ int h = raster.getHeight();
+ int x = raster.getMinX();
+ int y = raster.getMinY();
+ int size = w*h;
+ int numColors = getNumColorComponents();
+ int numComponents = getNumComponents();
+ int alphaScale = (1<<getComponentSize(numColors)) - 1;
+ double[] pixels = raster.getPixels(x, y, w, h, (double[]) null);
+
+ for (int i=0; i<size; i++)
+ {
+ double alpha = pixels[i*numComponents+numColors]*alphaScale;
+ for (int c=0; c<numColors; c++)
+ {
+ int offset = i*numComponents+c;
+ if (isAlphaPremultiplied)
+ pixels[offset] = pixels[offset]/alpha;
+ else
+ pixels[offset] = pixels[offset]*alpha;
+ }
+ }
+
+ raster.setPixels(0, 0, w, h, pixels);
+
+ // FIXME: what can we return?
+ return null;
+ }
+
+ /**
+ * Checks if the given raster has a compatible data-layout (SampleModel).
+ * @param raster The Raster to test.
+ * @return true if raster is compatible.
+ */
+ public boolean isCompatibleRaster(Raster raster)
+ {
+ SampleModel sampleModel = raster.getSampleModel();
+ return isCompatibleSampleModel(sampleModel);
+ }
+
+ // Typically overridden
+ public WritableRaster createCompatibleWritableRaster(int w, int h)
+ {
+ return new WritableRaster(createCompatibleSampleModel(w, h),
+ new Point(0, 0));
+ }
+
+ // Typically overridden
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ // Typically overridden
+ public boolean isCompatibleSampleModel(SampleModel sm)
+ {
+ return sm.getTransferType() == transferType;
+ }
+
+ public final int getTransferType ()
+ {
+ return transferType;
+ }
+
+ /**
+ * Subclasses must override this method if it is possible for the
+ * color model to have an alpha channel.
+ *
+ * @return null, as per JDK 1.3 doc. Subclasses will only return
+ * null if no alpha raster exists.
+ */
+ public WritableRaster getAlphaRaster(WritableRaster raster)
+ {
+ return null;
+
+ /* It is a mystery to me why we couldn't use the following code...
+
+
+ if (!hasAlpha()) return null;
+
+ SampleModel sm = raster.getSampleModel();
+ int[] alphaBand = { sm.getNumBands() - 1 };
+ SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
+ DataBuffer buffer = raster.getDataBuffer();
+ Point origin = new Point(0, 0);
+ return Raster.createWritableRaster(alphaModel, buffer, origin);
+
+
+ ...here, and avoided overriding the method in subclasses,
+ but the Sun docs state that this method always will return
+ null, and that overriding is required. Oh, well.
+ */
+ }
+
+ String stringParam()
+ {
+ return "pixel_bits=" + pixel_bits +
+ ", cspace=" + cspace +
+ ", transferType=" + transferType +
+ ", transparency=" + transparency +
+ ", hasAlpha=" + hasAlpha +
+ ", isAlphaPremultiplied=" + isAlphaPremultiplied;
+ }
+
+ public String toString()
+ {
+ return getClass().getName() + "[" + stringParam() + "]";
+ }
+}
diff --git a/libjava/classpath/java/awt/image/ComponentColorModel.java b/libjava/classpath/java/awt/image/ComponentColorModel.java
new file mode 100644
index 0000000..f56688f
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ComponentColorModel.java
@@ -0,0 +1,391 @@
+/* ComponentColorModel.java --
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import gnu.java.awt.Buffers;
+
+import java.awt.Point;
+import java.awt.color.ColorSpace;
+
+public class ComponentColorModel extends ColorModel
+{
+ private static int sum(int[] values)
+ {
+ int sum = 0;
+ for (int i=0; i<values.length; i++)
+ sum += values[i];
+ return sum;
+ }
+
+ public ComponentColorModel(ColorSpace colorSpace, int[] bits,
+ boolean hasAlpha,
+ boolean isAlphaPremultiplied,
+ int transparency, int transferType)
+ {
+ super(sum(bits), bits, colorSpace, hasAlpha, isAlphaPremultiplied,
+ transparency, transferType);
+ }
+
+ /**
+ * Construct a new ComponentColorModel.
+ *
+ * This constructor makes all bits of each sample significant, so for a
+ * transferType of DataBuffer.BYTE, the bits per sample is 8, etc. If
+ * both hasAlpha and isAlphaPremultiplied are true, color samples are
+ * assumed to be premultiplied by the alpha component. Transparency may be
+ * one of OPAQUE, BITMASK, or TRANSLUCENT.
+ *
+ * @param colorSpace The colorspace for this color model.
+ * @param hasAlpha True if there is an alpha component.
+ * @param isAlphaPremultiplied True if colors are already multiplied by
+ * alpha.
+ * @param transparency The type of alpha values.
+ * @param transferType Data type of pixel sample values.
+ * @since 1.4
+ */
+ public ComponentColorModel(ColorSpace colorSpace,
+ boolean hasAlpha,
+ boolean isAlphaPremultiplied,
+ int transparency, int transferType)
+ {
+ this(colorSpace, null, hasAlpha, isAlphaPremultiplied,
+ transparency, transferType);
+ }
+
+ public int getRed(int pixel)
+ {
+ if (getNumComponents()>1) throw new IllegalArgumentException();
+ return (int) getRGBFloat(pixel)[0];
+ }
+
+ public int getGreen(int pixel)
+ {
+ if (getNumComponents()>1) throw new IllegalArgumentException();
+ return (int) getRGBFloat(pixel)[0];
+ }
+
+ public int getBlue(int pixel)
+ {
+ if (getNumComponents()>1) throw new IllegalArgumentException();
+ return (int) getRGBFloat(pixel)[0];
+ }
+
+ public int getAlpha(int pixel)
+ {
+ if (getNumComponents()>1) throw new IllegalArgumentException();
+ int shift = 8 - getComponentSize(getNumColorComponents());
+ if (shift >= 0) return pixel << shift;
+ return pixel >> (-shift);
+ }
+
+ public int getRGB(int pixel)
+ {
+ float[] rgb = getRGBFloat(pixel);
+ int ret = getRGB(rgb);
+ if (hasAlpha()) ret |= getAlpha(pixel) << 24;
+ return ret;
+ }
+
+
+ /* Note, it's OK to pass a to large array to toRGB(). Extra
+ elements are ignored. */
+
+ private float[] getRGBFloat(int pixel)
+ {
+ float[] data = { pixel };
+ return cspace.toRGB(data);
+ }
+
+ private float[] getRGBFloat(Object inData)
+ {
+ DataBuffer buffer =
+ Buffers.createBufferFromData(transferType, inData,
+ getNumComponents());
+ int colors = getNumColorComponents();
+ float[] data = new float[colors];
+
+ // FIXME: unpremultiply data that is premultiplied
+ for (int i=0; i<colors; i++)
+ {
+ float maxValue = (1<<getComponentSize(i))-1;
+ data[i] = buffer.getElemFloat(i)/maxValue;
+ }
+ float[] rgb = cspace.toRGB(data);
+ return rgb;
+ }
+
+ public int getRed(Object inData)
+ {
+ return (int) getRGBFloat(inData)[0]*255;
+ }
+
+ public int getGreen(Object inData)
+ {
+ return (int) getRGBFloat(inData)[1]*255;
+ }
+
+ public int getBlue(Object inData)
+ {
+ return (int) getRGBFloat(inData)[2]*255;
+ }
+
+ public int getAlpha(Object inData)
+ {
+ DataBuffer buffer =
+ Buffers.createBufferFromData(transferType, inData,
+ getNumComponents());
+ int shift = 8 - getComponentSize(getNumColorComponents());
+ int alpha = buffer.getElem(getNumColorComponents());
+ if (shift >= 0) return alpha << shift;
+ return alpha >> (-shift);
+ }
+
+ private int getRGB(float[] rgb)
+ {
+ /* NOTE: We could cast to byte instead of int here. This would
+ avoid bits spilling over from one bit field to
+ another. But, if we assume that floats are in the [0.0,
+ 1.0] range, this will never happen anyway. */
+
+ /* Remember to multiply BEFORE casting to int, otherwise, decimal
+ point data will be lost. */
+ int ret =
+ (((int) (rgb[0]*255F)) << 16) |
+ (((int) (rgb[1]*255F)) << 8) |
+ (((int) (rgb[2]*255F)) << 0);
+ return ret;
+ }
+
+ /**
+ * @param inData pixel data of transferType, as returned by the
+ * getDataElements method in SampleModel.
+ */
+ public int getRGB(Object inData)
+ {
+ float[] rgb = getRGBFloat(inData);
+ int ret = getRGB(rgb);
+ if (hasAlpha()) ret |= getAlpha(inData) << 24;
+ return ret;
+ }
+
+ public Object getDataElements(int rgb, Object pixel)
+ {
+ // Convert rgb to [0.0, 1.0] sRGB values.
+ float[] rgbFloats = {
+ ((rgb >> 16)&0xff)/255.0F,
+ ((rgb >> 8)&0xff)/255.0F,
+ ((rgb >> 0)&0xff)/255.0F
+ };
+
+ // Convert from rgb to color space components.
+ float[] data = cspace.fromRGB(rgbFloats);
+ DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
+ getNumComponents());
+ int numColors = getNumColorComponents();
+
+ if (hasAlpha())
+ {
+ float alpha = ((rgb >> 24)&0xff)/255.0F;
+
+ /* If color model has alpha and should be premultiplied, multiply
+ color space components with alpha value. */
+ if (isAlphaPremultiplied()) {
+ for (int i=0; i<numColors; i++)
+ data[i] *= alpha;
+ }
+ // Scale the alpha sample to the correct number of bits.
+ alpha *= (1<<(bits[numColors]-1));
+ // Arrange the alpha sample in the output array.
+ buffer.setElemFloat(numColors, alpha);
+ }
+ for (int i=0; i<numColors; i++)
+ {
+ // Scale the color samples to the correct number of bits.
+ float value = data[i]*(1<<(bits[i]-1));
+ // Arrange the color samples in the output array.
+ buffer.setElemFloat(i, value);
+ }
+ return Buffers.getData(buffer);
+ }
+
+ public int[] getComponents(int pixel, int[] components, int offset)
+ {
+ if (getNumComponents()>1) throw new IllegalArgumentException();
+ if (components == null)
+ components = new int[getNumComponents() + offset];
+ components[offset] = pixel;
+ return components;
+ }
+
+ public int[] getComponents(Object pixel, int[] components, int offset)
+ {
+ DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
+ getNumComponents());
+ int numComponents = getNumComponents();
+
+ if (components == null)
+ components = new int[numComponents + offset];
+
+ for (int i=0; i<numComponents; i++)
+ components[offset++] = buffer.getElem(i);
+
+ return components;
+ }
+
+ public int getDataElement(int[] components, int offset)
+ {
+ if (getNumComponents()>1) throw new IllegalArgumentException();
+ return components[offset];
+ }
+
+ public Object getDataElements(int[] components, int offset, Object obj)
+ {
+ DataBuffer buffer = Buffers.createBuffer(transferType, obj,
+ getNumComponents());
+ int numComponents = getNumComponents();
+
+ for (int i=0; i<numComponents; i++)
+ buffer.setElem(i, components[offset++]);
+
+ return Buffers.getData(buffer);
+ }
+
+ public ColorModel coerceData(WritableRaster raster,
+ boolean isAlphaPremultiplied) {
+ if (this.isAlphaPremultiplied == isAlphaPremultiplied)
+ return this;
+
+ /* TODO: provide better implementation based on the
+ assumptions we can make due to the specific type of the
+ color model. */
+ super.coerceData(raster, isAlphaPremultiplied);
+
+ return new ComponentColorModel(cspace, bits, hasAlpha(),
+ isAlphaPremultiplied, // argument
+ transparency, transferType);
+ }
+
+ public boolean isCompatibleRaster(Raster raster)
+ {
+ return super.isCompatibleRaster(raster);
+ // FIXME: Should we test something more here? (Why override?)
+ }
+
+ public WritableRaster createCompatibleWritableRaster(int w, int h)
+ {
+ SampleModel sm = createCompatibleSampleModel(w, h);
+ Point origin = new Point(0, 0);
+ return Raster.createWritableRaster(sm, origin);
+ }
+
+
+ /**
+ * Creates a <code>SampleModel</code> whose arrangement of pixel
+ * data is compatible to this <code>ColorModel</code>.
+ *
+ * @param w the number of pixels in the horizontal direction.
+ * @param h the number of pixels in the vertical direction.
+ */
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ int pixelStride, scanlineStride;
+ int[] bandOffsets;
+
+ pixelStride = getNumComponents();
+ scanlineStride = pixelStride * w;
+
+ /* We might be able to re-use the same bandOffsets array among
+ * multiple calls to this method. However, this optimization does
+ * not seem worthwile because setting up descriptive data
+ * structures (such as SampleModels) is neglectible in comparision
+ * to shuffling around masses of pixel data.
+ */
+ bandOffsets = new int[pixelStride];
+ for (int i = 0; i < pixelStride; i++)
+ bandOffsets[i] = i;
+
+ /* FIXME: Think about whether it would make sense to return the
+ * possibly more efficient PixelInterleavedSampleModel for other
+ * transferTypes as well. It seems unlikely that this would break
+ * any user applications, so the Mauve tests on this method
+ * might be too restrictive.
+ */
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ case DataBuffer.TYPE_USHORT:
+ return new PixelInterleavedSampleModel(transferType, w, h,
+ pixelStride,
+ scanlineStride,
+ bandOffsets);
+
+ default:
+ return new ComponentSampleModel(transferType, w, h,
+ pixelStride,
+ scanlineStride,
+ bandOffsets);
+ }
+ }
+
+
+ public boolean isCompatibleSampleModel(SampleModel sm)
+ {
+ return
+ (sm instanceof ComponentSampleModel) &&
+ super.isCompatibleSampleModel(sm);
+ }
+
+ public WritableRaster getAlphaRaster(WritableRaster raster)
+ {
+ if (!hasAlpha()) return null;
+
+ SampleModel sm = raster.getSampleModel();
+ int[] alphaBand = { sm.getNumBands() - 1 };
+ SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
+ DataBuffer buffer = raster.getDataBuffer();
+ Point origin = new Point(0, 0);
+ return Raster.createWritableRaster(alphaModel, buffer, origin);
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof ComponentColorModel)) return false;
+ return super.equals(obj);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/ComponentSampleModel.java b/libjava/classpath/java/awt/image/ComponentSampleModel.java
new file mode 100644
index 0000000..953f63c
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ComponentSampleModel.java
@@ -0,0 +1,544 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+import gnu.java.awt.Buffers;
+
+/* FIXME: This class does not yet support data type TYPE_SHORT */
+
+/**
+ * ComponentSampleModel supports a flexible organization of pixel samples in
+ * memory, permitting pixel samples to be interleaved by band, by scanline,
+ * and by pixel.
+ *
+ * A DataBuffer for this sample model has K banks of data. Pixels have N
+ * samples, so there are N bands in the DataBuffer. Each band is completely
+ * contained in one bank of data, but a bank may contain more than one band.
+ * Each pixel sample is stored in a single data element.
+ *
+ * Within a bank, each band begins at an offset stored in bandOffsets. The
+ * banks containing the band is given by bankIndices. Within the bank, there
+ * are three dimensions - band, pixel, and scanline. The dimension ordering
+ * is controlled by bandOffset, pixelStride, and scanlineStride, which means
+ * that any combination of interleavings is supported.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public class ComponentSampleModel extends SampleModel
+{
+ protected int[] bandOffsets;
+ protected int[] bankIndices;
+
+ // FIXME: Should we really shadow the numBands in the superclass?
+ //protected int numBands;
+
+ /** Used when creating data buffers. */
+ protected int numBanks;
+
+ protected int scanlineStride;
+
+ protected int pixelStride;
+
+ private boolean tightPixelPacking = false;
+
+ public ComponentSampleModel(int dataType,
+ int w, int h,
+ int pixelStride,
+ int scanlineStride,
+ int[] bandOffsets)
+ {
+ this(dataType, w, h, pixelStride, scanlineStride,
+ new int[bandOffsets.length], bandOffsets);
+ }
+
+ public ComponentSampleModel(int dataType,
+ int w, int h,
+ int pixelStride,
+ int scanlineStride,
+ int[] bankIndices,
+ int[] bandOffsets)
+ {
+ super(dataType, w, h, bandOffsets.length);
+ if ((pixelStride<0) || (scanlineStride<0) ||
+ (bandOffsets.length<1) ||
+ (bandOffsets.length != bankIndices.length))
+ throw new IllegalArgumentException();
+
+ this.bandOffsets = bandOffsets;
+ this.bankIndices = bankIndices;
+
+ this.numBanks = 0;
+ for (int b=0; b<bankIndices.length; b++)
+ this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
+
+ this.scanlineStride = scanlineStride;
+ this.pixelStride = pixelStride;
+
+ // See if we can use some speedups
+
+ /* FIXME: May these checks should be reserved for the
+ PixelInterleavedSampleModel? */
+
+ if (pixelStride == numBands)
+ {
+ tightPixelPacking = true;
+ for (int b=0; b<numBands; b++) {
+ if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
+ {
+ tightPixelPacking = false;
+ break;
+ }
+ }
+ }
+ }
+
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ return new ComponentSampleModel(dataType, w, h, pixelStride,
+ scanlineStride, bankIndices,
+ bandOffsets);
+ }
+
+ public SampleModel createSubsetSampleModel(int[] bands)
+ {
+ int numBands = bands.length;
+
+ int[] bankIndices = new int[numBands];
+ int[] bandOffsets = new int[numBands];
+ for (int b=0; b<numBands; b++)
+ {
+ bankIndices[b] = this.bankIndices[bands[b]];
+ bandOffsets[b] = this.bandOffsets[bands[b]];
+ }
+
+ return new ComponentSampleModel(dataType, width, height, pixelStride,
+ scanlineStride, bankIndices,
+ bandOffsets);
+ }
+
+ public DataBuffer createDataBuffer()
+ {
+ // Maybe this value should be precalculated in the constructor?
+ int highestOffset = 0;
+ for (int b=0; b<numBands; b++)
+ {
+ highestOffset = Math.max(highestOffset, bandOffsets[b]);
+ }
+ int size = pixelStride*(width-1) + scanlineStride*(height-1) +
+ highestOffset + 1;
+
+ return Buffers.createBuffer(getDataType(), size, numBanks);
+ }
+
+ public int getOffset(int x, int y)
+ {
+ return getOffset(x, y, 0);
+ }
+
+ public int getOffset(int x, int y, int b)
+ {
+ return bandOffsets[b] + pixelStride*x + scanlineStride*y;
+ }
+
+ public final int[] getSampleSize()
+ {
+ int size = DataBuffer.getDataTypeSize(getDataType());
+ int[] sizes = new int[numBands];
+
+ java.util.Arrays.fill(sizes, size);
+ return sizes;
+ }
+
+ public final int getSampleSize(int band)
+ {
+ return DataBuffer.getDataTypeSize(getDataType());
+ }
+
+ public final int[] getBankIndices()
+ {
+ return bankIndices;
+ }
+
+ public final int[] getBandOffsets()
+ {
+ return bandOffsets;
+ }
+
+ public final int getScanlineStride()
+ {
+ return scanlineStride;
+ }
+
+ public final int getPixelStride()
+ {
+ return pixelStride;
+ }
+
+ public final int getNumDataElements()
+ {
+ return numBands;
+ }
+
+ public Object getDataElements(int x, int y, Object obj, DataBuffer data)
+ {
+ int xyOffset = pixelStride*x + scanlineStride*y;
+
+ int[] totalBandDataOffsets = new int[numBands];
+
+ /* Notice that band and bank offsets are different. Band offsets
+ are managed by the sample model, and bank offsets are managed
+ by the data buffer. Both must be accounted for. */
+
+ /* FIXME: For single pixels, it is probably easier to simple
+ call getElem instead of calculating the bank offset ourself.
+
+ On the other hand, then we need to push the value through
+ the int type returned by the getElem method. */
+
+ int[] bankOffsets = data.getOffsets();
+
+ for (int b=0; b<numBands; b++)
+ {
+ totalBandDataOffsets[b] =
+ bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
+ }
+
+ try
+ {
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ DataBufferByte inByte = (DataBufferByte) data;
+ byte[] outByte = (byte[]) obj;
+ if (outByte == null) outByte = new byte[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outByte[b] = inByte.getData(bankIndices[b])[dOffset];
+ }
+ return outByte;
+
+ case DataBuffer.TYPE_USHORT:
+ DataBufferUShort inUShort = (DataBufferUShort) data;
+ short[] outUShort = (short[]) obj;
+ if (outUShort == null) outUShort = new short[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
+ }
+ return outUShort;
+
+ case DataBuffer.TYPE_SHORT:
+ DataBufferShort inShort = (DataBufferShort) data;
+ short[] outShort = (short[]) obj;
+ if (outShort == null) outShort = new short[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outShort[b] = inShort.getData(bankIndices[b])[dOffset];
+ }
+ return outShort;
+
+ case DataBuffer.TYPE_INT:
+ DataBufferInt inInt = (DataBufferInt) data;
+ int[] outInt = (int[]) obj;
+ if (outInt == null) outInt = new int[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outInt[b] = inInt.getData(bankIndices[b])[dOffset];
+ }
+ return outInt;
+
+ case DataBuffer.TYPE_FLOAT:
+ DataBufferFloat inFloat = (DataBufferFloat) data;
+ float[] outFloat = (float[]) obj;
+ if (outFloat == null) outFloat = new float[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outFloat[b] = inFloat.getData(bankIndices[b])[dOffset];
+ }
+ return outFloat;
+
+ case DataBuffer.TYPE_DOUBLE:
+ DataBufferDouble inDouble = (DataBufferDouble) data;
+ double[] outDouble = (double[]) obj;
+ if (outDouble == null) outDouble = new double[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outDouble[b] = inDouble.getData(bankIndices[b])[dOffset];
+ }
+ return outDouble;
+
+ default:
+ throw new IllegalStateException("unknown transfer type " +
+ getTransferType());
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException aioobe)
+ {
+ String msg = "While reading data elements, " +
+ "x=" + x + ", y=" + y +", " + ", xyOffset=" + xyOffset +
+ ", data.getSize()=" + data.getSize() + ": " + aioobe;
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+ }
+
+ public Object getDataElements(int x, int y, int w, int h, Object obj,
+ DataBuffer data)
+ {
+ if (!tightPixelPacking)
+ {
+ return super.getDataElements(x, y, w, h, obj, data);
+ }
+
+ // using get speedup
+
+ // We can copy whole rows
+ int rowSize = w*numBands;
+ int dataSize = rowSize*h;
+
+ DataBuffer transferBuffer =
+ Buffers.createBuffer(getTransferType(), obj, dataSize);
+ obj = Buffers.getData(transferBuffer);
+
+ int inOffset =
+ pixelStride*x +
+ scanlineStride*y +
+ data.getOffset(); // Assumes only one band is used
+
+ /* We don't add band offsets since we assume that bands have
+ offsets 0, 1, 2, ... */
+
+ // See if we can copy everything in one go
+ if (scanlineStride == rowSize)
+ {
+ // Collapse scan lines:
+ rowSize *= h;
+ // We ignore scanlineStride since it won't be of any use
+ h = 1;
+ }
+
+ int outOffset = 0;
+ Object inArray = Buffers.getData(data);
+ for (int yd = 0; yd<h; yd++)
+ {
+ System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
+ inOffset += scanlineStride;
+ outOffset += rowSize;
+ }
+ return obj;
+ }
+
+ public void setDataElements(int x, int y, int w, int h,
+ Object obj, DataBuffer data)
+ {
+ if (!tightPixelPacking)
+ {
+ super.setDataElements(x, y, w, h, obj, data);
+ return;
+ }
+
+ // using set speedup, we can copy whole rows
+ int rowSize = w*numBands;
+ int dataSize = rowSize*h;
+
+ DataBuffer transferBuffer =
+ Buffers.createBufferFromData(getTransferType(), obj, dataSize);
+
+ int[] bankOffsets = data.getOffsets();
+
+ int outOffset =
+ pixelStride*x +
+ scanlineStride*y +
+ bankOffsets[0]; // same assuptions as in get...
+
+ // See if we can copy everything in one go
+ if (scanlineStride == rowSize)
+ {
+ // Collapse scan lines:
+ rowSize *= h;
+ h = 1;
+ }
+
+ int inOffset = 0;
+ Object outArray = Buffers.getData(data);
+ for (int yd = 0; yd<h; yd++)
+ {
+ System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
+ outOffset += scanlineStride;
+ inOffset += rowSize;
+ }
+ }
+
+ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ int offset = pixelStride*x + scanlineStride*y;
+ if (iArray == null) iArray = new int[numBands];
+ for (int b=0; b<numBands; b++)
+ {
+ iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
+ }
+ return iArray;
+ }
+
+ public int[] getPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int offset = pixelStride*x + scanlineStride*y;
+ if (iArray == null) iArray = new int[numBands*w*h];
+ int outOffset = 0;
+ for (y=0; y<h; y++)
+ {
+ int lineOffset = offset;
+ for (x=0; x<w; x++)
+ {
+ for (int b=0; b<numBands; b++)
+ {
+ iArray[outOffset++] =
+ data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
+ }
+ lineOffset += pixelStride;
+ }
+ offset += scanlineStride;
+ }
+ return iArray;
+ }
+
+ public int getSample(int x, int y, int b, DataBuffer data)
+ {
+ return data.getElem(bankIndices[b], getOffset(x, y, b));
+ }
+
+ public void setDataElements(int x, int y, Object obj, DataBuffer data)
+ {
+ int offset = pixelStride*x + scanlineStride*y;
+ int[] totalBandDataOffsets = new int[numBands];
+ int[] bankOffsets = data.getOffsets();
+ for (int b=0; b<numBands; b++)
+ totalBandDataOffsets[b] =
+ bandOffsets[b]+bankOffsets[bankIndices[b]] + offset;
+
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ DataBufferByte out = (DataBufferByte) data;
+ byte[] in = (byte[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ DataBufferUShort out = (DataBufferUShort) data;
+ short[] in = (short[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
+ case DataBuffer.TYPE_SHORT:
+ {
+ DataBufferShort out = (DataBufferShort) data;
+ short[] in = (short[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ DataBufferInt out = (DataBufferInt) data;
+ int[] in = (int[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
+ case DataBuffer.TYPE_FLOAT:
+ {
+ DataBufferFloat out = (DataBufferFloat) data;
+ float[] in = (float[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
+ case DataBuffer.TYPE_DOUBLE:
+ {
+ DataBufferDouble out = (DataBufferDouble) data;
+ double[] in = (double[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
+ default:
+ throw new UnsupportedOperationException("transfer type not " +
+ "implemented");
+ }
+ }
+
+ public void setPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ int offset = pixelStride*x + scanlineStride*y;
+ for (int b=0; b<numBands; b++)
+ data.setElem(bankIndices[b], offset+bandOffsets[b], iArray[b]);
+ }
+
+ public void setSample(int x, int y, int b, int s, DataBuffer data)
+ {
+ data.setElem(bankIndices[b], getOffset(x, y, b), s);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/ConvolveOp.java b/libjava/classpath/java/awt/image/ConvolveOp.java
new file mode 100644
index 0000000..f841c13
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ConvolveOp.java
@@ -0,0 +1,337 @@
+/* ConvolveOp.java --
+ Copyright (C) 2004 Free Software Foundation -- ConvolveOp
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+/**
+ * Convolution filter.
+ *
+ * ConvolveOp convolves the source image with a Kernel to generate a
+ * destination image. This involves multiplying each pixel and its neighbors
+ * with elements in the kernel to compute a new pixel.
+ *
+ * Each band in a Raster is convolved and copied to the destination Raster.
+ *
+ * For BufferedImages, convolution is applied to all components. If the
+ * source is not premultiplied, the data will be premultiplied before
+ * convolving. Premultiplication will be undone if the destination is not
+ * premultiplied. Color conversion will be applied if needed.
+ *
+ * @author jlquinn@optonline.net
+ */
+public class ConvolveOp implements BufferedImageOp, RasterOp
+{
+ /** Edge pixels are set to 0. */
+ public static final int EDGE_ZERO_FILL = 0;
+
+ /** Edge pixels are copied from the source. */
+ public static final int EDGE_NO_OP = 1;
+
+ private Kernel kernel;
+ private int edge;
+ private RenderingHints hints;
+
+ /**
+ * Construct a ConvolveOp.
+ *
+ * The edge condition specifies that pixels outside the area that can be
+ * filtered are either set to 0 or copied from the source image.
+ *
+ * @param kernel The kernel to convolve with.
+ * @param edgeCondition Either EDGE_ZERO_FILL or EDGE_NO_OP.
+ * @param hints Rendering hints for color conversion, or null.
+ */
+ public ConvolveOp(Kernel kernel,
+ int edgeCondition,
+ RenderingHints hints)
+ {
+ this.kernel = kernel;
+ edge = edgeCondition;
+ this.hints = hints;
+ }
+
+ /**
+ * Construct a ConvolveOp.
+ *
+ * The edge condition defaults to EDGE_ZERO_FILL.
+ *
+ * @param kernel The kernel to convolve with.
+ */
+ public ConvolveOp(Kernel kernel)
+ {
+ this.kernel = kernel;
+ edge = EDGE_ZERO_FILL;
+ hints = null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage,
+ * java.awt.image.BufferedImage)
+ */
+ public BufferedImage filter(BufferedImage src, BufferedImage dst)
+ {
+ if (src == dst)
+ throw new IllegalArgumentException();
+
+ if (dst == null)
+ dst = createCompatibleDestImage(src, src.getColorModel());
+
+ // Make sure source image is premultiplied
+ BufferedImage src1 = src;
+ if (!src.isPremultiplied)
+ {
+ src1 = createCompatibleDestImage(src, src.getColorModel());
+ src.copyData(src1.getRaster());
+ src1.coerceData(true);
+ }
+
+ BufferedImage dst1 = dst;
+ if (!src.getColorModel().equals(dst.getColorModel()))
+ dst1 = createCompatibleDestImage(src, src.getColorModel());
+
+ filter(src1.getRaster(), dst1.getRaster());
+
+ if (dst1 != dst)
+ {
+ // Convert between color models.
+ // TODO Check that premultiplied alpha is handled correctly here.
+ Graphics2D gg = dst.createGraphics();
+ gg.setRenderingHints(hints);
+ gg.drawImage(dst1, 0, 0, null);
+ gg.dispose();
+ }
+
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see
+ * java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage,
+ * java.awt.image.ColorModel)
+ */
+ public BufferedImage createCompatibleDestImage(BufferedImage src,
+ ColorModel dstCM)
+ {
+ // FIXME: set properties to those in src
+ return new BufferedImage(dstCM,
+ src.getRaster().createCompatibleWritableRaster(),
+ src.isPremultiplied, null);
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getRenderingHints()
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /**
+ * @return The edge condition.
+ */
+ public int getEdgeCondition()
+ {
+ return edge;
+ }
+
+ /**
+ * @return The convolution kernel.
+ */
+ public Kernel getKernel()
+ {
+ return kernel;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster,
+ * java.awt.image.WritableRaster)
+ */
+ public WritableRaster filter(Raster src, WritableRaster dest) {
+ if (src.numBands != dest.numBands)
+ throw new ImagingOpException(null);
+ if (src == dest)
+ throw new IllegalArgumentException();
+ if (src.getWidth() < kernel.getWidth() ||
+ src.getHeight() < kernel.getHeight())
+ throw new ImagingOpException(null);
+
+ if (dest == null)
+ dest = createCompatibleDestRaster(src);
+
+ // Deal with bottom edge
+ if (edge == EDGE_ZERO_FILL)
+ {
+ float[] zeros = new float[src.getNumBands() * src.getWidth()
+ * (kernel.getYOrigin() - 1)];
+ Arrays.fill(zeros, 0);
+ dest.setPixels(src.getMinX(), src.getMinY(), src.getWidth(),
+ kernel.getYOrigin() - 1, zeros);
+ }
+ else
+ {
+ float[] vals = new float[src.getNumBands() * src.getWidth()
+ * (kernel.getYOrigin() - 1)];
+ src.getPixels(src.getMinX(), src.getMinY(), src.getWidth(),
+ kernel.getYOrigin() - 1, vals);
+ dest.setPixels(src.getMinX(), src.getMinY(), src.getWidth(),
+ kernel.getYOrigin() - 1, vals);
+ }
+
+ // Handle main section
+ float[] kvals = kernel.getKernelData(null);
+
+ float[] tmp = new float[kernel.getWidth() * kernel.getHeight()];
+ for (int y = src.getMinY() + kernel.getYOrigin();
+ y < src.getMinY() + src.getHeight() - kernel.getYOrigin() / 2; y++)
+ {
+ // Handle unfiltered edge pixels at start of line
+ float[] t1 = new float[(kernel.getXOrigin() - 1) * src.getNumBands()];
+ if (edge == EDGE_ZERO_FILL)
+ Arrays.fill(t1, 0);
+ else
+ src.getPixels(src.getMinX(), y, kernel.getXOrigin() - 1, 1, t1);
+ dest.setPixels(src.getMinX(), y, kernel.getXOrigin() - 1, 1, t1);
+
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ {
+ // FIXME: This needs a much more efficient implementation
+ for (int b = 0; b < src.getNumBands(); b++)
+ {
+ float v = 0;
+ src.getSamples(x, y, kernel.getWidth(), kernel.getHeight(), b, tmp);
+ for (int i=0; i < tmp.length; i++)
+ v += tmp[i] * kvals[i];
+ dest.setSample(x, y, b, v);
+ }
+ }
+
+ // Handle unfiltered edge pixels at end of line
+ float[] t2 = new float[(kernel.getWidth() / 2) * src.getNumBands()];
+ if (edge == EDGE_ZERO_FILL)
+ Arrays.fill(t2, 0);
+ else
+ src.getPixels(src.getMinX() + src.getWidth()
+ - (kernel.getWidth() / 2),
+ y, kernel.getWidth() / 2, 1, t2);
+ dest.setPixels(src.getMinX() + src.getWidth() - (kernel.getWidth() / 2),
+ y, kernel.getWidth() / 2, 1, t2);
+ }
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++)
+ {
+
+ }
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++)
+ {
+
+ }
+
+ // Handle top edge
+ if (edge == EDGE_ZERO_FILL)
+ {
+ float[] zeros = new float[src.getNumBands() * src.getWidth() *
+ (kernel.getHeight() / 2)];
+ Arrays.fill(zeros, 0);
+ dest.setPixels(src.getMinX(),
+ src.getHeight() + src.getMinY() - (kernel.getHeight() / 2),
+ src.getWidth(), kernel.getHeight() / 2, zeros);
+ }
+ else
+ {
+ float[] vals = new float[src.getNumBands() * src.getWidth() *
+ (kernel.getHeight() / 2)];
+ src.getPixels(src.getMinX(),
+ src.getHeight() + src.getMinY()
+ - (kernel.getHeight() / 2),
+ src.getWidth(), kernel.getHeight() / 2, vals);
+ dest.setPixels(src.getMinX(),
+ src.getHeight() + src.getMinY()
+ - (kernel.getHeight() / 2),
+ src.getWidth(), kernel.getHeight() / 2, vals);
+ }
+
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return src.createCompatibleWritableRaster();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
+ */
+ public Rectangle2D getBounds2D(BufferedImage src)
+ {
+ return src.getRaster().getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ /** Return corresponding destination point for source point.
+ *
+ * ConvolveOp will return the value of src unchanged.
+ * @param src The source point.
+ * @param dst The destination point.
+ * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D,
+ * java.awt.geom.Point2D)
+ */
+ public Point2D getPoint2D(Point2D src, Point2D dst)
+ {
+ if (dst == null) return (Point2D)src.clone();
+ dst.setLocation(src);
+ return dst;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/CropImageFilter.java b/libjava/classpath/java/awt/image/CropImageFilter.java
new file mode 100644
index 0000000..490f43c
--- /dev/null
+++ b/libjava/classpath/java/awt/image/CropImageFilter.java
@@ -0,0 +1,180 @@
+/* CropImageFilter.java -- Java class for cropping image filter
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Rectangle;
+import java.util.Hashtable;
+
+/**
+ * Currently this filter does almost nothing and needs to be implemented.
+ *
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public class CropImageFilter extends ImageFilter
+{
+ int x;
+ int y;
+ int width;
+ int height;
+
+ /**
+ * Construct a new <code>CropImageFilter</code> instance.
+ *
+ * @param x the x-coordinate location of the top-left of the cropped rectangle
+ * @param y the y-coordinate location of the top-left of the cropped rectangle
+ * @param width the width of the cropped rectangle
+ * @param height the height of the cropped rectangle
+ */
+ public CropImageFilter(int x, int y, int width, int height) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * An <code>ImageProducer</code> indicates the size of the image
+ * being produced using this method. This filter overrides this
+ * method in order to set the dimentions to the size of the
+ * cropped rectangle instead of the size of the image.
+ *
+ * @param width the width of the image
+ * @param height the height of the image
+ */
+ public void setDimensions(int width, int height)
+ {
+ consumer.setDimensions(this.width, this.height);
+ }
+
+ /**
+ * An <code>ImageProducer</code> can set a list of properties
+ * associated with this image by using this method.
+ * <br>
+ * FIXME - What property is set for this class?
+ *
+ * @param props the list of properties associated with this image
+ */
+ public void setProperties(Hashtable props)
+ {
+ props.put("filters", "CropImageFilter");
+ consumer.setProperties(props);
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as a <code>byte</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels, int offset, int scansize)
+ {
+ Rectangle filterBounds = new Rectangle(this.x, this.y,
+ this.width, this.height);
+ Rectangle pixelBounds = new Rectangle(x, y, w, h);
+
+ if (filterBounds.intersects(pixelBounds))
+ {
+ Rectangle bounds = filterBounds.intersection(pixelBounds);
+
+ byte[] cropped = new byte[bounds.width * bounds.height];
+ for (int i = 0; i < bounds.height; i++)
+ {
+ int start = (bounds.y - pixelBounds.y + i) * scansize + offset;
+
+ for (int j = 0; j < bounds.width; j++)
+ cropped[i * bounds.width + j] = pixels[start + bounds.x + j];
+ }
+
+ consumer.setPixels(bounds.x, bounds.y,
+ bounds.width, bounds.height,
+ model, cropped, 0, bounds.width);
+ }
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as an <code>int</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels, int offset, int scansize)
+ {
+ Rectangle filterBounds = new Rectangle(this.x, this.y,
+ this.width, this.height);
+ Rectangle pixelBounds = new Rectangle(x, y, w, h);
+
+ if (filterBounds.intersects(pixelBounds))
+ {
+ Rectangle bounds = filterBounds.intersection(pixelBounds);
+
+ int[] cropped = new int[bounds.width * bounds.height];
+ for (int i = 0; i < bounds.height; i++)
+ {
+ int start = (bounds.y - pixelBounds.y + i) * scansize + offset;
+
+ for (int j = 0; j < bounds.width; j++)
+ cropped[i * bounds.width + j] = pixels[start + bounds.x + j];
+ }
+
+ consumer.setPixels(bounds.x, bounds.y,
+ bounds.width, bounds.height,
+ model, cropped, 0, bounds.width);
+ }
+ }
+
+}
+
diff --git a/libjava/classpath/java/awt/image/DataBuffer.java b/libjava/classpath/java/awt/image/DataBuffer.java
new file mode 100644
index 0000000..9e4f714
--- /dev/null
+++ b/libjava/classpath/java/awt/image/DataBuffer.java
@@ -0,0 +1,436 @@
+/* Copyright (C) 2000, 2002, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/**
+ * Class that manages arrays of data elements. A data buffer consists
+ * of one or more banks. A bank is a continuous region of data
+ * elements.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public abstract class DataBuffer
+{
+ /**
+ * A constant representing a data type that uses <code>byte</code> primitives
+ * as the storage unit.
+ */
+ public static final int TYPE_BYTE = 0;
+
+ /**
+ * A constant representing a data type that uses <code>short</code>
+ * primitives as the storage unit.
+ */
+ public static final int TYPE_USHORT = 1;
+
+ /**
+ * A constant representing a data type that uses <code>short</code>
+ * primitives as the storage unit.
+ */
+ public static final int TYPE_SHORT = 2;
+
+ /**
+ * A constant representing a data type that uses <code>int</code>
+ * primitives as the storage unit.
+ */
+ public static final int TYPE_INT = 3;
+
+ /**
+ * A constant representing a data type that uses <code>float</code>
+ * primitives as the storage unit.
+ */
+ public static final int TYPE_FLOAT = 4;
+
+ /**
+ * A constant representing a data type that uses <code>double</code>
+ * primitives as the storage unit.
+ */
+ public static final int TYPE_DOUBLE = 5;
+
+ /**
+ * A constant representing an undefined data type.
+ */
+ public static final int TYPE_UNDEFINED = 32;
+
+ /** The type of the data elements stored in the data buffer. */
+ protected int dataType;
+
+ /** The number of banks in this buffer. */
+ protected int banks = 1;
+
+ /** Offset into the default (0'th) bank). */
+ protected int offset; // FIXME: Is offsets[0] always mirrored in offset?
+
+ /** The size of the banks. */
+ protected int size;
+
+ /** Offset into each bank. */
+ protected int[] offsets;
+
+ /**
+ * Creates a new <code>DataBuffer</code> with the specified data type and
+ * size. The <code>dataType</code> should be one of the constants
+ * {@link #TYPE_BYTE}, {@link #TYPE_SHORT}, {@link #TYPE_USHORT},
+ * {@link #TYPE_INT}, {@link #TYPE_FLOAT} and {@link #TYPE_DOUBLE}.
+ * <p>
+ * The physical (array-based) storage is allocated by a subclass.
+ *
+ * @param dataType the data type.
+ * @param size the number of elements in the buffer.
+ */
+ protected DataBuffer(int dataType, int size)
+ {
+ this.dataType = dataType;
+ this.size = size;
+ }
+
+ /**
+ * Creates a new <code>DataBuffer</code> with the specified data type,
+ * size and number of banks. The <code>dataType</code> should be one of
+ * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ * <p>
+ * The physical (array-based) storage is allocated by a subclass.
+ *
+ * @param dataType the data type.
+ * @param size the number of elements in the buffer.
+ * @param numBanks the number of data banks.
+ */
+ protected DataBuffer(int dataType, int size, int numBanks) {
+ this(dataType, size);
+ banks = numBanks;
+ offsets = new int[numBanks];
+ }
+
+ /**
+ * Creates a new <code>DataBuffer</code> with the specified data type,
+ * size and number of banks. An offset (which applies to all banks) is
+ * also specified. The <code>dataType</code> should be one of
+ * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ * <p>
+ * The physical (array-based) storage is allocated by a subclass.
+ *
+ * @param dataType the data type.
+ * @param size the number of elements in the buffer.
+ * @param numBanks the number of data banks.
+ * @param offset the offset to the first element for all banks.
+ */
+ protected DataBuffer(int dataType, int size, int numBanks, int offset) {
+ this(dataType, size, numBanks);
+
+ java.util.Arrays.fill(offsets, offset);
+
+ this.offset = offset;
+ }
+
+ /**
+ * Creates a new <code>DataBuffer</code> with the specified data type,
+ * size and number of banks. An offset (which applies to all banks) is
+ * also specified. The <code>dataType</code> should be one of
+ * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ * <p>
+ * The physical (array-based) storage is allocated by a subclass.
+ *
+ * @param dataType the data type.
+ * @param size the number of elements in the buffer.
+ * @param numBanks the number of data banks.
+ * @param offsets the offsets to the first element for all banks.
+ *
+ * @throws ArrayIndexOutOfBoundsException if
+ * <code>numBanks != offsets.length</code>.
+ */
+ protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
+ this(dataType, size);
+ if (numBanks != offsets.length)
+ throw new ArrayIndexOutOfBoundsException();
+
+ banks = numBanks;
+ this.offsets = offsets;
+
+ offset = offsets[0];
+ }
+
+ /**
+ * Returns the size (number of bits) of the specified data type. Valid types
+ * are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ *
+ * @param dataType the data type.
+ * @return The number of bits for the specified data type.
+ * @throws IllegalArgumentException if <code>dataType < 0</code> or
+ * <code>dataType > TYPE_DOUBLE</code>.
+ */
+ public static int getDataTypeSize(int dataType) {
+ // Maybe this should be a lookup table instead.
+ switch (dataType)
+ {
+ case TYPE_BYTE:
+ return 8;
+ case TYPE_USHORT:
+ case TYPE_SHORT:
+ return 16;
+ case TYPE_INT:
+ case TYPE_FLOAT:
+ return 32;
+ case TYPE_DOUBLE:
+ return 64;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Returns the type of the data elements in the data buffer. Valid types
+ * are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ *
+ * @return The type.
+ */
+ public int getDataType()
+ {
+ return dataType;
+ }
+
+ /**
+ * Returns the size of the data buffer.
+ *
+ * @return The size.
+ */
+ public int getSize()
+ {
+ return size;
+ }
+
+ /**
+ * Returns the element offset for the first data bank.
+ *
+ * @return The element offset.
+ */
+ public int getOffset()
+ {
+ return offset;
+ }
+
+ /**
+ * Returns the offsets for all the data banks used by this
+ * <code>DataBuffer</code>.
+ *
+ * @return The offsets.
+ */
+ public int[] getOffsets()
+ {
+ if (offsets == null)
+ {
+ // is this necessary?
+ offsets = new int[1];
+ offsets[0] = offset;
+ }
+ return offsets;
+ }
+
+ /**
+ * Returns the number of data banks for this <code>DataBuffer</code>.
+ * @return The number of data banks.
+ */
+ public int getNumBanks()
+ {
+ return banks;
+ }
+
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int i)
+ {
+ return getElem(0, i);
+ }
+
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public abstract int getElem(int bank, int i);
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int i, int val)
+ {
+ setElem(0, i, val);
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public abstract void setElem(int bank, int i, int val);
+
+ /**
+ * Returns an element from the first data bank, converted to a
+ * <code>float</code>. The offset (specified in the constructor) is added
+ * to <code>i</code> before accessing the underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public float getElemFloat(int i)
+ {
+ return getElem(i);
+ }
+
+ /**
+ * Returns an element from a particular data bank, converted to a
+ * <code>float</code>. The offset (specified in the constructor) is
+ * added to <code>i</code> before accessing the underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public float getElemFloat(int bank, int i)
+ {
+ return getElem(bank, i);
+ }
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElemFloat(int i, float val)
+ {
+ setElem(i, (int) val);
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElemFloat(int bank, int i, float val)
+ {
+ setElem(bank, i, (int) val);
+ }
+
+ /**
+ * Returns an element from the first data bank, converted to a
+ * <code>double</code>. The offset (specified in the constructor) is added
+ * to <code>i</code> before accessing the underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public double getElemDouble(int i)
+ {
+ return getElem(i);
+ }
+
+ /**
+ * Returns an element from a particular data bank, converted to a
+ * <code>double</code>. The offset (specified in the constructor) is
+ * added to <code>i</code> before accessing the underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public double getElemDouble(int bank, int i)
+ {
+ return getElem(bank, i);
+ }
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElemDouble(int i, double val)
+ {
+ setElem(i, (int) val);
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElemDouble(int bank, int i, double val)
+ {
+ setElem(bank, i, (int) val);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/DataBufferByte.java b/libjava/classpath/java/awt/image/DataBufferByte.java
new file mode 100644
index 0000000..1113ebb
--- /dev/null
+++ b/libjava/classpath/java/awt/image/DataBufferByte.java
@@ -0,0 +1,245 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * A {@link DataBuffer} that uses an array of <code>byte</code> primitives
+ * to represent each of its banks.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public final class DataBufferByte extends DataBuffer
+{
+ private byte[] data;
+ private byte[][] bankData;
+
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>byte</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferByte(int size)
+ {
+ super(TYPE_BYTE, size, 1, 0);
+ bankData = new byte[1][];
+ data = new byte[size];
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>byte</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
+ public DataBufferByte(int size, int numBanks)
+ {
+ super(TYPE_BYTE, size, numBanks);
+ bankData = new byte[numBanks][size];
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferByte(byte[] dataArray, int size)
+ {
+ super(TYPE_BYTE, size, 1, 0);
+ bankData = new byte[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
+ public DataBufferByte(byte[] dataArray, int size, int offset)
+ {
+ super(TYPE_BYTE, size, 1, offset);
+ bankData = new byte[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferByte(byte[][] dataArray, int size)
+ {
+ super(TYPE_BYTE, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferByte(byte[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_BYTE, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
+ public byte[] getData()
+ {
+ return data;
+ }
+
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
+ public byte[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
+ public byte[][] getBankData()
+ {
+ return bankData;
+ }
+
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int i)
+ {
+ return data[i+offset] & 0xff; // get unsigned byte as int
+ }
+
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int bank, int i)
+ {
+ // get unsigned byte as int
+ return bankData[bank][i+offsets[bank]] & 0xff;
+ }
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = (byte) val;
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = (byte) val;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/DataBufferDouble.java b/libjava/classpath/java/awt/image/DataBufferDouble.java
new file mode 100644
index 0000000..a8c4b9d
--- /dev/null
+++ b/libjava/classpath/java/awt/image/DataBufferDouble.java
@@ -0,0 +1,288 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * A {@link DataBuffer} that uses an array of <code>double</code> primitives
+ * to represent each of its banks.
+ *
+ * @since 1.4
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public final class DataBufferDouble
+ extends DataBuffer
+{
+ private double[] data;
+ private double[][] bankData;
+
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>double</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferDouble(int size)
+ {
+ super(TYPE_DOUBLE, size, 1, 0);
+ bankData = new double[1][];
+ data = new double[size];
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>double</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
+ public DataBufferDouble(int size, int numBanks)
+ {
+ super(TYPE_DOUBLE, size, numBanks);
+ bankData = new double[numBanks][size];
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferDouble(double[] dataArray, int size)
+ {
+ super(TYPE_DOUBLE, size, 1, 0);
+ bankData = new double[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
+ public DataBufferDouble(double[] dataArray, int size, int offset)
+ {
+ super(TYPE_DOUBLE, size, 1, offset);
+ bankData = new double[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferDouble(double[][] dataArray, int size)
+ {
+ super(TYPE_DOUBLE, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferDouble(double[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_DOUBLE, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
+ public double[] getData()
+ {
+ return data;
+ }
+
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
+ public double[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
+ public double[][] getBankData()
+ {
+ return bankData;
+ }
+
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int i)
+ {
+ return (int) data[i+offset];
+ }
+
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int bank, int i)
+ {
+ return (int) bankData[bank][i+offsets[bank]];
+ }
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = val;
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = val;
+ }
+
+ public float getElemFloat(int i)
+ {
+ return (float) data[i+offset];
+ }
+
+ public float getElemFloat(int bank, int i)
+ {
+ return (float) bankData[bank][i+offsets[bank]];
+ }
+
+ public void setElemFloat(int i, float val)
+ {
+ data[i+offset] = val;
+ }
+
+ public void setElemFloat(int bank, int i, float val)
+ {
+ bankData[bank][i+offsets[bank]] = val;
+ }
+
+ public double getElemDouble(int i)
+ {
+ return data[i + offset];
+ }
+
+ public double getElemDouble(int bank, int i)
+ {
+ return bankData[bank][i + offsets[bank]];
+ }
+
+ public void setElemDouble(int i, double val)
+ {
+ data[i + offset] = val;
+ }
+
+ public void setElemDouble(int bank, int i, double val)
+ {
+ bankData[bank][i + offsets[bank]] = val;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/DataBufferFloat.java b/libjava/classpath/java/awt/image/DataBufferFloat.java
new file mode 100644
index 0000000..9cf8784
--- /dev/null
+++ b/libjava/classpath/java/awt/image/DataBufferFloat.java
@@ -0,0 +1,286 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * A {@link DataBuffer} that uses an array of <code>float</code> primitives
+ * to represent each of its banks.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public final class DataBufferFloat
+ extends DataBuffer
+{
+ private float[] data;
+ private float[][] bankData;
+
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>float</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferFloat(int size)
+ {
+ super(TYPE_FLOAT, size, 1, 0);
+ bankData = new float[1][];
+ data = new float[size];
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>float</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
+ public DataBufferFloat(int size, int numBanks)
+ {
+ super(TYPE_FLOAT, size, numBanks);
+ bankData = new float[numBanks][size];
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferFloat(float[] dataArray, int size)
+ {
+ super(TYPE_FLOAT, size, 1, 0);
+ bankData = new float[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
+ public DataBufferFloat(float[] dataArray, int size, int offset)
+ {
+ super(TYPE_FLOAT, size, 1, offset);
+ bankData = new float[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferFloat(float[][] dataArray, int size)
+ {
+ super(TYPE_FLOAT, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferFloat(float[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_FLOAT, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
+ public float[] getData()
+ {
+ return data;
+ }
+
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
+ public float[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
+ public float[][] getBankData()
+ {
+ return bankData;
+ }
+
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int i)
+ {
+ return (int) data[i+offset];
+ }
+
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int bank, int i)
+ {
+ return (int) bankData[bank][i+offsets[bank]];
+ }
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = val;
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = val;
+ }
+
+ public float getElemFloat(int i)
+ {
+ return data[i+offset];
+ }
+
+ public float getElemFloat(int bank, int i)
+ {
+ return bankData[bank][i+offsets[bank]];
+ }
+
+ public void setElemFloat(int i, float val)
+ {
+ data[i+offset] = val;
+ }
+
+ public void setElemFloat(int bank, int i, float val)
+ {
+ bankData[bank][i+offsets[bank]] = val;
+ }
+
+ public double getElemDouble(int i)
+ {
+ return getElemFloat(i);
+ }
+
+ public double getElemDouble(int bank, int i)
+ {
+ return getElemFloat(bank, i);
+ }
+
+ public void setElemDouble(int i, double val)
+ {
+ setElemFloat(i, (float) val);
+ }
+
+ public void setElemDouble(int bank, int i, double val)
+ {
+ setElemFloat(bank, i, (float) val);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/DataBufferInt.java b/libjava/classpath/java/awt/image/DataBufferInt.java
new file mode 100644
index 0000000..0aac940
--- /dev/null
+++ b/libjava/classpath/java/awt/image/DataBufferInt.java
@@ -0,0 +1,244 @@
+/* Copyright (C) 2000, 2002, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * A {@link DataBuffer} that uses an array of <code>int</code> primitives
+ * to represent each of its banks.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public final class DataBufferInt extends DataBuffer
+{
+ private int[] data;
+ private int[][] bankData;
+
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>int</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferInt(int size)
+ {
+ super(TYPE_INT, size, 1, 0);
+ bankData = new int[1][];
+ data = new int[size];
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>int</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
+ public DataBufferInt(int size, int numBanks)
+ {
+ super(TYPE_INT, size, numBanks);
+ bankData = new int[numBanks][size];
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferInt(int[] dataArray, int size)
+ {
+ super(TYPE_INT, size, 1, 0);
+ bankData = new int[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
+ public DataBufferInt(int[] dataArray, int size, int offset)
+ {
+ super(TYPE_INT, size, 1, offset);
+ bankData = new int[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferInt(int[][] dataArray, int size)
+ {
+ super(TYPE_INT, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferInt(int[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_INT, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
+ public int[] getData()
+ {
+ return data;
+ }
+
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
+ public int[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
+ public int[][] getBankData()
+ {
+ return bankData;
+ }
+
+ /**
+ * Returns an element from the first data bank. The <code>offset</code> is
+ * added to the specified index before accessing the underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int i)
+ {
+ return data[i+offset];
+ }
+
+ /**
+ * Returns an element from a particular data bank. The <code>offset</code>
+ * is added to the specified index before accessing the underlying data
+ * array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int bank, int i)
+ {
+ // get unsigned int as int
+ return bankData[bank][i+offsets[bank]];
+ }
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = val;
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = val;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/DataBufferShort.java b/libjava/classpath/java/awt/image/DataBufferShort.java
new file mode 100644
index 0000000..5c67a8d
--- /dev/null
+++ b/libjava/classpath/java/awt/image/DataBufferShort.java
@@ -0,0 +1,245 @@
+/* DataBufferShort.java --
+ Copyright (C) 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * A {@link DataBuffer} that uses an array of <code>short</code> primitives
+ * to represent each of its banks.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public final class DataBufferShort extends DataBuffer
+{
+ private short[] data;
+ private short[][] bankData;
+
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>short</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferShort(int size)
+ {
+ super(TYPE_SHORT, size, 1, 0);
+ bankData = new short[1][];
+ data = new short[size];
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>short</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
+ public DataBufferShort(int size, int numBanks)
+ {
+ super(TYPE_SHORT, size, numBanks);
+ bankData = new short[numBanks][size];
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferShort(short[] dataArray, int size)
+ {
+ super(TYPE_SHORT, size, 1, 0);
+ bankData = new short[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
+ public DataBufferShort(short[] dataArray, int size, int offset)
+ {
+ super(TYPE_SHORT, size, 1, offset);
+ bankData = new short[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferShort(short[][] dataArray, int size)
+ {
+ super(TYPE_SHORT, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferShort(short[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_SHORT, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
+ public short[] getData()
+ {
+ return data;
+ }
+
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
+ public short[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
+ public short[][] getBankData()
+ {
+ return bankData;
+ }
+
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int i)
+ {
+ return data[i+offset];
+ }
+
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int bank, int i)
+ {
+ return bankData[bank][i+offsets[bank]];
+ }
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = (short) val;
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = (short) val;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/DataBufferUShort.java b/libjava/classpath/java/awt/image/DataBufferUShort.java
new file mode 100644
index 0000000..981e9e9
--- /dev/null
+++ b/libjava/classpath/java/awt/image/DataBufferUShort.java
@@ -0,0 +1,246 @@
+/* DataBufferUShort.java --
+ Copyright (C) 2000, 2002, 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * A {@link DataBuffer} that uses an array of <code>short</code> primitives
+ * to represent each of its banks.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public final class DataBufferUShort extends DataBuffer
+{
+ private short[] data;
+ private short[][] bankData;
+
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>short</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
+ public DataBufferUShort(int size)
+ {
+ super(TYPE_USHORT, size, 1, 0);
+ bankData = new short[1][];
+ data = new short[size];
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>short</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
+ public DataBufferUShort(int size, int numBanks)
+ {
+ super(TYPE_USHORT, size, numBanks);
+ bankData = new short[numBanks][size];
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if dataArray is null
+ */
+ public DataBufferUShort(short[] dataArray, int size)
+ {
+ super(TYPE_USHORT, size, 1, 0);
+ if (dataArray == null)
+ throw new NullPointerException();
+ bankData = new short[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ *
+ * @throws NullPointerException if dataArray is null
+ */
+ public DataBufferUShort(short[] dataArray, int size, int offset)
+ {
+ super(TYPE_USHORT, size, 1, offset);
+ if (dataArray == null)
+ throw new NullPointerException();
+ bankData = new short[1][];
+ data = dataArray;
+ bankData[0] = data;
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferUShort(short[][] dataArray, int size)
+ {
+ super(TYPE_USHORT, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
+ public DataBufferUShort(short[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_USHORT, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
+ public short[] getData()
+ {
+ return data;
+ }
+
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
+ public short[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
+ public short[][] getBankData()
+ {
+ return bankData;
+ }
+
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int i)
+ {
+ return data[i+offset] & 0xffff; // get unsigned short as int
+ }
+
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
+ public int getElem(int bank, int i)
+ {
+ // get unsigned short as int
+ return bankData[bank][i+offsets[bank]] & 0xffff;
+ }
+
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = (short) val;
+ }
+
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = (short) val;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/DirectColorModel.java b/libjava/classpath/java/awt/image/DirectColorModel.java
new file mode 100644
index 0000000..c98c3f8
--- /dev/null
+++ b/libjava/classpath/java/awt/image/DirectColorModel.java
@@ -0,0 +1,420 @@
+/* DirectColorModel.java --
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import gnu.java.awt.Buffers;
+
+import java.awt.Point;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+
+/**
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @author C. Brian Jones (cbj@gnu.org)
+ * @author Mark Benvenuto (mcb54@columbia.edu)
+ */
+public class DirectColorModel extends PackedColorModel
+{
+ /**
+ * For the color model created with this constructor the pixels
+ * will have fully opaque alpha components with a value of 255.
+ * Each mask should describe a fully contiguous set of bits in the
+ * most likely order of alpha, red, green, blue from the most significant
+ * byte to the least significant byte.
+ *
+ * @param pixelBits the number of bits wide used for bit size of pixel values
+ * @param rmask the bits describing the red component of a pixel
+ * @param gmask the bits describing the green component of a pixel
+ * @param bmask the bits describing the blue component of a pixel
+ */
+ public DirectColorModel(int pixelBits, int rmask, int gmask, int bmask)
+ {
+ this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
+ rmask, gmask, bmask, 0,
+ false, // not alpha premultiplied
+ Buffers.smallestAppropriateTransferType(pixelBits) // find type
+ );
+ }
+
+ /**
+ * For the color model created with this constructor the pixels
+ * will have fully opaque alpha components with a value of 255.
+ * Each mask should describe a fully contiguous set of bits in the
+ * most likely order of red, green, blue from the most significant
+ * byte to the least significant byte.
+ *
+ * @param pixelBits the number of bits wide used for bit size of pixel values
+ * @param rmask the bits describing the red component of a pixel
+ * @param gmask the bits describing the green component of a pixel
+ * @param bmask the bits describing the blue component of a pixel
+ * @param amask the bits describing the alpha component of a pixel
+ */
+ public DirectColorModel(int pixelBits,
+ int rmask, int gmask, int bmask, int amask)
+ {
+ this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
+ rmask, gmask, bmask, amask,
+ false, // not alpha premultiplied
+ Buffers.smallestAppropriateTransferType(pixelBits) // find type
+ );
+ }
+
+ public DirectColorModel(ColorSpace cspace, int pixelBits,
+ int rmask, int gmask, int bmask, int amask,
+ boolean isAlphaPremultiplied,
+ int transferType)
+ {
+ super(cspace, pixelBits,
+ rmask, gmask, bmask, amask, isAlphaPremultiplied,
+ ((amask == 0) ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
+ transferType);
+ }
+
+ public final int getRedMask()
+ {
+ return getMask(0);
+ }
+
+ public final int getGreenMask()
+ {
+ return getMask(1);
+ }
+
+ public final int getBlueMask()
+ {
+ return getMask(2);
+ }
+
+ public final int getAlphaMask()
+ {
+ return hasAlpha() ? getMask(3) : 0;
+ }
+
+ /**
+ * Get the red component of the given pixel.
+ * <br>
+ */
+ public final int getRed(int pixel)
+ {
+ return extractAndNormalizeSample(pixel, 0);
+ }
+
+ /**
+ * Get the green component of the given pixel.
+ * <br>
+ */
+ public final int getGreen(int pixel)
+ {
+ return extractAndNormalizeSample(pixel, 1);
+ }
+
+ /**
+ * Get the blue component of the given pixel.
+ * <br>
+ */
+ public final int getBlue(int pixel)
+ {
+ return extractAndNormalizeSample(pixel, 2);
+ }
+
+ /**
+ * Get the alpha component of the given pixel.
+ * <br>
+ */
+ public final int getAlpha(int pixel)
+ {
+ if (!hasAlpha())
+ return 255;
+ return extractAndScaleSample(pixel, 3);
+ }
+
+ private int extractAndNormalizeSample(int pixel, int component)
+ {
+ int value = extractAndScaleSample(pixel, component);
+ if (hasAlpha() && isAlphaPremultiplied())
+ value = value*255/getAlpha(pixel);
+ return value;
+ }
+
+ private int extractAndScaleSample(int pixel, int component)
+ {
+ int field = pixel & getMask(component);
+ int to8BitShift =
+ 8 - shifts[component] - getComponentSize(component);
+ return (to8BitShift>0) ?
+ (field << to8BitShift) :
+ (field >>> (-to8BitShift));
+ }
+
+ /**
+ * Get the RGB color value of the given pixel using the default
+ * RGB color model.
+ * <br>
+ *
+ * @param pixel a pixel value
+ */
+ public final int getRGB(int pixel)
+ {
+ /* FIXME: The Sun docs show that this method is overridden, but I
+ don't see any way to improve on the superclass
+ implementation. */
+ return super.getRGB(pixel);
+ }
+
+ public int getRed(Object inData)
+ {
+ return getRed(getPixelFromArray(inData));
+ }
+
+ public int getGreen(Object inData)
+ {
+ return getGreen(getPixelFromArray(inData));
+ }
+
+ public int getBlue(Object inData)
+ {
+ return getBlue(getPixelFromArray(inData));
+ }
+
+ public int getAlpha(Object inData)
+ {
+ return getAlpha(getPixelFromArray(inData));
+ }
+
+ public int getRGB(Object inData)
+ {
+ return getRGB(getPixelFromArray(inData));
+ }
+
+ /**
+ * Converts a normalized pixel int value in the sRGB color
+ * space to an array containing a single pixel of the color space
+ * of the color model.
+ *
+ * <p>This method performs the inverse function of
+ * <code>getRGB(Object inData)</code>.
+ *
+ * @param rgb pixel as a normalized sRGB, 0xAARRGGBB value.
+ *
+ * @param pixel to avoid needless creation of arrays, an array to
+ * use to return the pixel can be given. If null, a suitable array
+ * will be created.
+ *
+ * @return array of transferType containing a single pixel. The
+ * pixel should be encoded in the natural way of the color model.
+ *
+ * @see #getRGB(Object)
+ */
+ public Object getDataElements(int rgb, Object pixel)
+ {
+ // FIXME: handle alpha multiply
+
+ int pixelValue = 0;
+ int a = 0;
+ if (hasAlpha()) {
+ a = (rgb >>> 24) & 0xff;
+ pixelValue = valueToField(a, 3, 8);
+ }
+
+ if (hasAlpha() && isAlphaPremultiplied())
+ {
+ int r, g, b;
+ /* if r=0xff and a=0xff, then resulting
+ value will be (r*a)>>>8 == 0xfe... This seems wrong.
+ We should divide by 255 rather than shifting >>>8 after
+ multiplying.
+
+ Too bad, shifting is probably less expensive.
+ r = ((rgb >>> 16) & 0xff)*a;
+ g = ((rgb >>> 8) & 0xff)*a;
+ b = ((rgb >>> 0) & 0xff)*a; */
+ /* The r, g, b values we calculate are 16 bit. This allows
+ us to avoid discarding the lower 8 bits obtained if
+ multiplying with the alpha band. */
+
+ // using 16 bit values
+ r = ((rgb >>> 8) & 0xff00)*a/255;
+ g = ((rgb >>> 0) & 0xff00)*a/255;
+ b = ((rgb << 8) & 0xff00)*a/255;
+ pixelValue |=
+ valueToField(r, 0, 16) | // Red
+ valueToField(g, 1, 16) | // Green
+ valueToField(b, 2, 16); // Blue
+ }
+ else
+ {
+ int r, g, b;
+ // using 8 bit values
+ r = (rgb >>> 16) & 0xff;
+ g = (rgb >>> 8) & 0xff;
+ b = (rgb >>> 0) & 0xff;
+
+ pixelValue |=
+ valueToField(r, 0, 8) | // Red
+ valueToField(g, 1, 8) | // Green
+ valueToField(b, 2, 8); // Blue
+ }
+
+ /* In this color model, the whole pixel fits in the first element
+ of the array. */
+ DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1);
+ buffer.setElem(0, pixelValue);
+ return Buffers.getData(buffer);
+ }
+
+ /**
+ * Converts a value to the correct field bits based on the
+ * information derived from the field masks.
+ *
+ * @param highBit the position of the most significant bit in the
+ * val parameter.
+ */
+ private int valueToField(int val, int component, int highBit)
+ {
+ int toFieldShift =
+ getComponentSize(component) + shifts[component] - highBit;
+ int ret = (toFieldShift>0) ?
+ (val << toFieldShift) :
+ (val >>> (-toFieldShift));
+ return ret & getMask(component);
+ }
+
+ /**
+ * Converts a 16 bit value to the correct field bits based on the
+ * information derived from the field masks.
+ */
+ private int value16ToField(int val, int component)
+ {
+ int toFieldShift = getComponentSize(component) + shifts[component] - 16;
+ return (toFieldShift>0) ?
+ (val << toFieldShift) :
+ (val >>> (-toFieldShift));
+ }
+
+ /**
+ * Fills an array with the unnormalized component samples from a
+ * pixel value. I.e. decompose the pixel, but not perform any
+ * color conversion.
+ */
+ public final int[] getComponents(int pixel, int[] components, int offset)
+ {
+ int numComponents = getNumComponents();
+ if (components == null) components = new int[offset + numComponents];
+
+ for (int b=0; b<numComponents; b++)
+ components[offset++] = (pixel&getMask(b)) >>> shifts[b];
+
+ return components;
+ }
+
+ public final int[] getComponents(Object pixel, int[] components,
+ int offset)
+ {
+ return getComponents(getPixelFromArray(pixel), components, offset);
+ }
+
+ public final WritableRaster createCompatibleWritableRaster(int w, int h)
+ {
+ SampleModel sm = createCompatibleSampleModel(w, h);
+ Point origin = new Point(0, 0);
+ return Raster.createWritableRaster(sm, origin);
+ }
+
+ public int getDataElement(int[] components, int offset)
+ {
+ int numComponents = getNumComponents();
+ int pixelValue = 0;
+
+ for (int c=0; c<numComponents; c++)
+ pixelValue |= (components[offset++] << shifts[c]) & getMask(c);
+
+ return pixelValue;
+ }
+
+ public Object getDataElements(int[] components, int offset, Object obj)
+ {
+ /* In this color model, the whole pixel fits in the first element
+ of the array. */
+ int pixelValue = getDataElement(components, offset);
+
+ DataBuffer buffer = Buffers.createBuffer(transferType, obj, 1);
+ buffer.setElem(0, pixelValue);
+ return Buffers.getData(buffer);
+ }
+
+ public final ColorModel coerceData (WritableRaster raster,
+ boolean isAlphaPremultiplied)
+ {
+ if (this.isAlphaPremultiplied == isAlphaPremultiplied)
+ return this;
+
+ /* TODO: provide better implementation based on the
+ assumptions we can make due to the specific type of the
+ color model. */
+ super.coerceData(raster, isAlphaPremultiplied);
+
+ return new ComponentColorModel(cspace, bits, hasAlpha(),
+ isAlphaPremultiplied, // argument
+ transparency, transferType);
+ }
+
+ public boolean isCompatibleRaster(Raster raster)
+ {
+ /* FIXME: the Sun docs say this method is overridden here,
+ but I don't see any way to improve upon the implementation
+ in ColorModel. */
+ return super.isCompatibleRaster(raster);
+ }
+
+ String stringParam()
+ {
+ return super.stringParam() +
+ ", redMask=" + Integer.toHexString(getRedMask()) +
+ ", greenMask=" + Integer.toHexString(getGreenMask()) +
+ ", blueMask=" + Integer.toHexString(getBlueMask()) +
+ ", alphaMask=" + Integer.toHexString(getAlphaMask());
+ }
+
+ public String toString()
+ {
+ /* FIXME: Again, docs say override, but how do we improve upon the
+ superclass implementation? */
+ return super.toString();
+ }
+}
diff --git a/libjava/classpath/java/awt/image/FilteredImageSource.java b/libjava/classpath/java/awt/image/FilteredImageSource.java
new file mode 100644
index 0000000..8893e86
--- /dev/null
+++ b/libjava/classpath/java/awt/image/FilteredImageSource.java
@@ -0,0 +1,125 @@
+/* FilteredImageSource.java -- Java class for providing image data
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ *
+ * @see ImageConsumer
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public class FilteredImageSource implements ImageProducer
+{
+ ImageProducer ip;
+ ImageFilter filter;
+ Hashtable consumers = new Hashtable();
+
+ /**
+ * The given filter is applied to the given image producer
+ * to create a new image producer.
+ */
+ public FilteredImageSource(ImageProducer ip, ImageFilter filter) {
+ this.ip = ip;
+ this.filter = filter;
+ }
+
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code>.
+ */
+ public synchronized void addConsumer(ImageConsumer ic) {
+ if (consumers.containsKey(ic))
+ return;
+
+ ImageFilter f = filter.getFilterInstance(ic);
+ consumers.put(ic, f);
+ ip.addConsumer(f);
+ }
+
+ /**
+ * Used to determine if the given <code>ImageConsumer</code> is
+ * already registered with this <code>ImageProducer</code>.
+ */
+ public synchronized boolean isConsumer(ImageConsumer ic) {
+ ImageFilter f = (ImageFilter)consumers.get(ic);
+ if (f != null)
+ return ip.isConsumer(f);
+ return false;
+ }
+
+ /**
+ * Used to remove an <code>ImageConsumer</code> from the list of
+ * registered consumers for this <code>ImageProducer</code>.
+ */
+ public synchronized void removeConsumer(ImageConsumer ic) {
+ ImageFilter f = (ImageFilter)consumers.remove(ic);
+ if (f != null)
+ ip.removeConsumer(f);
+ }
+
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code> and then immediately start
+ * reconstruction of the image data to be delivered to all
+ * registered consumers.
+ */
+ public void startProduction(ImageConsumer ic) {
+ ImageFilter f;
+ if (!(consumers.containsKey(ic))) {
+ f = filter.getFilterInstance(ic);
+ consumers.put(ic, f);
+ ip.addConsumer(f);
+ } else {
+ f = (ImageFilter)consumers.get( ic );
+ }
+ ip.startProduction(f);
+ }
+
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code> and then request that this producer
+ * resend the image data in the order top-down, left-right.
+ */
+ public void requestTopDownLeftRightResend(ImageConsumer ic) {
+ ImageFilter f = (ImageFilter)consumers.get(ic);
+ ip.requestTopDownLeftRightResend(f);
+ }
+}
+
diff --git a/libjava/classpath/java/awt/image/ImageConsumer.java b/libjava/classpath/java/awt/image/ImageConsumer.java
new file mode 100644
index 0000000..e1834c3
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ImageConsumer.java
@@ -0,0 +1,216 @@
+/* ImageConsumer.java -- Java interface for image consumption
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * An object implementing the <code>ImageProducer</code> interface can
+ * use objects implementing this interface to deliver the image data.
+ *
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public interface ImageConsumer
+{
+ /**
+ * The pixel order may be random. This should be
+ * the default assumption of the <code>ImageConsumer</code>.
+ *
+ * @see #setHints
+ */
+ int RANDOMPIXELORDER = 1;
+
+ /**
+ * The pixel order is top-down, left-right.
+ *
+ * @see #setHints
+ */
+ int TOPDOWNLEFTRIGHT = 2;
+
+ /**
+ * The pixel order is in multiples of complete scanlines.
+ *
+ * @see #setHints
+ */
+ int COMPLETESCANLINES = 4;
+
+ /**
+ * The pixels will be delivered in a single pass. There is at
+ * most one call to <code>setPixels</code> for any single pixel.
+ *
+ * @see #setHints
+ * @see #setPixels
+ */
+ int SINGLEPASS = 8;
+
+ /**
+ * The pixels will be delivered with multiple calls to
+ * <code>setPixels</code>. The image contains a single frame
+ * which ends when <code>imageComplete</code> is called with the
+ * <code>STATICIMAGEDONE</code> flag. If the image is constantly
+ * changing such as with video then the end of each frame is
+ * marked by a similar call to <code>imageComplete</code> with the
+ * <code>SINGLEFRAMEDONE</code> flag.
+ *
+ * @see #setHints
+ * @see #imageComplete
+ */
+ int SINGLEFRAME = 16;
+
+ /**
+ * Indicates an error occurred while producing an image.
+ *
+ * @see #imageComplete
+ */
+ int IMAGEERROR = 1;
+
+ /**
+ * A single frame is complete but more will follow.
+ *
+ * @see #imageComplete
+ */
+ int SINGLEFRAMEDONE = 2;
+
+ /**
+ * The image is complete and no more pixels or frames will follow.
+ *
+ * @see #imageComplete
+ */
+ int STATICIMAGEDONE = 3;
+
+ /**
+ * Production of the image has been aborted.
+ *
+ * @see #imageComplete
+ */
+ int IMAGEABORTED = 4;
+
+ /**
+ * An <code>ImageProducer</code> indicates the size of the image
+ * being produced using this method.
+ *
+ * @param width the width of the image
+ * @param height the height of the image
+ */
+ void setDimensions(int width, int height);
+
+ /**
+ * An <code>ImageProducer</code> can set a list of properties
+ * associated with this image by using this method.
+ *
+ * @param props the list of properties associated with this image
+ */
+ void setProperties(Hashtable props);
+
+ /**
+ * This <code>ColorModel</code> should indicate the model used by
+ * the majority of calls to <code>setPixels</code>. Each call to
+ * <code>setPixels</code> could however indicate a different
+ * <code>ColorModel</code>.
+ *
+ * @param model the color model to be used most often by setPixels
+ * @see ColorModel
+ */
+ void setColorModel(ColorModel model);
+
+ /**
+ * The <code>ImageProducer</code> should call this method with a
+ * bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
+ * <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
+ * <code>SINGLEPASS</code>, <code>SINGLEFRAME</code>.
+ *
+ * @param flags a bit mask of hints
+ */
+ void setHints(int flags);
+
+ /**
+ * Deliver a subset of an ImageProducer's pixels to this ImageConsumer.
+ *
+ * Each element of the pixels array represents one pixel. The
+ * pixel data is formatted according to the color model model.
+ * The x and y parameters are the coordinates of the block of
+ * pixels being delivered to this ImageConsumer. They are
+ * specified relative to the top left corner of the image being
+ * produced. Likewise, w and h are the pixel block's dimensions.
+ *
+ * @param x x coordinate of pixel block
+ * @param y y coordinate of pixel block
+ * @param w width of pixel block
+ * @param h height of pixel block
+ * @param model color model used to interpret pixel data
+ * @param pixels pixel block data
+ * @param offset offset into pixels array
+ * @param scansize width of one row in the pixel block
+ */
+ void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels, int offset, int scansize);
+
+ /**
+ * Deliver a subset of an ImageProducer's pixels to this ImageConsumer.
+ *
+ * Each element of the pixels array represents one pixel. The
+ * pixel data is formatted according to the color model model.
+ * The x and y parameters are the coordinates of the rectangular
+ * region of pixels being delivered to this ImageConsumer,
+ * specified relative to the top left corner of the image being
+ * produced. Likewise, w and h are the pixel region's dimensions.
+ *
+ * @param x x coordinate of pixel block
+ * @param y y coordinate of pixel block
+ * @param w width of pixel block
+ * @param h height of pixel block
+ * @param model color model used to interpret pixel data
+ * @param pixels pixel block data
+ * @param offset offset into pixels array
+ * @param scansize width of one row in the pixel block
+ */
+ void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels, int offset, int scansize);
+
+ /**
+ * The <code>ImageProducer</code> calls this method to indicate a
+ * single frame or the entire image is complete. The method is
+ * also used to indicate an error in loading or producing the
+ * image.
+ *
+ * @param status the status of image production, represented by a
+ * bitwise OR of ImageConsumer flags
+ */
+ void imageComplete(int status);
+}
diff --git a/libjava/classpath/java/awt/image/ImageFilter.java b/libjava/classpath/java/awt/image/ImageFilter.java
new file mode 100644
index 0000000..9940a2b
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ImageFilter.java
@@ -0,0 +1,221 @@
+/* ImageFilter.java -- Java class for filtering images
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The <code>ImageFilter</code> class is a base class which can be
+ * extended to provide different types of filters for an image. By
+ * default this class does nothing to an image passing through it.
+ *
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public class ImageFilter implements ImageConsumer, Cloneable
+{
+ /**
+ * The consumer this filter is filtering an image data stream for.
+ * It is initialized in the method <code>getFilterInstance</code>.
+ */
+ protected ImageConsumer consumer = null;
+
+ /**
+ * The <code>ImageConsumer</code> can use this method to request
+ * the pixels be delivered in top-down, left-right order.
+ * <br>
+ * The filter can respond in three different ways.
+ * <ul>
+ * <li>The default behavior is to forward the request to the
+ * <code>ImageProducer</code>
+ * using the method <code>requestTopDownLeftRightResend</code>
+ * and using the filter as the consumer.</li>
+ * <li>The filter has the pixels and can retransmit them in the
+ * top-down, left-right order.</li>
+ * <li>The filter can do nothing when this method is called.</li>
+ * </ul>
+ */
+ public void resendTopDownLeftRight(ImageProducer ip)
+ {
+ ip.requestTopDownLeftRightResend(this);
+ }
+
+ /**
+ * By default, returns a shallow copy of the object created by
+ * <code>Object.clone()</code>
+ *
+ * @see java.lang.Object#clone ()
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ // This should never happen as this class implements the
+ // Cloneable interface.
+ throw new InternalError ();
+ }
+ }
+
+ /**
+ * This is the only method which can set the
+ * <code>ImageConsumer</code> for this filter. By default a clone
+ * of this filter with the appropriate consumer set is returned.
+ *
+ * @see #clone ()
+ */
+ public ImageFilter getFilterInstance(ImageConsumer ic)
+ {
+ if ( ic == null )
+ throw new IllegalArgumentException("null argument for ImageFilter.getFilterInstance(ImageConsumer)");
+
+ consumer = ic;
+ ImageFilter f = (ImageFilter)clone();
+ consumer = null;
+ return f;
+ }
+
+ /**
+ * An <code>ImageProducer</code> indicates the size of the image
+ * being produced using this method. A filter can override this
+ * method to intercept these calls from the producer in order to
+ * change either the width or the height before in turn calling
+ * the consumer's <code>setDimensions</code> method.
+ *
+ * @param width the width of the image
+ * @param height the height of the image
+ */
+ public void setDimensions(int width, int height)
+ {
+ consumer.setDimensions(width, height);
+ }
+
+ /**
+ * An <code>ImageProducer</code> can set a list of properties
+ * associated with this image by using this method.
+ *
+ * @param props the list of properties associated with this image
+ */
+ public void setProperties(Hashtable props)
+ {
+ props.put("filters", "ImageFilter");
+ consumer.setProperties(props);
+ }
+
+ /**
+ * Override this method to process calls to this method from the
+ * <code>ImageProducer</code>. By default the <code>setColorModel</code>
+ * method of the consumer is called with the specified <code>model</code>.
+ *
+ * @param model the color model to be used most often by setPixels
+ * @see ColorModel */
+ public void setColorModel(ColorModel model)
+ {
+ consumer.setColorModel(model);
+ }
+
+ /**
+ * The <code>ImageProducer</code> should call this method with a
+ * bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
+ * <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
+ * <code>SINGLEPASS</code>, <code>SINGLEFRAME</code> from the
+ * <code>ImageConsumer</code> interface.
+ *
+ * @param flags a bit mask of hints
+ * @see ImageConsumer
+ */
+ public void setHints(int flags)
+ {
+ consumer.setHints(flags);
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as a <code>byte</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels, int offset, int scansize)
+ {
+ consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as an <code>int</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels, int offset, int scansize)
+ {
+ consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
+ }
+
+ /**
+ * The <code>ImageProducer</code> calls this method to indicate a
+ * single frame or the entire image is complete. The method is
+ * also used to indicate an error in loading or producing the
+ * image.
+ */
+ public void imageComplete(int status)
+ {
+ consumer.imageComplete(status);
+ }
+}
+
diff --git a/libjava/classpath/java/awt/image/ImageObserver.java b/libjava/classpath/java/awt/image/ImageObserver.java
new file mode 100644
index 0000000..36dd013
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ImageObserver.java
@@ -0,0 +1,129 @@
+/* ImageObserver.java -- Java interface for asynchronous updates to an image
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Image;
+
+/**
+ * An object implementing the <code>ImageObserver</code> interface can
+ * receive updates on image construction from an
+ * <code>ImageProducer</code> asynchronously.
+ *
+ * @see ImageProducer
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public interface ImageObserver
+{
+ /**
+ * The width of the image has been provided as the
+ * <code>width</code> argument to <code>imageUpdate</code>.
+ *
+ * @see #imageUpdate
+ */
+ int WIDTH = 1;
+
+ /**
+ * The height of the image has been provided as the
+ * <code>height</code> argument to <code>imageUpdate</code>.
+ *
+ * @see #imageUpdate
+ */
+ int HEIGHT = 2;
+
+ /**
+ * The properties of the image have been provided.
+ *
+ * @see #imageUpdate
+ * @see java.awt.Image#getProperty (java.lang.String, java.awt.image.ImageObserver)
+ */
+ int PROPERTIES = 4;
+
+ /**
+ * More pixels are now available for drawing a scaled variation of
+ * the image.
+ *
+ * @see #imageUpdate
+ */
+ int SOMEBITS = 8;
+
+ /**
+ * All the pixels needed to draw a complete frame of a multi-frame
+ * image are available.
+ *
+ * @see #imageUpdate
+ */
+ int FRAMEBITS = 16;
+
+ /**
+ * An image with a single frame, a static image, is complete.
+ *
+ * @see #imageUpdate
+ */
+ int ALLBITS = 32;
+
+ /**
+ * An error was encountered while producing the image.
+ *
+ * @see #imageUpdate
+ */
+ int ERROR = 64;
+
+ /**
+ * Production of the image was aborted.
+ *
+ * @see #imageUpdate
+ */
+ int ABORT = 128;
+
+ /**
+ * This is a callback method for an asynchronous image producer to
+ * provide updates on the production of the image as it happens.
+ *
+ * @param image the image the update refers to
+ * @param flags a bit mask indicating what is provided with this update
+ * @param x the x coordinate of the image
+ * @param y the y coordinate of the image
+ * @param width the width of the image
+ * @param height the height of the image
+ *
+ * @see java.awt.Image
+ */
+ boolean imageUpdate(Image image, int flags, int x,
+ int y, int width, int height);
+}
diff --git a/libjava/classpath/java/awt/image/ImageProducer.java b/libjava/classpath/java/awt/image/ImageProducer.java
new file mode 100644
index 0000000..4984668
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ImageProducer.java
@@ -0,0 +1,85 @@
+/* ImageProducer.java -- Java interface for image production
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * An object implementing the <code>ImageProducer</code> interface can
+ * produce data for images. Each image has a corresponding
+ * <code>ImageProducer</code> which is needed for things such as
+ * resizing the image.
+ *
+ * @see ImageConsumer
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public interface ImageProducer
+{
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code>.
+ */
+ void addConsumer(ImageConsumer ic);
+
+ /**
+ * Used to determine if the given <code>ImageConsumer</code> is
+ * already registered with this <code>ImageProducer</code>.
+ */
+ boolean isConsumer(ImageConsumer ic);
+
+ /**
+ * Used to remove an <code>ImageConsumer</code> from the list of
+ * registered consumers for this <code>ImageProducer</code>.
+ */
+ void removeConsumer(ImageConsumer ic);
+
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code> and then immediately start
+ * reconstruction of the image data to be delivered to all
+ * registered consumers.
+ */
+ void startProduction(ImageConsumer ic);
+
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code> and then request that this producer
+ * resend the image data in the order top-down, left-right.
+ */
+ void requestTopDownLeftRightResend(ImageConsumer ic);
+}
+
diff --git a/libjava/classpath/java/awt/image/ImagingOpException.java b/libjava/classpath/java/awt/image/ImagingOpException.java
new file mode 100644
index 0000000..ca40e9e
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ImagingOpException.java
@@ -0,0 +1,66 @@
+/* ImagingOpException.java -- indicates an imaging filter failure
+ Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * This exception is thrown when <code>BufferedImageOp</code> or
+ * <code>RasterOp</code> filters cannot process an image.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see BufferedImageOp
+ * @see RasterOp
+ * @status updated to 1.4
+ */
+public class ImagingOpException extends RuntimeException
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 8026288481846276658L;
+
+ /**
+ * Create a new instance with a descriptive error message.
+ *
+ * @param message the descriptive error message
+ */
+ public ImagingOpException(String message)
+ {
+ super(message);
+ }
+} // class ImagingOpException
diff --git a/libjava/classpath/java/awt/image/IndexColorModel.java b/libjava/classpath/java/awt/image/IndexColorModel.java
new file mode 100644
index 0000000..299b4dc
--- /dev/null
+++ b/libjava/classpath/java/awt/image/IndexColorModel.java
@@ -0,0 +1,697 @@
+/* IndexColorModel.java -- Java class for interpreting Pixel objects
+ Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+import gnu.java.awt.Buffers;
+
+import java.awt.color.ColorSpace;
+import java.math.BigInteger;
+
+/**
+ * Color model similar to pseudo visual in X11.
+ * <br><br>
+ * This color model maps linear pixel values to actual RGB and alpha colors.
+ * Thus, pixel values are indexes into the color map. Each color component is
+ * an 8-bit unsigned value.
+ * <br><br>
+ * The <code>IndexColorModel</code> supports a map of valid pixels, allowing
+ * the representation of holes in the the color map. The valid map is
+ * represented as a {@link BigInteger} where each bit indicates the validity
+ * of the map entry with the same index.
+ * <br><br>
+ * Colors can have alpha components for transparency support. If alpha
+ * component values aren't given, color values are opaque. The model also
+ * supports a reserved pixel value to represent completely transparent colors,
+ * no matter what the actual color component values are.
+ * <br><br>
+ * <code>IndexColorModel</code> supports anywhere from 1 to 16 bit index
+ * values. The allowed transfer types are {@link DataBuffer#TYPE_BYTE} and
+ * {@link DataBuffer#TYPE_USHORT}.
+ *
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public class IndexColorModel extends ColorModel
+{
+ private int map_size;
+ private boolean opaque; // no alpha, but doesn't account for trans
+ private int trans = -1;
+ private int[] rgb;
+ private BigInteger validBits = BigInteger.ZERO;
+
+ /**
+ * Creates a new indexed color model for <code>size</code> color elements
+ * with no alpha component. Each array must contain at least
+ * <code>size</code> elements. For each array, the i-th color is described
+ * by reds[i], greens[i] and blues[i].
+ *
+ * @param bits the number of bits needed to represent <code>size</code>
+ * colors.
+ * @param size the number of colors in the color map.
+ * @param reds the red component of all colors.
+ * @param greens the green component of all colors.
+ * @param blues the blue component of all colors.
+ *
+ * @throws IllegalArgumentException if <code>bits</code> &lt; 1 or
+ * <code>bits</code> &gt; 16.
+ * @throws NullPointerException if any of the arrays is <code>null</code>.
+ * @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater
+ * than the length of the component arrays.
+ */
+ public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
+ byte[] blues)
+ {
+ this(bits, size, reds, greens, blues, (byte[]) null);
+ }
+
+ /**
+ * Creates a new indexed color model for <code>size</code> color elements.
+ * Each array must contain at least <code>size</code> elements. For each
+ * array, the i-th color is described by reds[i], greens[i] and blues[i].
+ * All the colors are opaque except for the transparent color.
+ *
+ * @param bits the number of bits needed to represent <code>size</code>
+ * colors
+ * @param size the number of colors in the color map
+ * @param reds the red component of all colors
+ * @param greens the green component of all colors
+ * @param blues the blue component of all colors
+ * @param trans the index of the transparent color (use -1 for no
+ * transparent color).
+ *
+ * @throws IllegalArgumentException if <code>bits</code> &lt; 1 or
+ * <code>bits</code> &gt; 16.
+ * @throws NullPointerException if any of the arrays is <code>null</code>.
+ * @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater
+ * than the length of the component arrays.
+ */
+ public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
+ byte[] blues, int trans)
+ {
+ super(bits, nArray(8, (0 <= trans && trans < size) ? 4 : 3),
+ ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ (0 <= trans && trans < size), // hasAlpha
+ false, OPAQUE,
+ Buffers.smallestAppropriateTransferType(bits));
+ if (bits < 1)
+ throw new IllegalArgumentException("bits < 1");
+ if (bits > 16)
+ throw new IllegalArgumentException("bits > 16");
+ if (size < 1)
+ throw new IllegalArgumentException("size < 1");
+ map_size = size;
+ if (0 <= trans && trans < size) {
+ this.trans = trans;
+ transparency = BITMASK;
+ }
+ rgb = new int[size];
+ for (int i = 0; i < size; i++)
+ {
+ rgb[i] = (0xff000000
+ | ((reds[i] & 0xff) << 16)
+ | ((greens[i] & 0xff) << 8)
+ | (blues[i] & 0xff));
+ }
+ // Generate a bigint with 1's for every pixel
+ validBits = validBits.setBit(size).subtract(BigInteger.ONE);
+ }
+
+ /**
+ * Creates a new indexed color model for <code>size</code> color elements
+ * including alpha. Each array must contain at least <code>size</code>
+ * elements. For each array, the i-th color is described
+ * by reds[i], greens[i], blues[i] and alphas[i].
+ *
+ * @param bits the number of bits needed to represent <code>size</code>
+ * colors.
+ * @param size the number of colors in the color map.
+ * @param reds the red component of all colors.
+ * @param greens the green component of all colors.
+ * @param blues the blue component of all colors.
+ * @param alphas the alpha component of all colors (<code>null</code>
+ * permitted).
+ *
+ * @throws IllegalArgumentException if <code>bits</code> &lt; 1 or
+ * <code>bits</code> &gt; 16.
+ * @throws NullPointerException if <code>reds</code>, <code>greens</code> or
+ * <code>blues</code> is <code>null</code>.
+ * @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater
+ * than the length of the component arrays.
+ */
+ public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
+ byte[] blues, byte[] alphas)
+ {
+ super(bits, nArray(8, (alphas == null ? 3 : 4)),
+ ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ (alphas != null), false, TRANSLUCENT,
+ Buffers.smallestAppropriateTransferType(bits));
+ if (bits < 1)
+ throw new IllegalArgumentException("bits < 1");
+ if (bits > 16)
+ throw new IllegalArgumentException("bits > 16");
+ if (size < 1)
+ throw new IllegalArgumentException("size < 1");
+ map_size = size;
+ opaque = (alphas == null);
+
+ rgb = new int[size];
+ if (alphas == null)
+ {
+ for (int i = 0; i < size; i++)
+ {
+ rgb[i] = (0xff000000
+ | ((reds[i] & 0xff) << 16)
+ | ((greens[i] & 0xff) << 8)
+ | (blues[i] & 0xff));
+ }
+ transparency = OPAQUE;
+ }
+ else
+ {
+ byte alphaZero = (byte) 0x00;
+ byte alphaOne = (byte) 0xFF;
+ for (int i = 0; i < size; i++)
+ {
+ alphaZero = (byte) (alphaZero | alphas[i]);
+ alphaOne = (byte) (alphaOne & alphas[i]);
+ rgb[i] = ((alphas[i] & 0xff) << 24
+ | ((reds[i] & 0xff) << 16)
+ | ((greens[i] & 0xff) << 8)
+ | (blues[i] & 0xff));
+ }
+ if ((alphaZero == (byte) 0x00) || (alphaOne == (byte) 0xFF))
+ transparency = BITMASK;
+ else
+ transparency = TRANSLUCENT;
+ }
+
+ // Generate a bigint with 1's for every pixel
+ validBits = validBits.setBit(size).subtract(BigInteger.ONE);
+ }
+
+ /**
+ * Creates a new indexed color model using the color components in
+ * <code>cmap</code>. If <code>hasAlpha</code> is <code>true</code> then
+ * <code>cmap</code> contains an alpha component after each of the red, green
+ * and blue components.
+ *
+ * @param bits the number of bits needed to represent <code>size</code>
+ * colors
+ * @param size the number of colors in the color map
+ * @param cmap packed color components
+ * @param start the offset of the first color component in <code>cmap</code>
+ * @param hasAlpha <code>cmap</code> has alpha values
+ * @throws IllegalArgumentException if bits &lt; 1, bits &gt; 16, or size
+ * &lt; 1.
+ * @throws NullPointerException if <code>cmap</code> is <code>null</code>.
+ */
+ public IndexColorModel(int bits, int size, byte[] cmap, int start,
+ boolean hasAlpha)
+ {
+ this(bits, size, cmap, start, hasAlpha, -1);
+ }
+
+ /**
+ * Construct an IndexColorModel from an array of red, green, blue, and
+ * optional alpha components. The component values are interleaved as RGB(A).
+ *
+ * @param bits the number of bits needed to represent <code>size</code>
+ * colors
+ * @param size the number of colors in the color map
+ * @param cmap interleaved color components
+ * @param start the offset of the first color component in <code>cmap</code>
+ * @param hasAlpha <code>cmap</code> has alpha values
+ * @param trans the index of the transparent color
+ * @throws IllegalArgumentException if bits &lt; 1, bits &gt; 16, or size
+ * &lt; 1.
+ * @throws NullPointerException if <code>cmap</code> is <code>null</code>.
+ */
+ public IndexColorModel(int bits, int size, byte[] cmap, int start,
+ boolean hasAlpha, int trans)
+ {
+ super(bits, nArray(8, hasAlpha || (0 <= trans && trans < size) ? 4 : 3),
+ ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ hasAlpha || (0 <= trans && trans < size), false, OPAQUE,
+ Buffers.smallestAppropriateTransferType(bits));
+ if (bits < 1)
+ throw new IllegalArgumentException("bits < 1");
+ if (bits > 16)
+ throw new IllegalArgumentException("bits > 16");
+ if (size < 1)
+ throw new IllegalArgumentException("size < 1");
+ map_size = size;
+ opaque = !hasAlpha;
+ if (0 <= trans && trans < size)
+ this.trans = trans;
+
+ rgb = new int[size];
+ if (hasAlpha)
+ {
+ int alpha;
+ int alphaZero = 0x00; // use to detect all zeros
+ int alphaOne = 0xff; // use to detect all ones
+ for (int i = 0; i < size; i++) {
+ alpha = cmap[4 * i + 3 + start] & 0xff;
+ alphaZero = alphaZero | alpha;
+ alphaOne = alphaOne & alpha;
+ rgb[i] =
+ ( alpha << 24
+ // red
+ | ((cmap[4 * i + start] & 0xff) << 16)
+ // green
+ | ((cmap[4 * i + 1 + start] & 0xff) << 8)
+ // blue
+ | (cmap[4 * i + 2 + start] & 0xff));
+ }
+ if (alphaZero == 0)
+ transparency = BITMASK;
+ else if (alphaOne == 255)
+ transparency = (trans != -1 ? BITMASK : OPAQUE);
+ else
+ transparency = TRANSLUCENT;
+ }
+ else
+ {
+ for (int i = 0; i < size; i++)
+ rgb[i] = (0xff000000
+ // red
+ | ((cmap[3 * i + start] & 0xff) << 16)
+ // green
+ | ((cmap[3 * i + 1 + start] & 0xff) << 8)
+ // blue
+ | (cmap[3 * i + 2 + start] & 0xff));
+ if (trans != -1)
+ transparency = BITMASK;
+ }
+
+ // Generate a bigint with 1's for every pixel
+ validBits = validBits.setBit(size).subtract(BigInteger.ONE);
+ }
+
+ /**
+ * Construct an IndexColorModel from an array of <code>size</code> packed
+ * colors. Each int element contains 8-bit red, green, blue, and optional
+ * alpha values packed in order. If hasAlpha is false, then all the colors
+ * are opaque except for the transparent color.
+ *
+ * @param bits the number of bits needed to represent <code>size</code>
+ * colors
+ * @param size the number of colors in the color map
+ * @param cmap packed color components
+ * @param start the offset of the first color component in <code>cmap</code>
+ * @param hasAlpha <code>cmap</code> has alpha values
+ * @param trans the index of the transparent color
+ * @param transferType {@link DataBuffer#TYPE_BYTE} or
+ {@link DataBuffer#TYPE_USHORT}.
+ * @throws IllegalArgumentException if bits &lt; 1, bits &gt; 16, or size
+ * &lt; 1.
+ * @throws IllegalArgumentException if <code>transferType</code> is something
+ * other than {@link DataBuffer#TYPE_BYTE} or
+ * {@link DataBuffer#TYPE_USHORT}.
+ */
+ public IndexColorModel(int bits, int size, int[] cmap, int start,
+ boolean hasAlpha, int trans, int transferType)
+ {
+ super(bits,
+ nArray(8, 4), // bits for each channel
+ ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
+ true, // has alpha
+ false, // not premultiplied
+ TRANSLUCENT, transferType);
+ if (transferType != DataBuffer.TYPE_BYTE
+ && transferType != DataBuffer.TYPE_USHORT)
+ throw new IllegalArgumentException();
+ if (bits > 16)
+ throw new IllegalArgumentException("bits > 16");
+ if (size < 1)
+ throw new IllegalArgumentException("size < 1");
+ map_size = size;
+ opaque = !hasAlpha;
+ if (0 <= trans && trans < size)
+ this.trans = trans;
+
+ rgb = new int[size];
+ if (!hasAlpha)
+ for (int i = 0; i < size; i++)
+ rgb[i] = cmap[i + start] | 0xff000000;
+ else
+ System.arraycopy(cmap, start, rgb, 0, size);
+
+ // Generate a bigint with 1's for every pixel
+ validBits = validBits.setBit(size).subtract(BigInteger.ONE);
+ }
+
+ /**
+ * Construct an IndexColorModel using a colormap with holes.
+ * <br><br>
+ * The IndexColorModel is built from the array of ints defining the
+ * colormap. Each element contains red, green, blue, and alpha
+ * components. The ColorSpace is sRGB. The transparency value is
+ * automatically determined.
+ * <br><br>
+ * This constructor permits indicating which colormap entries are valid,
+ * using the validBits argument. Each entry in cmap is valid if the
+ * corresponding bit in validBits is set.
+ *
+ * @param bits the number of bits needed to represent <code>size</code>
+ * colors.
+ * @param size the number of colors in the color map.
+ * @param cmap packed color components.
+ * @param start the offset of the first color component in <code>cmap</code>.
+ * @param transferType {@link DataBuffer#TYPE_BYTE} or
+ * {@link DataBuffer#TYPE_USHORT}.
+ * @param validBits a map of the valid entries in <code>cmap</code>.
+ * @throws IllegalArgumentException if bits &lt; 1, bits &gt; 16, or size
+ * &lt; 1.
+ * @throws IllegalArgumentException if transferType is something other than
+ * {@link DataBuffer#TYPE_BYTE} or {@link DataBuffer#TYPE_USHORT}.
+ */
+ public IndexColorModel(int bits, int size, int[] cmap, int start,
+ int transferType, BigInteger validBits)
+ {
+ super(bits, // total bits, sRGB, four channels
+ nArray(8, 4), // bits for each channel
+ ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
+ true, // has alpha
+ false, // not premultiplied
+ TRANSLUCENT, transferType);
+ if (transferType != DataBuffer.TYPE_BYTE
+ && transferType != DataBuffer.TYPE_USHORT)
+ throw new IllegalArgumentException();
+ if (bits > 16)
+ throw new IllegalArgumentException("bits > 16");
+ if (size < 1)
+ throw new IllegalArgumentException("size < 1");
+ map_size = size;
+ opaque = false;
+ this.trans = -1;
+ this.validBits = validBits;
+
+ rgb = new int[size];
+ if (!hasAlpha)
+ for (int i = 0; i < size; i++)
+ rgb[i] = cmap[i + start] | 0xff000000;
+ else
+ System.arraycopy(cmap, start, rgb, 0, size);
+ }
+
+ /**
+ * Returns the size of the color lookup table.
+ *
+ * @return The size of the color lookup table.
+ */
+ public final int getMapSize()
+ {
+ return map_size;
+ }
+
+ /**
+ * Get the index of the transparent color in this color model.
+ *
+ * @return The index of the color that is considered transparent, or -1 if
+ * there is no transparent color.
+ */
+ public final int getTransparentPixel()
+ {
+ return trans;
+ }
+
+ /**
+ * Fills the supplied array with the red component of each color in the
+ * lookup table.
+ *
+ * @param r an array that is at least as large as {@link #getMapSize()}.
+ * @throws NullPointerException if <code>r</code> is <code>null</code>.
+ * @throws ArrayIndexOutOfBoundsException if <code>r</code> has less
+ * than {@link #getMapSize()} elements.
+ */
+ public final void getReds(byte[] r)
+ {
+ int i;
+ for (i = 0; i < map_size; i++)
+ r[i] = (byte) ((0x00FF0000 & rgb[i]) >> 16);
+ }
+
+ /**
+ * Fills the supplied array with the green component of each color in the
+ * lookup table.
+ *
+ * @param g an array that is at least as large as {@link #getMapSize()}.
+ * @throws NullPointerException if <code>g</code> is <code>null</code>.
+ * @throws ArrayIndexOutOfBoundsException if <code>g</code> has less
+ * than {@link #getMapSize()} elements.
+ */
+ public final void getGreens(byte[] g)
+ {
+ int i;
+ for (i = 0; i < map_size; i++)
+ g[i] = (byte) ((0x0000FF00 & rgb[i]) >> 8);
+ }
+
+ /**
+ * Fills the supplied array with the blue component of each color in the
+ * lookup table.
+ *
+ * @param b an array that is at least as large as {@link #getMapSize()}.
+ * @throws NullPointerException if <code>b</code> is <code>null</code>.
+ * @throws ArrayIndexOutOfBoundsException if <code>b</code> has less
+ * than {@link #getMapSize()} elements.
+ */
+ public final void getBlues(byte[] b)
+ {
+ int i;
+ for (i = 0; i < map_size; i++)
+ b[i] = (byte) (0x000000FF & rgb[i]);
+ }
+
+ /**
+ * Fills the supplied array with the alpha component of each color in the
+ * lookup table. If the model has a transparent pixel specified, the alpha
+ * for that pixel will be 0.
+ *
+ * @param a an array that is at least as large as {@link #getMapSize()}.
+ * @throws NullPointerException if <code>a</code> is <code>null</code>.
+ * @throws ArrayIndexOutOfBoundsException if <code>a</code> has less
+ * than {@link #getMapSize()} elements.
+ */
+ public final void getAlphas(byte[] a)
+ {
+ int i;
+ for (i = 0; i < map_size; i++)
+ if (i == trans)
+ a[i] = (byte) 0;
+ else
+ a[i] = (byte) ((0xFF000000 & rgb[i]) >> 24);
+ }
+
+ /**
+ * Returns the red component of the color in the lookup table for the
+ * given pixel value.
+ *
+ * @param pixel the pixel lookup value.
+ *
+ * @return The red component of the color in the lookup table.
+ * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
+ */
+ public final int getRed(int pixel)
+ {
+ if (pixel < map_size)
+ return (0x00FF0000 & rgb[pixel]) >> 16;
+
+ return 0;
+ }
+
+ /**
+ * Returns the green component of the color in the lookup table for the
+ * given pixel value.
+ *
+ * @param pixel the pixel lookup value.
+ *
+ * @return The green component of the color in the lookup table.
+ * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
+ */
+ public final int getGreen(int pixel)
+ {
+ if (pixel < map_size)
+ return (0x0000FF00 & rgb[pixel]) >> 8;
+
+ return 0;
+ }
+
+ /**
+ * Returns the blue component of the color in the lookup table for the
+ * given pixel value.
+ *
+ * @param pixel the pixel lookup value.
+ *
+ * @return The blue component of the color in the lookup table.
+ * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
+ */
+ public final int getBlue(int pixel)
+ {
+ if (pixel < map_size)
+ return 0x000000FF & rgb[pixel];
+
+ return 0;
+ }
+
+ /**
+ * Returns the alpha component of the color in the lookup table for the
+ * given pixel value. If no alpha channel was specified when the color model
+ * was created, then 255 is returned for all pixels except the transparent
+ * pixel (if one is defined - see {@link #getTransparentPixel()}) which
+ * returns an alpha of 0.
+ *
+ * @param pixel the pixel lookup value.
+ *
+ * @return The alpha component of the color in the lookup table (in the
+ * range 0 to 255).
+ * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
+ */
+ public final int getAlpha(int pixel)
+ {
+ if (opaque && pixel != trans)
+ return 255;
+ if ((pixel == trans && trans != -1) || pixel >= map_size)
+ return 0;
+
+ return (0xFF000000 & rgb[pixel]) >> 24;
+ }
+
+ /**
+ * Get the RGB color value of the given pixel using the default
+ * RGB color model.
+ *
+ * @param pixel the pixel lookup value.
+ * @return The RGB color value.
+ * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
+ */
+ public final int getRGB(int pixel)
+ {
+ if (pixel >= 0 && pixel < map_size)
+ return rgb[pixel];
+
+ return 0;
+ }
+
+ /**
+ * Get the RGB color values of all pixels in the map using the default
+ * RGB color model.
+ *
+ * @param rgb The destination array.
+ */
+ public final void getRGBs(int[] rgb)
+ {
+ System.arraycopy(this.rgb, 0, rgb, 0, map_size);
+ }
+
+ /**
+ * Return <code>true</code> if the lookup table contains valid data for
+ * <code>pixel</code>, and <code>false</code> otherwise.
+ *
+ * @param pixel the pixel value used to index the color lookup table.
+ * @return <code>true</code> if <code>pixel</code> is valid,
+ * <code>false</code> otherwise.
+ */
+ public boolean isValid(int pixel)
+ {
+ if (pixel >= 0)
+ return validBits.testBit(pixel);
+ return false;
+ }
+
+ /**
+ * Return <code>true</code> if all pixels are valid, <code>false</code>
+ * otherwise.
+ *
+ * @return <code>true</code> if all pixels are valid, <code>false</code>
+ * otherwise.
+ */
+ public boolean isValid()
+ {
+ // Generate a bigint with 1's for every pixel
+ BigInteger allbits = new BigInteger("0");
+ allbits = allbits.setBit(map_size);
+ allbits = allbits.subtract(new BigInteger("1"));
+ return allbits.equals(validBits);
+ }
+
+ /**
+ * Returns a binary value ({@link BigInteger}) where each bit represents an
+ * entry in the color lookup table. If the bit is on, the entry is valid.
+ *
+ * @return The binary value.
+ */
+ public BigInteger getValidPixels()
+ {
+ return validBits;
+ }
+
+ /**
+ * Construct a {@link BufferedImage} with rgb pixel values from a
+ * {@link Raster}.
+ *
+ * Constructs a new BufferedImage in which each pixel is an RGBA int from
+ * a Raster with index-valued pixels. If this model has no alpha component
+ * or transparent pixel, the type of the new BufferedImage is TYPE_INT_RGB.
+ * Otherwise the type is TYPE_INT_ARGB. If forceARGB is true, the type is
+ * forced to be TYPE_INT_ARGB no matter what.
+ *
+ * @param raster The source of pixel values.
+ * @param forceARGB True if type must be TYPE_INT_ARGB.
+ * @return New BufferedImage with RBGA int pixel values.
+ */
+ public BufferedImage convertToIntDiscrete(Raster raster, boolean forceARGB)
+ {
+ int type = forceARGB ? BufferedImage.TYPE_INT_ARGB
+ : ((opaque && trans == -1) ? BufferedImage.TYPE_INT_RGB :
+ BufferedImage.TYPE_INT_ARGB);
+
+ // FIXME: assuming that raster has only 1 band since pixels are supposed
+ // to be int indexes.
+ // FIXME: it would likely be more efficient to fetch a complete array,
+ // but it would take much more memory.
+ // FIXME: I'm not sure if transparent pixels or alpha values need special
+ // handling here.
+ BufferedImage im = new BufferedImage(raster.width, raster.height, type);
+ for (int x = raster.minX; x < raster.width + raster.minX; x++)
+ for (int y = raster.minY; y < raster.height + raster.minY; y++)
+ im.setRGB(x, y, rgb[raster.getSample(x, y, 0)]);
+
+ return im;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/Kernel.java b/libjava/classpath/java/awt/image/Kernel.java
new file mode 100644
index 0000000..f7c29c3
--- /dev/null
+++ b/libjava/classpath/java/awt/image/Kernel.java
@@ -0,0 +1,143 @@
+/* Kernel.java -- Java class for an image processing kernel
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * Kernel represents an image processing kernel. It gets used to hold
+ * convolution filters among other purposes. It stores an array of float
+ * values representing a 2-dimensional array in row-major order.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ * @version 1.0
+ */
+public class Kernel implements Cloneable
+{
+ private final int width;
+ private final int height;
+ private final float[] data;
+
+ /**
+ * Creates a new <code>Kernel</code> instance.
+ *
+ * @param width The 2D width of data.
+ * @param height The 2D height of data.
+ * @param data The source data array.
+ * @exception IllegalArgumentException if width * height < data.length.
+ */
+ public Kernel(int width, int height, float[] data)
+ throws IllegalArgumentException
+ {
+ this.width = width;
+ this.height = height;
+ if (data.length < width * height || width < 0 || height < 0)
+ throw new IllegalArgumentException();
+ this.data = new float[width * height];
+ System.arraycopy(data, 0, this.data, 0, width * height);
+ }
+
+ /**
+ * Return the X origin: (width - 1) / 2
+ */
+ public final int getXOrigin()
+ {
+ return (width - 1) / 2;
+ }
+
+ /**
+ * Return the Y origin: (height - 1) / 2
+ */
+ public final int getYOrigin()
+ {
+ return (height - 1) / 2;
+ }
+
+ /**
+ * @return The kernel width.
+ */
+ public final int getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * @return The kernel height.
+ */
+ public final int getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Return the kernel data.
+ *
+ * If data is null, allocates a new array and returns it. Otherwise, the
+ * kernel values are copied into data.
+ *
+ * @param data Array to copy values into, or null.
+ * @return The array with copied values.
+ * @exception IllegalArgumentException if data != null and too small.
+ */
+ public final float[] getKernelData(float[] data)
+ throws IllegalArgumentException
+ {
+ if (data == null)
+ return (float[])this.data.clone();
+
+ if (data.length < this.data.length)
+ throw new IllegalArgumentException();
+
+ System.arraycopy(this.data, 0, data, 0, this.data.length);
+ return data;
+ }
+
+ /**
+ * @return a clone of this Kernel.
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // Impossible
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/image/LookupOp.java b/libjava/classpath/java/awt/image/LookupOp.java
new file mode 100644
index 0000000..f131daa
--- /dev/null
+++ b/libjava/classpath/java/awt/image/LookupOp.java
@@ -0,0 +1,252 @@
+/* LookupOp.java -- Filter that converts each pixel using a lookup table.
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * LookupOp is a filter that converts each pixel using a lookup table.
+ *
+ * For filtering Rasters, the lookup table must have either one component
+ * that is applied to all bands, or one component for every band in the
+ * Rasters.
+ *
+ * For BufferedImages, the lookup table may apply to both color and alpha
+ * components. If the lookup table contains one component, or if there are
+ * the same number of components as color components in the source, the table
+ * applies to all color components. Otherwise the table applies to all
+ * components including alpha. Alpha premultiplication is ignored during the
+ * lookup filtering.
+ *
+ * After filtering, if color conversion is necessary, the conversion happens,
+ * taking alpha premultiplication into account.
+ *
+ * @author jlquinn
+ */
+public class LookupOp implements BufferedImageOp, RasterOp
+{
+ private LookupTable lut;
+ private RenderingHints hints;
+
+ /** Construct a new LookupOp.
+ *
+ * @param lookup LookupTable to use.
+ * @param hints Rendering hints (can be null).
+ */
+ public LookupOp(LookupTable lookup, RenderingHints hints)
+ {
+ lut = lookup;
+ this.hints = hints;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage, java.awt.image.BufferedImage)
+ */
+ public BufferedImage filter(BufferedImage src, BufferedImage dst)
+ {
+ if (src.getColorModel() instanceof IndexColorModel)
+ throw new IllegalArgumentException("LookupOp.filter: IndexColorModel "
+ + "not allowed");
+ if (dst == null)
+ dst = createCompatibleDestImage(src, src.getColorModel());
+
+ // Set up for potential colormodel mismatch
+ BufferedImage tgt;
+ if (dst.getColorModel().equals(src.getColorModel()))
+ tgt = dst;
+ else
+ tgt = createCompatibleDestImage(src, src.getColorModel());
+
+ Raster sr = src.getRaster();
+ WritableRaster dr = tgt.getRaster();
+
+ if (src.getColorModel().hasAlpha() &&
+ (lut.getNumComponents() == 1 ||
+ lut.getNumComponents() == src.getColorModel().getNumColorComponents()))
+ {
+ // Need to ignore alpha for lookup
+ int[] dbuf = new int[src.getColorModel().getNumComponents()];
+ int tmpBands = src.getColorModel().getNumColorComponents();
+ int[] tmp = new int[tmpBands];
+
+ // Filter the pixels
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ {
+ // Filter only color components, but also copy alpha
+ sr.getPixel(x, y, dbuf);
+ System.arraycopy(dbuf, 0, tmp, 0, tmpBands);
+ dr.setPixel(x, y, lut.lookupPixel(tmp, dbuf));
+ }
+ }
+ else if (lut.getNumComponents() != 1
+ &&
+ lut.getNumComponents() != src.getColorModel().getNumComponents())
+ throw new IllegalArgumentException("LookupOp.filter: "
+ + "Incompatible lookup "
+ + "table and source image");
+
+ // No alpha to ignore
+ int[] dbuf = new int[src.getColorModel().getNumComponents()];
+
+ // Filter the pixels
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ dr.setPixel(x, y, lut.lookupPixel(sr.getPixel(x, y, dbuf), dbuf));
+
+ if (tgt != dst)
+ {
+ // Convert between color models.
+ // TODO Check that premultiplied alpha is handled correctly here.
+ Graphics2D gg = dst.createGraphics();
+ gg.setRenderingHints(hints);
+ gg.drawImage(tgt, 0, 0, null);
+ gg.dispose();
+ }
+
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
+ */
+ public Rectangle2D getBounds2D(BufferedImage src)
+ {
+ return src.getRaster().getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
+ */
+ public BufferedImage createCompatibleDestImage(BufferedImage src,
+ ColorModel dstCM)
+ {
+ // FIXME: set properties to those in src
+ return new BufferedImage(dstCM,
+ src.getRaster().createCompatibleWritableRaster(),
+ src.isPremultiplied, null);
+ }
+
+ /** Return corresponding destination point for source point.
+ *
+ * LookupOp will return the value of src unchanged.
+ * @param src The source point.
+ * @param dst The destination point.
+ * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
+ */
+ public Point2D getPoint2D(Point2D src, Point2D dst)
+ {
+ if (dst == null)
+ return (Point2D) src.clone();
+
+ dst.setLocation(src);
+ return dst;
+ }
+
+ /** Return the LookupTable for this op. */
+ public LookupTable getTable()
+ {
+ return lut;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getRenderingHints()
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /** Filter a raster through a lookup table.
+ *
+ * Applies the lookup table for this Rasterop to each pixel of src and
+ * puts the results in dest. If dest is null, a new Raster is created and
+ * returned.
+ *
+ * @param src The source raster.
+ * @param dest The destination raster.
+ * @return The WritableRaster with the filtered pixels.
+ * @throws IllegalArgumentException if lookup table has more than one
+ * component but not the same as src and dest.
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
+ */
+ public WritableRaster filter(Raster src, WritableRaster dest)
+ {
+ if (dest == null)
+ // Allocate a raster if needed
+ dest = createCompatibleDestRaster(src);
+ else
+ if (src.getNumBands() != dest.getNumBands())
+ throw new IllegalArgumentException();
+
+ if (lut.getNumComponents() != 1
+ && lut.getNumComponents() != src.getNumBands())
+ throw new IllegalArgumentException();
+
+
+ // Allocate pixel storage.
+ int[] tmp = new int[src.getNumBands()];
+
+ // Filter the pixels
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ dest.setPixel(x, y, lut.lookupPixel(src.getPixel(x, y, tmp), tmp));
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return src.createCompatibleWritableRaster();
+ }
+
+}
diff --git a/libjava/classpath/java/awt/image/LookupTable.java b/libjava/classpath/java/awt/image/LookupTable.java
new file mode 100644
index 0000000..f814b8e
--- /dev/null
+++ b/libjava/classpath/java/awt/image/LookupTable.java
@@ -0,0 +1,109 @@
+/* LookupTable.java -- Java class for a pixel translation table.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * LookupTable represents translation arrays for pixel values. It wraps one
+ * or more data arrays for each layer (or component) in an image, such as
+ * Alpha, R, G, and B. When doing translation, the offset is subtracted from
+ * the pixel values to allow a subset of an array to be used.
+ *
+ * @see ByteLookupTable
+ * @see ShortLookupTable
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ * @version 1.0
+ */
+public abstract class LookupTable
+{
+ // Not protected since that's part of the public API.
+ int offset;
+ int numComponents;
+
+ /**
+ * Creates a new <code>LookupTable</code> instance.
+ *
+ * If numComponents is 1, the same translation table is used for all pixel
+ * components.
+ *
+ * @param offset Offset to be subtracted.
+ * @param numComponents Number of image components.
+ * @exception IllegalArgumentException if offset < 0 or numComponents < 1.
+ */
+ protected LookupTable(int offset, int numComponents)
+ throws IllegalArgumentException
+ {
+ if (offset < 0 || numComponents < 1)
+ throw new IllegalArgumentException();
+ this.offset = offset;
+ this.numComponents = numComponents;
+ }
+
+ /** Return the number of components. */
+ public int getNumComponents()
+ {
+ return numComponents;
+ }
+
+ /** Return the offset. */
+ public int getOffset()
+ {
+ return offset;
+ }
+
+
+ /**
+ * Return translated values for a pixel.
+ *
+ * For each value in the pixel src, use the value minus offset as an index
+ * in the component array and copy the value there to the output for the
+ * component. If dest is null, the output is a new array, otherwise the
+ * translated values are written to dest. Dest can be the same array as
+ * src.
+ *
+ * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+ * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+ * translation arrays.
+ *
+ * @param src Component values of a pixel.
+ * @param dest Destination array for values, or null.
+ * @return Translated values for the pixel.
+ */
+ public abstract int[] lookupPixel(int[] src, int[] dest);
+}
diff --git a/libjava/classpath/java/awt/image/MemoryImageSource.java b/libjava/classpath/java/awt/image/MemoryImageSource.java
new file mode 100644
index 0000000..c27e0bf
--- /dev/null
+++ b/libjava/classpath/java/awt/image/MemoryImageSource.java
@@ -0,0 +1,373 @@
+/* MemoryImageSource.java -- Java class for providing image data
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+public class MemoryImageSource implements ImageProducer
+{
+ private boolean animated = false;
+ private boolean fullbuffers = false;
+ private int[] pixeli;
+ private int width;
+ private int height;
+ private int offset;
+ private int scansize;
+ private byte[] pixelb;
+ private ColorModel cm;
+ private Hashtable props = new Hashtable();
+ private Vector consumers = new Vector();
+
+ /**
+ * Construct an image producer that reads image data from a byte
+ * array.
+ *
+ * @param w width of image
+ * @param h height of image
+ * @param cm the color model used to represent pixel values
+ * @param pix a byte array of pixel values
+ * @param off the offset into the array at which the first pixel is stored
+ * @param scan the number of array elements that represents a single pixel row
+ */
+ public MemoryImageSource(int w, int h, ColorModel cm, byte[] pix, int off,
+ int scan)
+ {
+ this(w, h, cm, pix, off, scan, null);
+ }
+
+ /**
+ * Constructs an ImageProducer from memory
+ */
+ public MemoryImageSource(int w, int h, ColorModel cm, byte[] pix, int off,
+ int scan, Hashtable props)
+ {
+ width = w;
+ height = h;
+ this.cm = cm;
+ offset = off;
+ scansize = scan;
+ this.props = props;
+ int max = ((scansize > width) ? scansize : width);
+ pixelb = pix;
+ }
+
+ /**
+ * Construct an image producer that reads image data from an
+ * integer array.
+ *
+ * @param w width of image
+ * @param h height of image
+ * @param cm the color model used to represent pixel values
+ * @param pix an integer array of pixel values
+ * @param off the offset into the array at which the first pixel is stored
+ * @param scan the number of array elements that represents a single pixel row
+ */
+ public MemoryImageSource(int w, int h, ColorModel cm, int[] pix, int off,
+ int scan)
+ {
+ this(w, h, cm, pix, off, scan, null);
+ }
+
+ /**
+ Constructs an ImageProducer from memory
+ */
+ public MemoryImageSource(int w, int h, ColorModel cm, int[] pix, int off,
+ int scan, Hashtable props)
+ {
+ width = w;
+ height = h;
+ this.cm = cm;
+ offset = off;
+ scansize = scan;
+ this.props = props;
+ int max = ((scansize > width) ? scansize : width);
+ pixeli = pix;
+ }
+
+ /**
+ * Constructs an ImageProducer from memory using the default RGB ColorModel
+ */
+ public MemoryImageSource(int w, int h, int[] pix, int off, int scan,
+ Hashtable props)
+ {
+ this(w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
+ }
+
+ /**
+ * Constructs an ImageProducer from memory using the default RGB ColorModel
+ */
+ public MemoryImageSource(int w, int h, int[] pix, int off, int scan)
+ {
+ this(w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
+ }
+
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code>.
+ */
+ public synchronized void addConsumer(ImageConsumer ic)
+ {
+ if (consumers.contains(ic))
+ return;
+
+ consumers.addElement(ic);
+ }
+
+ /**
+ * Used to determine if the given <code>ImageConsumer</code> is
+ * already registered with this <code>ImageProducer</code>.
+ */
+ public synchronized boolean isConsumer(ImageConsumer ic)
+ {
+ if (consumers.contains(ic))
+ return true;
+ return false;
+ }
+
+ /**
+ * Used to remove an <code>ImageConsumer</code> from the list of
+ * registered consumers for this <code>ImageProducer</code>.
+ */
+ public synchronized void removeConsumer(ImageConsumer ic)
+ {
+ consumers.removeElement(ic);
+ }
+
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code> and then immediately start
+ * reconstruction of the image data to be delivered to all
+ * registered consumers.
+ */
+ public void startProduction(ImageConsumer ic)
+ {
+ if (! (consumers.contains(ic)))
+ consumers.addElement(ic);
+
+ Vector list = (Vector) consumers.clone();
+ for (int i = 0; i < list.size(); i++)
+ {
+ ic = (ImageConsumer) list.elementAt(i);
+ sendPicture(ic);
+ if (animated)
+ ic.imageComplete(ImageConsumer.SINGLEFRAME);
+ else
+ ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
+ }
+ }
+
+ /**
+ * Used to register an <code>ImageConsumer</code> with this
+ * <code>ImageProducer</code> and then request that this producer
+ * resend the image data in the order top-down, left-right.
+ */
+ public void requestTopDownLeftRightResend(ImageConsumer ic)
+ {
+ startProduction(ic);
+ }
+
+ /**
+ * Changes a flag to indicate whether this MemoryImageSource supports
+ * animations.
+ *
+ * @param animated A flag indicating whether this class supports animations
+ */
+ public synchronized void setAnimated(boolean animated)
+ {
+ this.animated = animated;
+ }
+
+ /**
+ * A flag to indicate whether or not to send full buffer updates when
+ * sending animation. If this flag is set then full buffers are sent
+ * in the newPixels methods instead of just regions.
+ *
+ * @param fullbuffers - a flag indicating whether to send the full buffers
+ */
+ public synchronized void setFullBufferUpdates(boolean fullbuffers)
+ {
+ this.fullbuffers = fullbuffers;
+ }
+
+ /**
+ * Send an animation frame to the image consumers.
+ */
+ public void newPixels()
+ {
+ if (animated == true)
+ {
+ ImageConsumer ic;
+ Vector list = (Vector) consumers.clone();
+ for (int i = 0; i < list.size(); i++)
+ {
+ ic = (ImageConsumer) list.elementAt(i);
+ sendPicture(ic);
+ ic.imageComplete(ImageConsumer.SINGLEFRAME);
+ }
+ }
+ }
+
+ private void sendPicture(ImageConsumer ic)
+ {
+ ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT);
+ if (props != null)
+ ic.setProperties(props);
+ ic.setDimensions(width, height);
+ ic.setColorModel(cm);
+ if (pixeli != null)
+ ic.setPixels(0, 0, width, height, cm, pixeli, offset, scansize);
+ else
+ ic.setPixels(0, 0, width, height, cm, pixelb, offset, scansize);
+ }
+
+ /**
+ * Send an animation frame to the image consumers containing the specified
+ * pixels unless setFullBufferUpdates is set.
+ */
+ public synchronized void newPixels(int x, int y, int w, int h)
+ {
+ if (animated == true)
+ {
+ if (fullbuffers)
+ newPixels();
+ else
+ {
+ ImageConsumer ic;
+ Vector list = (Vector) consumers.clone();
+ for (int i = 0; i < list.size(); i++)
+ {
+ ic = (ImageConsumer) list.elementAt(i);
+ ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT);
+ if (props != null)
+ ic.setProperties(props);
+ if (pixeli != null)
+ {
+ int[] pixelbuf = new int[w * h];
+ for (int row = y; row < y + h; row++)
+ System.arraycopy(pixeli, row * scansize + x + offset,
+ pixelbuf, 0, w * h);
+ ic.setPixels(x, y, w, h, cm, pixelbuf, 0, w);
+ }
+ else
+ {
+ byte[] pixelbuf = new byte[w * h];
+ for (int row = y; row < y + h; row++)
+ System.arraycopy(pixelb, row * scansize + x + offset,
+ pixelbuf, 0, w * h);
+
+ ic.setPixels(x, y, w, h, cm, pixelbuf, 0, w);
+ }
+ ic.imageComplete(ImageConsumer.SINGLEFRAME);
+ }
+ }
+ }
+ }
+
+ /**
+ * Send an animation frame to the image consumers containing the specified
+ * pixels unless setFullBufferUpdates is set.
+ *
+ * If framenotify is set then a notification is sent when the frame
+ * is sent otherwise no status is sent.
+ */
+ public synchronized void newPixels(int x, int y, int w, int h,
+ boolean framenotify)
+ {
+ if (animated == true)
+ {
+ if (fullbuffers)
+ newPixels();
+ else
+ {
+ ImageConsumer ic;
+ Vector list = (Vector) consumers.clone();
+ for (int i = 0; i < list.size(); i++)
+ {
+ ic = (ImageConsumer) list.elementAt(i);
+ ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT);
+ if (props != null)
+ ic.setProperties(props);
+ if (pixeli != null)
+ {
+ int[] pixelbuf = new int[w * h];
+ for (int row = y; row < y + h; row++)
+ System.arraycopy(pixeli, row * scansize + x + offset,
+ pixelbuf, 0, w * h);
+ ic.setPixels(x, y, w, h, cm, pixelbuf, 0, w);
+ }
+ else
+ {
+ byte[] pixelbuf = new byte[w * h];
+ for (int row = y; row < y + h; row++)
+ System.arraycopy(pixelb, row * scansize + x + offset,
+ pixelbuf, 0, w * h);
+ ic.setPixels(x, y, w, h, cm, pixelbuf, 0, w);
+ }
+ if (framenotify == true)
+ ic.imageComplete(ImageConsumer.SINGLEFRAME);
+ }
+ }
+ }
+ }
+
+ public synchronized void newPixels(byte[] newpix, ColorModel newmodel,
+ int offset, int scansize)
+ {
+ pixeli = null;
+ pixelb = newpix;
+ cm = newmodel;
+ this.offset = offset;
+ this.scansize = scansize;
+ if (animated == true)
+ newPixels();
+ }
+
+ public synchronized void newPixels(int[] newpix, ColorModel newmodel,
+ int offset, int scansize)
+ {
+ pixelb = null;
+ pixeli = newpix;
+ cm = newmodel;
+ this.offset = offset;
+ this.scansize = scansize;
+ if (animated == true)
+ newPixels();
+ }
+}
diff --git a/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java b/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java
new file mode 100644
index 0000000..18a6e55
--- /dev/null
+++ b/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java
@@ -0,0 +1,388 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+import gnu.java.awt.Buffers;
+
+/**
+ * MultiPixelPackedSampleModel provides a single band model that supports
+ * multiple pixels in a single unit. Pixels have 2^n bits and 2^k pixels fit
+ * per data element.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ */
+public class MultiPixelPackedSampleModel extends SampleModel
+{
+ private int scanlineStride;
+ private int[] bitMasks;
+ private int[] bitOffsets;
+ private int[] sampleSize;
+ private int dataBitOffset;
+ private int elemBits;
+ private int numberOfBits;
+ private int numElems;
+
+ public MultiPixelPackedSampleModel(int dataType, int w, int h,
+ int numberOfBits)
+ {
+ this(dataType, w, h, numberOfBits, 0, 0);
+ }
+
+ public MultiPixelPackedSampleModel(int dataType, int w, int h,
+ int numberOfBits, int scanlineStride,
+ int dataBitOffset)
+ {
+ super(dataType, w, h, 1);
+
+ switch (dataType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ elemBits = 8;
+ break;
+ case DataBuffer.TYPE_USHORT:
+ elemBits = 16;
+ break;
+ case DataBuffer.TYPE_INT:
+ elemBits = 32;
+ break;
+ default:
+ throw new IllegalArgumentException("MultiPixelPackedSampleModel"
+ + " unsupported dataType");
+ }
+
+ this.dataBitOffset = dataBitOffset;
+
+ this.numberOfBits = numberOfBits;
+ if (numberOfBits > elemBits)
+ throw new RasterFormatException("MultiPixelPackedSampleModel pixel size"
+ + " larger than dataType");
+ switch (numberOfBits)
+ {
+ case 1: case 2: case 4: case 8: case 16: case 32: break;
+ default:
+ throw new RasterFormatException("MultiPixelPackedSampleModel pixel"
+ + " size not 2^n bits");
+ }
+ numElems = elemBits / numberOfBits;
+
+ // Compute scan line large enough for w pixels.
+ if (scanlineStride == 0)
+ scanlineStride = ((dataBitOffset + w * numberOfBits) / elemBits);
+ this.scanlineStride = scanlineStride;
+
+
+ sampleSize = new int[1];
+ sampleSize[0] = numberOfBits;
+
+ bitMasks = new int[numElems];
+ bitOffsets = new int[numElems];
+ for (int i=0; i < numElems; i++)
+ {
+ bitOffsets[numElems - i- 1] = numberOfBits * i;
+ bitMasks[numElems - i - 1] = ((1 << numberOfBits) - 1) <<
+ bitOffsets[numElems - i - 1];
+ }
+ }
+
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ /* FIXME: We can avoid recalculation of bit offsets and sample
+ sizes here by passing these from the current instance to a
+ special private constructor. */
+ return new MultiPixelPackedSampleModel(dataType, w, h, numberOfBits);
+ }
+
+
+ /**
+ * Creates a DataBuffer for holding pixel data in the format and
+ * layout described by this SampleModel. The returned buffer will
+ * consist of one single bank.
+ */
+ public DataBuffer createDataBuffer()
+ {
+ int size;
+
+ // FIXME: The comment refers to SinglePixelPackedSampleModel. See if the
+ // same can be done for MultiPixelPackedSampleModel.
+ // We can save (scanlineStride - width) pixels at the very end of
+ // the buffer. The Sun reference implementation (J2SE 1.3.1 and
+ // 1.4.1_01) seems to do this; tested with Mauve test code.
+ size = scanlineStride * height;
+
+ return Buffers.createBuffer(getDataType(), size);
+ }
+
+
+ public int getNumDataElements()
+ {
+ return 1;
+ }
+
+ public int[] getSampleSize()
+ {
+ return sampleSize;
+ }
+
+ public int getSampleSize(int band)
+ {
+ return sampleSize[0];
+ }
+
+ public int getOffset(int x, int y)
+ {
+ return scanlineStride * y + ((dataBitOffset + x*numberOfBits) / elemBits);
+ }
+
+ public int getBitOffset(int x)
+ {
+ return (dataBitOffset + x*numberOfBits) % elemBits;
+ }
+
+ public int getDataBitOffset()
+ {
+ return dataBitOffset;
+ }
+
+ public int getScanlineStride()
+ {
+ return scanlineStride;
+ }
+
+ public int getPixelBitStride()
+ {
+ return numberOfBits;
+ }
+
+
+ public SampleModel createSubsetSampleModel(int[] bands)
+ {
+ int numBands = bands.length;
+ if (numBands != 1)
+ throw new RasterFormatException("MultiPixelPackedSampleModel only"
+ + " supports one band");
+
+ return new MultiPixelPackedSampleModel(dataType, width, height,
+ numberOfBits, scanlineStride,
+ dataBitOffset);
+ }
+
+ /**
+ * Extract one pixel and return in an array of transfer type.
+ *
+ * Extracts the pixel at x, y from data and stores into the 0th index of the
+ * array obj, since there is only one band. If obj is null, a new array of
+ * getTransferType() is created.
+ *
+ * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ * @see java.awt.image.SampleModel#getDataElements(int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public Object getDataElements(int x, int y, Object obj,
+ DataBuffer data)
+ {
+ int pixel = getSample(x, y, 0, data);
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ if (obj == null) obj = new byte[1];
+ ((byte[])obj)[0] = (byte)pixel;
+ return obj;
+ case DataBuffer.TYPE_USHORT:
+ if (obj == null) obj = new short[1];
+ ((short[])obj)[0] = (short)pixel;
+ return obj;
+ case DataBuffer.TYPE_INT:
+ if (obj == null) obj = new int[1];
+ ((int[])obj)[0] = pixel;
+ return obj;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+ }
+
+ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[1];
+ iArray[0] = getSample(x, y, 0, data);
+
+ return iArray;
+ }
+
+ public int[] getPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int offset = getOffset(x, y);
+ if (iArray == null) iArray = new int[w*h];
+ int outOffset = 0;
+ for (y=0; y<h; y++)
+ {
+ int lineOffset = offset;
+ for (x=0; x<w;)
+ {
+ int samples = data.getElem(lineOffset++);
+ for (int b=0; b<numElems && x<w; b++)
+ {
+ iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
+ x++;
+ }
+ }
+ offset += scanlineStride;
+ }
+ return iArray;
+ }
+
+ public int getSample(int x, int y, int b, DataBuffer data)
+ {
+ int pos =
+ ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
+ int offset = getOffset(x, y);
+ int samples = data.getElem(offset);
+ return (samples & bitMasks[pos]) >>> bitOffsets[pos];
+ }
+
+ /**
+ * Set the pixel at x, y to the value in the first element of the primitive
+ * array obj.
+ *
+ * @param x The x-coordinate of the data elements in <code>obj</code>.
+ * @param y The y-coordinate of the data elements in <code>obj</code>.
+ * @param obj The primitive array containing the data elements to set.
+ * @param data The DataBuffer to store the data elements into.
+ * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public void setDataElements(int x, int y, Object obj, DataBuffer data)
+ {
+ int transferType = getTransferType();
+ if (getTransferType() != data.getDataType())
+ {
+ throw new IllegalArgumentException("transfer type ("+
+ getTransferType()+"), "+
+ "does not match data "+
+ "buffer type (" +
+ data.getDataType() +
+ ").");
+ }
+
+ int offset = getOffset(x, y);
+
+ try
+ {
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ DataBufferByte out = (DataBufferByte) data;
+ byte[] in = (byte[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ DataBufferUShort out = (DataBufferUShort) data;
+ short[] in = (short[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ DataBufferInt out = (DataBufferInt) data;
+ int[] in = (int[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ default:
+ throw new ClassCastException("Unsupported data type");
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException aioobe)
+ {
+ String msg = "While writing data elements" +
+ ", x="+x+", y="+y+
+ ", width="+width+", height="+height+
+ ", scanlineStride="+scanlineStride+
+ ", offset="+offset+
+ ", data.getSize()="+data.getSize()+
+ ", data.getOffset()="+data.getOffset()+
+ ": " +
+ aioobe;
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+ }
+
+ public void setPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ setSample(x, y, 0, iArray[0], data);
+ }
+
+ public void setSample(int x, int y, int b, int s, DataBuffer data)
+ {
+ int bitpos =
+ ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
+ int offset = getOffset(x, y);
+
+ s = s << bitOffsets[bitpos];
+ s = s & bitMasks[bitpos];
+
+ int sample = data.getElem(offset);
+ sample |= s;
+ data.setElem(offset, sample);
+ }
+
+ /**
+ * Creates a String with some information about this SampleModel.
+ * @return A String describing this SampleModel.
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+ result.append(getClass().getName());
+ result.append("[");
+ result.append("scanlineStride=").append(scanlineStride);
+ for(int i=0; i < bitMasks.length; i+=1)
+ {
+ result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+ }
+
+ result.append("]");
+ return result.toString();
+ }
+}
diff --git a/libjava/classpath/java/awt/image/PackedColorModel.java b/libjava/classpath/java/awt/image/PackedColorModel.java
new file mode 100644
index 0000000..894e6e6
--- /dev/null
+++ b/libjava/classpath/java/awt/image/PackedColorModel.java
@@ -0,0 +1,192 @@
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import gnu.java.awt.BitMaskExtent;
+
+import java.awt.Point;
+import java.awt.color.ColorSpace;
+
+/**
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public abstract class PackedColorModel extends ColorModel
+{
+ private int masks[];
+
+ /* Package accessibility, the DirectColorModel needs this array */
+ int shifts[];
+
+ public PackedColorModel(ColorSpace cspace, int pixelBits,
+ int[] colorMaskArray, int alphaMask,
+ boolean isAlphaPremultiplied,
+ int transparency,
+ int transferType)
+ {
+ super(pixelBits, calcBitsPerComponent(colorMaskArray, alphaMask),
+ cspace, (alphaMask != 0), isAlphaPremultiplied, transparency,
+ transferType);
+ initMasks(colorMaskArray, alphaMask);
+ if ((pixelBits<1) || (pixelBits>32)) {
+ throw new IllegalArgumentException("pixels per bits must be " +
+ "in the range [1, 32]");
+ }
+ }
+
+ private static int[] calcBitsPerComponent(int[] colorMaskArray,
+ int alphaMask)
+ {
+ int numComponents = colorMaskArray.length;
+ if (alphaMask != 0) numComponents++;
+
+ int[] bitsPerComponent = new int[numComponents];
+
+ BitMaskExtent extent = new BitMaskExtent();
+ for (int b=0; b<colorMaskArray.length; b++)
+ {
+ extent.setMask(colorMaskArray[b]);
+ bitsPerComponent[b] = extent.bitWidth;
+ }
+ if (alphaMask != 0)
+ {
+ extent.setMask(alphaMask);
+ bitsPerComponent[numComponents-1] = extent.bitWidth;
+ }
+ return bitsPerComponent;
+ }
+
+ /** Initializes the masks.
+ *
+ * @return an array containing the number of bits per color
+ * component.
+ */
+ private void initMasks(int[] colorMaskArray, int alphaMask)
+ {
+ int numComponents = colorMaskArray.length;
+ if (alphaMask == 0)
+ {
+ masks = colorMaskArray;
+ }
+ else
+ {
+ masks = new int[numComponents+1];
+ System.arraycopy(colorMaskArray, 0,
+ masks, 0,
+ numComponents);
+ masks[numComponents++] = alphaMask;
+ }
+
+ shifts = new int[numComponents];
+
+ // Bit field handling have been moved to a utility class
+ BitMaskExtent extent = new BitMaskExtent();
+ for (int b=0; b<numComponents; b++)
+ {
+ extent.setMask(masks[b]);
+ shifts[b] = extent.leastSignificantBit;
+ }
+ }
+
+ public PackedColorModel(ColorSpace cspace, int pixelBits,
+ int rmask, int gmask, int bmask,
+ int amask, boolean isAlphaPremultiplied,
+ int transparency,
+ int transferType)
+ {
+ this(cspace, pixelBits, makeColorMaskArray(rmask, gmask, bmask),
+ amask, isAlphaPremultiplied, transparency, transferType);
+ }
+
+ /* TODO: If there is a alpha mask, it is inefficient to create a
+ color mask array that will be discarded when the alpha mask is
+ appended. We should probably create a private constructor that
+ takes a complete array of masks (color+alpha) as an
+ argument. */
+
+ private static int[] makeColorMaskArray(int rmask, int gmask, int bmask)
+ {
+ int[] colorMaskArray = { rmask, gmask, bmask };
+ return colorMaskArray;
+ }
+
+ public final int getMask(int index)
+ {
+ return masks[index];
+ }
+
+ public final int[] getMasks()
+ {
+ return masks;
+ }
+
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ return new SinglePixelPackedSampleModel(transferType, w, h, masks);
+ }
+
+ public boolean isCompatibleSampleModel(SampleModel sm)
+ {
+ if (!super.isCompatibleSampleModel(sm)) return false;
+ if (!(sm instanceof SinglePixelPackedSampleModel)) return false;
+
+ SinglePixelPackedSampleModel sppsm =
+ (SinglePixelPackedSampleModel) sm;
+ return java.util.Arrays.equals(sppsm.getBitMasks(), masks);
+ }
+
+ public WritableRaster getAlphaRaster(WritableRaster raster) {
+ if (!hasAlpha()) return null;
+
+ SampleModel sm = raster.getSampleModel();
+ int[] alphaBand = { sm.getNumBands() - 1 };
+ SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
+ DataBuffer buffer = raster.getDataBuffer();
+ Point origin = new Point(0, 0);
+ return Raster.createWritableRaster(alphaModel, buffer, origin);
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!super.equals(obj)) return false;
+ if (!(obj instanceof PackedColorModel)) return false;
+
+ PackedColorModel other = (PackedColorModel) obj;
+
+ return java.util.Arrays.equals(masks, other.masks);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/PixelGrabber.java b/libjava/classpath/java/awt/image/PixelGrabber.java
new file mode 100644
index 0000000..b576dbf
--- /dev/null
+++ b/libjava/classpath/java/awt/image/PixelGrabber.java
@@ -0,0 +1,618 @@
+/* PixelGrabber.java -- retrieve a subset of an image's data
+ Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Image;
+import java.util.Hashtable;
+
+/**
+ * PixelGrabber is an ImageConsumer that extracts a rectangular region
+ * of pixels from an Image.
+ */
+public class PixelGrabber implements ImageConsumer
+{
+ int x, y, offset;
+ int width = -1;
+ int height = -1;
+ int scansize = -1;
+ boolean forceRGB = true;
+
+ ColorModel model = ColorModel.getRGBdefault();
+ int hints;
+ Hashtable props;
+
+ int int_pixel_buffer[];
+ boolean ints_delivered = false;
+ byte byte_pixel_buffer[];
+ boolean bytes_delivered = false;
+
+ ImageProducer ip;
+ int observerStatus;
+ int consumerStatus;
+
+ private Thread grabberThread;
+ boolean grabbing = false;
+
+ /**
+ * Construct a PixelGrabber that will retrieve RGB data from a given
+ * Image.
+ *
+ * The RGB data will be retrieved from a rectangular region
+ * <code>(x, y, w, h)</code> within the image. The data will be
+ * stored in the provided <code>pix</code> array, which must have
+ * been initialized to a size of at least <code>w * h</code>. The
+ * data for a pixel (m, n) in the grab rectangle will be stored at
+ * <code>pix[(n - y) * scansize + (m - x) + off]</code>.
+ *
+ * @param img the Image from which to grab pixels
+ * @param x the x coordinate, relative to <code>img</code>'s
+ * top-left corner, of the grab rectangle's top-left pixel
+ * @param y the y coordinate, relative to <code>img</code>'s
+ * top-left corner, of the grab rectangle's top-left pixel
+ * @param w the width of the grab rectangle, in pixels
+ * @param h the height of the grab rectangle, in pixels
+ * @param pix the array in which to store grabbed RGB pixel data
+ * @param off the offset into the <code>pix</code> array at which to
+ * start storing RGB data
+ * @param scansize a set of <code>scansize</code> consecutive
+ * elements in the <code>pix</code> array represents one row of
+ * pixels in the grab rectangle
+ */
+ public PixelGrabber(Image img, int x, int y, int w, int h,
+ int pix[], int off, int scansize)
+ {
+ this (img.getSource(), x, y, w, h, pix, off, scansize);
+ }
+
+ /**
+ * Construct a PixelGrabber that will retrieve RGB data from a given
+ * ImageProducer.
+ *
+ * The RGB data will be retrieved from a rectangular region
+ * <code>(x, y, w, h)</code> within the image produced by
+ * <code>ip</code>. The data will be stored in the provided
+ * <code>pix</code> array, which must have been initialized to a
+ * size of at least <code>w * h</code>. The data for a pixel (m, n)
+ * in the grab rectangle will be stored at
+ * <code>pix[(n - y) * scansize + (m - x) + off]</code>.
+ *
+ * @param ip the ImageProducer from which to grab pixels
+ * @param x the x coordinate of the grab rectangle's top-left pixel,
+ * specified relative to the top-left corner of the image produced
+ * by <code>ip</code>
+ * @param y the y coordinate of the grab rectangle's top-left pixel,
+ * specified relative to the top-left corner of the image produced
+ * by <code>ip</code>
+ * @param w the width of the grab rectangle, in pixels
+ * @param h the height of the grab rectangle, in pixels
+ * @param pix the array in which to store grabbed RGB pixel data
+ * @param off the offset into the <code>pix</code> array at which to
+ * start storing RGB data
+ * @param scansize a set of <code>scansize</code> consecutive
+ * elements in the <code>pix</code> array represents one row of
+ * pixels in the grab rectangle
+ */
+ public PixelGrabber(ImageProducer ip, int x, int y, int w, int h,
+ int pix[], int off, int scansize)
+ {
+ this.ip = ip;
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ this.offset = off;
+ this.scansize = scansize;
+
+ int_pixel_buffer = pix;
+ // Initialize the byte array in case ip sends us byte-formatted
+ // pixel data.
+ byte_pixel_buffer = new byte[pix.length * 4];
+ }
+
+ /**
+ * Construct a PixelGrabber that will retrieve data from a given
+ * Image.
+ *
+ * The RGB data will be retrieved from a rectangular region
+ * <code>(x, y, w, h)</code> within the image. The data will be
+ * stored in an internal array which can be accessed by calling
+ * <code>getPixels</code>. The data for a pixel (m, n) in the grab
+ * rectangle will be stored in the returned array at index
+ * <code>(n - y) * scansize + (m - x) + off</code>.
+ * If forceRGB is false, then the returned data will be not be
+ * converted to RGB from its format in <code>img</code>.
+ *
+ * If <code>w</code> is negative, the width of the grab region will
+ * be from x to the right edge of the image. Likewise, if
+ * <code>h</code> is negative, the height of the grab region will be
+ * from y to the bottom edge of the image.
+ *
+ * @param img the Image from which to grab pixels
+ * @param x the x coordinate, relative to <code>img</code>'s
+ * top-left corner, of the grab rectangle's top-left pixel
+ * @param y the y coordinate, relative to <code>img</code>'s
+ * top-left corner, of the grab rectangle's top-left pixel
+ * @param w the width of the grab rectangle, in pixels
+ * @param h the height of the grab rectangle, in pixels
+ * @param forceRGB true to force conversion of the rectangular
+ * region's pixel data to RGB
+ */
+ public PixelGrabber(Image img,
+ int x, int y,
+ int w, int h,
+ boolean forceRGB)
+ {
+ this.ip = img.getSource();
+ this.x = x;
+ this.y = y;
+ width = w;
+ height = h;
+ // If width or height is negative, postpone pixel buffer
+ // initialization until setDimensions is called back by ip.
+ if (width >= 0 && height >= 0)
+ {
+ int_pixel_buffer = new int[width * height];
+ byte_pixel_buffer = new byte[width * height];
+ }
+ this.forceRGB = forceRGB;
+ }
+
+ /**
+ * Start grabbing pixels.
+ *
+ * Spawns an image production thread that calls back to this
+ * PixelGrabber's ImageConsumer methods.
+ */
+ public synchronized void startGrabbing()
+ {
+ // Make sure we're not already grabbing.
+ if (grabbing == false)
+ {
+ grabbing = true;
+ grabberThread = new Thread ()
+ {
+ public void run ()
+ {
+ ip.startProduction (PixelGrabber.this);
+ }
+ };
+ grabberThread.start ();
+ }
+ }
+
+ /**
+ * Abort pixel grabbing.
+ */
+ public synchronized void abortGrabbing()
+ {
+ if (grabbing)
+ {
+ // Interrupt the grabbing thread.
+ Thread moribund = grabberThread;
+ grabberThread = null;
+ moribund.interrupt();
+
+ imageComplete (ImageConsumer.IMAGEABORTED);
+ }
+ }
+
+ /**
+ * Have our Image or ImageProducer start sending us pixels via our
+ * ImageConsumer methods and wait for all pixels in the grab
+ * rectangle to be delivered.
+ *
+ * @return true if successful, false on abort or error
+ *
+ * @throws InterruptedException if interrupted by another thread.
+ */
+ public synchronized boolean grabPixels() throws InterruptedException
+ {
+ return grabPixels(0);
+ }
+
+ /**
+ * grabPixels's behavior depends on the value of <code>ms</code>.
+ *
+ * If ms < 0, return true if all pixels from the source image have
+ * been delivered, false otherwise. Do not wait.
+ *
+ * If ms >= 0 then we request that our Image or ImageProducer start
+ * delivering pixels to us via our ImageConsumer methods.
+ *
+ * If ms > 0, wait at most <code>ms</code> milliseconds for
+ * delivery of all pixels within the grab rectangle.
+ *
+ * If ms == 0, wait until all pixels have been delivered.
+ *
+ * @return true if all pixels from the source image have been
+ * delivered, false otherwise
+ *
+ * @throws InterruptedException if this thread is interrupted while
+ * we are waiting for pixels to be delivered
+ */
+ public synchronized boolean grabPixels(long ms) throws InterruptedException
+ {
+ if (ms < 0)
+ return ((observerStatus & (ImageObserver.FRAMEBITS
+ | ImageObserver.ALLBITS)) != 0);
+
+ // Spawn a new ImageProducer thread to send us the image data via
+ // our ImageConsumer methods.
+ startGrabbing();
+
+ if (ms > 0)
+ {
+ long stop_time = System.currentTimeMillis() + ms;
+ long time_remaining;
+ while (grabbing)
+ {
+ time_remaining = stop_time - System.currentTimeMillis();
+ if (time_remaining <= 0)
+ break;
+ wait (time_remaining);
+ }
+ abortGrabbing ();
+ }
+ else
+ wait ();
+
+ // If consumerStatus is non-zero then the image is done loading or
+ // an error has occurred.
+ if (consumerStatus != 0)
+ return setObserverStatus ();
+
+ return ((observerStatus & (ImageObserver.FRAMEBITS
+ | ImageObserver.ALLBITS)) != 0);
+ }
+
+ // Set observer status flags based on the current consumer status
+ // flags. Return true if the consumer flags indicate that the
+ // image was loaded successfully, or false otherwise.
+ private synchronized boolean setObserverStatus ()
+ {
+ boolean retval = false;
+
+ if ((consumerStatus & IMAGEERROR) != 0)
+ observerStatus |= ImageObserver.ERROR;
+
+ if ((consumerStatus & IMAGEABORTED) != 0)
+ observerStatus |= ImageObserver.ABORT;
+
+ if ((consumerStatus & STATICIMAGEDONE) != 0)
+ {
+ observerStatus |= ImageObserver.ALLBITS;
+ retval = true;
+ }
+
+ if ((consumerStatus & SINGLEFRAMEDONE) != 0)
+ {
+ observerStatus |= ImageObserver.FRAMEBITS;
+ retval = true;
+ }
+
+ return retval;
+ }
+
+ /**
+ * @return the status of the pixel grabbing thread, represented by a
+ * bitwise OR of ImageObserver flags
+ */
+ public synchronized int getStatus()
+ {
+ return observerStatus;
+ }
+
+ /**
+ * @return the width of the grab rectangle in pixels, or a negative
+ * number if the ImageProducer has not yet called our setDimensions
+ * method
+ */
+ public synchronized int getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * @return the height of the grab rectangle in pixels, or a negative
+ * number if the ImageProducer has not yet called our setDimensions
+ * method
+ */
+ public synchronized int getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * @return a byte array of pixel data if ImageProducer delivered
+ * pixel data using the byte[] variant of setPixels, or an int array
+ * otherwise
+ */
+ public synchronized Object getPixels()
+ {
+ if (ints_delivered)
+ return int_pixel_buffer;
+ else if (bytes_delivered)
+ return byte_pixel_buffer;
+ else
+ return null;
+ }
+
+ /**
+ * @return the ColorModel currently being used for the majority of
+ * pixel data conversions
+ */
+ public synchronized ColorModel getColorModel()
+ {
+ return model;
+ }
+
+ /**
+ * Our <code>ImageProducer</code> calls this method to indicate the
+ * size of the image being produced.
+ *
+ * setDimensions is an ImageConsumer method. None of PixelGrabber's
+ * ImageConsumer methods should be called by code that instantiates
+ * a PixelGrabber. They are only made public so they can be called
+ * by the PixelGrabber's ImageProducer.
+ *
+ * @param width the width of the image
+ * @param height the height of the image
+ */
+ public synchronized void setDimensions(int width, int height)
+ {
+ // Our width wasn't set when we were constructed. Set our width
+ // so that the grab region includes all pixels from x to the right
+ // edge of the source image.
+ if (this.width < 0)
+ this.width = width - x;
+
+ // Our height wasn't set when we were constructed. Set our height
+ // so that the grab region includes all pixels from y to the
+ // bottom edge of the source image.
+ if (this.height < 0)
+ this.height = height - y;
+
+ if (scansize < 0)
+ scansize = this.width;
+
+ if (int_pixel_buffer == null)
+ int_pixel_buffer = new int[this.width * this.height];
+
+ if (byte_pixel_buffer == null)
+ byte_pixel_buffer = new byte[this.width * this.height];
+ }
+
+ /**
+ * Our <code>ImageProducer</code> may call this method to send us a
+ * list of its image's properties.
+ *
+ * setProperties is an ImageConsumer method. None of PixelGrabber's
+ * ImageConsumer methods should be called by code that instantiates
+ * a PixelGrabber. They are only made public so they can be called
+ * by the PixelGrabber's ImageProducer.
+ *
+ * @param props a list of properties associated with the image being
+ * produced
+ */
+ public synchronized void setProperties(Hashtable props)
+ {
+ this.props = props;
+ }
+
+ /**
+ * Our ImageProducer will call <code>setColorModel</code> to
+ * indicate the model used by the majority of calls to
+ * <code>setPixels</code>. Each call to <code>setPixels</code>
+ * could however indicate a different <code>ColorModel</code>.
+ *
+ * setColorModel is an ImageConsumer method. None of PixelGrabber's
+ * ImageConsumer methods should be called by code that instantiates
+ * a PixelGrabber. They are only made public so they can be called
+ * by the PixelGrabber's ImageProducer.
+ *
+ * @param model the color model to be used most often by setPixels
+ *
+ * @see ColorModel
+ */
+ public synchronized void setColorModel(ColorModel model)
+ {
+ this.model = model;
+ }
+
+ /**
+ * Our <code>ImageProducer</code> may call this method with a
+ * bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
+ * <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
+ * <code>SINGLEPASS</code>, <code>SINGLEFRAME</code>.
+ *
+ * setHints is an ImageConsumer method. None of PixelGrabber's
+ * ImageConsumer methods should be called by code that instantiates
+ * a PixelGrabber. They are only made public so they can be called
+ * by the PixelGrabber's ImageProducer.
+ *
+ * @param flags a bit mask of hints
+ */
+ public synchronized void setHints(int flags)
+ {
+ hints = flags;
+ }
+
+ /**
+ * Our ImageProducer calls setPixels to deliver a subset of its
+ * pixels.
+ *
+ * Each element of the pixels array represents one pixel. The
+ * pixel data is formatted according to the color model model.
+ * The x and y parameters are the coordinates of the rectangular
+ * region of pixels being delivered to this ImageConsumer,
+ * specified relative to the top left corner of the image being
+ * produced. Likewise, w and h are the pixel region's dimensions.
+ *
+ * @param x x coordinate of pixel block
+ * @param y y coordinate of pixel block
+ * @param w width of pixel block
+ * @param h height of pixel block
+ * @param model color model used to interpret pixel data
+ * @param pixels pixel block data
+ * @param offset offset into pixels array
+ * @param scansize width of one row in the pixel block
+ */
+ public synchronized void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels,
+ int offset, int scansize)
+ {
+ ColorModel currentModel;
+ if (model != null)
+ currentModel = model;
+ else
+ currentModel = this.model;
+
+ for(int yp = y; yp < (y + h); yp++)
+ {
+ for(int xp = x; xp < (x + w); xp++)
+ {
+ // Check if the coordinates (xp, yp) are within the
+ // pixel block that we are grabbing.
+ if(xp >= this.x
+ && yp >= this.y
+ && xp < (this.x + this.width)
+ && yp < (this.y + this.height))
+ {
+ int i = (yp - this.y) * this.scansize + (xp - this.x) + this.offset;
+ int p = (yp - y) * scansize + (xp - x) + offset;
+ if (forceRGB)
+ {
+ ints_delivered = true;
+
+ int_pixel_buffer[i] = currentModel.getRGB (pixels[p] & 0xFF);
+ }
+ else
+ {
+ bytes_delivered = true;
+
+ byte_pixel_buffer[i] = pixels[p];
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Our ImageProducer calls setPixels to deliver a subset of its
+ * pixels.
+ *
+ * Each element of the pixels array represents one pixel. The
+ * pixel data is formatted according to the color model model.
+ * The x and y parameters are the coordinates of the rectangular
+ * region of pixels being delivered to this ImageConsumer,
+ * specified relative to the top left corner of the image being
+ * produced. Likewise, w and h are the pixel region's dimensions.
+ *
+ * @param x x coordinate of pixel block
+ * @param y y coordinate of pixel block
+ * @param w width of pixel block
+ * @param h height of pixel block
+ * @param model color model used to interpret pixel data
+ * @param pixels pixel block data
+ * @param offset offset into pixels array
+ * @param scansize width of one row in the pixel block
+ */
+ public synchronized void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels,
+ int offset, int scansize)
+ {
+ ColorModel currentModel;
+ if (model != null)
+ currentModel = model;
+ else
+ currentModel = this.model;
+
+ ints_delivered = true;
+
+ for(int yp = y; yp < (y + h); yp++)
+ {
+ for(int xp = x; xp < (x + w); xp++)
+ {
+ // Check if the coordinates (xp, yp) are within the
+ // pixel block that we are grabbing.
+ if(xp >= this.x
+ && yp >= this.y
+ && xp < (this.x + this.width)
+ && yp < (this.y + this.height))
+ {
+ int i = (yp - this.y) * this.scansize + (xp - this.x) + this.offset;
+ int p = (yp - y) * scansize + (xp - x) + offset;
+ if (forceRGB)
+ int_pixel_buffer[i] = currentModel.getRGB (pixels[p]);
+ else
+ int_pixel_buffer[i] = pixels[p];
+ }
+ }
+ }
+ }
+
+ /**
+ * Our <code>ImageProducer</code> calls this method to inform us
+ * that a single frame or the entire image is complete. The method
+ * is also used to inform us of an error in loading or producing the
+ * image.
+ *
+ * @param status the status of image production, represented by a
+ * bitwise OR of ImageConsumer flags
+ */
+ public synchronized void imageComplete(int status)
+ {
+ consumerStatus = status;
+ setObserverStatus ();
+ grabbing = false;
+ ip.removeConsumer (this);
+
+ notifyAll ();
+ }
+
+ /**
+ * @return the return value of getStatus
+ *
+ * @specnote The newer getStatus should be used in place of status.
+ */
+ public synchronized int status()
+ {
+ return getStatus();
+ }
+}
diff --git a/libjava/classpath/java/awt/image/PixelInterleavedSampleModel.java b/libjava/classpath/java/awt/image/PixelInterleavedSampleModel.java
new file mode 100644
index 0000000..4c5c436
--- /dev/null
+++ b/libjava/classpath/java/awt/image/PixelInterleavedSampleModel.java
@@ -0,0 +1,98 @@
+/* PixelInterleavedSampleModel.java
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+
+/**
+ * A <code>SampleModel</code> that uses exactly one element of the
+ * raster&#x2019;s {@link DataBuffer} per pixel, holds all bands in a
+ * single bank, and stores band data in pixel-interleaved manner.
+ *
+ * @since 1.2
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public class PixelInterleavedSampleModel
+ extends ComponentSampleModel
+{
+ public PixelInterleavedSampleModel(int dataType, int width, int height,
+ int pixelStride, int scanlineStride,
+ int[] bandOffsets)
+ {
+ super(dataType, width, height, pixelStride, scanlineStride,
+ bandOffsets);
+ }
+
+
+ /**
+ * Creates a new <code>SampleModel</code> that is like this one, but
+ * uses the specified width and height.
+ *
+ * @param width the number of pixels in the horizontal direction.
+ *
+ * @param height the number of pixels in the vertical direction.
+ */
+ public SampleModel createCompatibleSampleModel(int width, int height)
+ {
+ return new PixelInterleavedSampleModel(dataType, width, height,
+ pixelStride, scanlineStride,
+ bandOffsets);
+ }
+
+
+ /**
+ * Creates a new <code>SampleModel</code> that is like this one, but
+ * uses only a subset of its bands.
+ *
+ * @param bands an array whose elements indicate which bands shall
+ * be part of the subset. For example, <code>[0, 2, 3]</code> would
+ * create a SampleModel containing bands #0, #2 and #3.
+ */
+ public SampleModel createSubsetSampleModel(int[] bands)
+ {
+ int[] subOffsets;
+
+ subOffsets = new int[bands.length];
+ for (int i = 0; i < bands.length; i++)
+ subOffsets[i] = bandOffsets[bands[i]];
+
+ return new PixelInterleavedSampleModel(dataType, width, height,
+ pixelStride, scanlineStride,
+ subOffsets);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/RGBImageFilter.java b/libjava/classpath/java/awt/image/RGBImageFilter.java
new file mode 100644
index 0000000..f7b39b9
--- /dev/null
+++ b/libjava/classpath/java/awt/image/RGBImageFilter.java
@@ -0,0 +1,267 @@
+/* RGBImageFilter.java -- Java class for filtering Pixels by RGB values
+ Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * A filter designed to filter images in the default RGBColorModel regardless of
+ * the ImageProducer's ColorModel.
+ *
+ * @author Mark Benvenuto (mcb54@columbia.edu)
+ */
+public abstract class RGBImageFilter extends ImageFilter
+{
+ protected ColorModel origmodel;
+
+ protected ColorModel newmodel;
+
+ /**
+ Specifies whether to apply the filter to the index entries of the
+ IndexColorModel. Subclasses should set this to true if the filter
+ does not depend on the pixel's coordinate.
+ */
+ protected boolean canFilterIndexColorModel = false;
+
+ /**
+ Construct new RGBImageFilter.
+ */
+ public RGBImageFilter()
+ {
+ }
+
+ /**
+ * Sets the ColorModel used to filter with. If the specified ColorModel is IndexColorModel
+ * and canFilterIndexColorModel is true, we subsitute the ColorModel for a filtered one
+ * here and in setPixels whenever the original one appears. Otherwise overrides the default
+ * ColorModel of ImageProducer and specifies the default RGBColorModel
+ *
+ * @param model the color model to be used most often by setPixels
+ * @see ColorModel */
+ public void setColorModel(ColorModel model)
+ {
+ origmodel = model;
+ newmodel = model;
+
+ if( ( model instanceof IndexColorModel) && canFilterIndexColorModel ) {
+ newmodel = filterIndexColorModel( (IndexColorModel) model );
+ consumer.setColorModel(newmodel);
+ }
+ else {
+ consumer.setColorModel(ColorModel.getRGBdefault());
+ }
+ }
+
+ /**
+ Registers a new ColorModel to subsitute for the old ColorModel when
+ setPixels encounters the a pixel with the old ColorModel. The pixel
+ remains unchanged except for a new ColorModel.
+
+ @param oldcm the old ColorModel
+ @param newcm the new ColorModel
+ */
+ public void substituteColorModel(ColorModel oldcm,
+ ColorModel newcm)
+ {
+ origmodel = oldcm;
+ newmodel = newcm;
+ }
+
+ /**
+ Filters an IndexColorModel through the filterRGB function. Uses
+ coordinates of -1 to indicate its filtering an index and not a pixel.
+
+ @param icm an IndexColorModel to filter
+ */
+ public IndexColorModel filterIndexColorModel(IndexColorModel icm)
+ {
+ int len = icm.getMapSize(), rgb;
+ byte reds[] = new byte[len], greens[] = new byte[len], blues[] = new byte[len], alphas[] = new byte[len];
+
+ icm.getAlphas( alphas );
+ icm.getReds( reds );
+ icm.getGreens( greens );
+ icm.getBlues( blues );
+
+ for( int i = 0; i < len; i++ )
+ {
+ rgb = filterRGB( -1, -1, makeColor ( alphas[i], reds[i], greens[i], blues[i] ) );
+ alphas[i] = (byte)(( 0xff000000 & rgb ) >> 24);
+ reds[i] = (byte)(( 0xff0000 & rgb ) >> 16);
+ greens[i] = (byte)(( 0xff00 & rgb ) >> 8);
+ blues[i] = (byte)(0xff & rgb);
+ }
+ return new IndexColorModel( icm.getPixelSize(), len, reds, greens, blues, alphas );
+ }
+
+ private int makeColor( byte a, byte r, byte g, byte b )
+ {
+ return ( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b );
+ }
+
+ /**
+ This functions filters a set of RGB pixels through filterRGB.
+
+ @param x the x coordinate of the rectangle
+ @param y the y coordinate of the rectangle
+ @param w the width of the rectangle
+ @param h the height of the rectangle
+ @param pixels the array of pixel values
+ @param offset the index of the first pixels in the <code>pixels</code> array
+ @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void filterRGBPixels(int x, int y, int w, int h, int[] pixels,
+ int offset, int scansize)
+ {
+ for (int yp = 0; yp < h; yp++)
+ {
+ for (int xp = 0; xp < w; xp++)
+ {
+ pixels[offset + xp] = filterRGB(xp + x, yp + y, pixels[offset + xp]);
+ }
+ offset += scansize;
+ }
+ }
+
+
+ /**
+ * If the ColorModel is the same ColorModel which as already converted
+ * then it converts it the converted ColorModel. Otherwise it passes the
+ * array of pixels through filterRGBpixels.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels,
+ int offset, int scansize)
+ {
+ if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
+ {
+ consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
+ }
+ else
+ {
+ int intPixels[] =
+ convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
+ filterRGBPixels( x, y, w, h, intPixels, offset, scansize );
+ consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), intPixels, offset, scansize);
+ }
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as an <code>int</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels,
+ int offset, int scansize)
+ {
+ if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
+ {
+ consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
+ }
+ else
+ {
+ //FIXME: Store the filtered pixels in a separate temporary buffer?
+ convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
+ filterRGBPixels( x, y, w, h, pixels, offset, scansize );
+ consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, offset, scansize);
+ }
+ }
+
+ private int[] convertColorModelToDefault(int x, int y, int w, int h,
+ ColorModel model, byte pixels[],
+ int offset, int scansize)
+ {
+ int intPixels[] = new int[pixels.length];
+ for (int i = 0; i < pixels.length; i++)
+ intPixels[i] = makeColorbyDefaultCM(model, pixels[i]);
+ return intPixels;
+ }
+
+ private void convertColorModelToDefault(int x, int y, int w, int h,
+ ColorModel model, int pixels[],
+ int offset, int scansize)
+ {
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = makeColorbyDefaultCM(model, pixels[i]);
+ }
+
+ private int makeColorbyDefaultCM(ColorModel model, byte rgb)
+ {
+ return makeColor( model.getAlpha( rgb ) * 4, model.getRed( rgb ) * 4, model.getGreen( rgb ) * 4, model.getBlue( rgb ) * 4 );
+ }
+
+ private int makeColorbyDefaultCM(ColorModel model, int rgb)
+ {
+ return makeColor( model.getAlpha( rgb ), model.getRed( rgb ), model.getGreen( rgb ), model.getBlue( rgb ) );
+ }
+
+ private int makeColor( int a, int r, int g, int b )
+ {
+ return (int)( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b );
+ }
+
+
+ /**
+ Filters a single pixel from the default ColorModel.
+
+ @param x x-coordinate
+ @param y y-coordinate
+ @param rgb color
+ */
+ public abstract int filterRGB(int x,
+ int y,
+ int rgb);
+}
diff --git a/libjava/classpath/java/awt/image/Raster.java b/libjava/classpath/java/awt/image/Raster.java
new file mode 100644
index 0000000..4af958a
--- /dev/null
+++ b/libjava/classpath/java/awt/image/Raster.java
@@ -0,0 +1,546 @@
+/* Copyright (C) 2000, 2002, 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+/**
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public class Raster
+{
+ protected SampleModel sampleModel;
+ protected DataBuffer dataBuffer;
+ protected int minX;
+ protected int minY;
+ protected int width;
+ protected int height;
+ protected int sampleModelTranslateX;
+ protected int sampleModelTranslateY;
+ protected int numBands;
+ protected int numDataElements;
+ protected Raster parent;
+
+ protected Raster(SampleModel sampleModel, Point origin)
+ {
+ this(sampleModel, sampleModel.createDataBuffer(), origin);
+ }
+
+ protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
+ Point origin)
+ {
+ this(sampleModel, dataBuffer,
+ new Rectangle(origin.x, origin.y,
+ sampleModel.getWidth(), sampleModel.getHeight()),
+ origin, null);
+ }
+
+ protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
+ Rectangle aRegion,
+ Point sampleModelTranslate, Raster parent)
+ {
+ this.sampleModel = sampleModel;
+ this.dataBuffer = dataBuffer;
+ this.minX = aRegion.x;
+ this.minY = aRegion.y;
+ this.width = aRegion.width;
+ this.height = aRegion.height;
+
+ // If sampleModelTranslate is null, use (0,0). Methods such as
+ // Raster.createRaster are specified to allow for a null argument.
+ if (sampleModelTranslate != null)
+ {
+ this.sampleModelTranslateX = sampleModelTranslate.x;
+ this.sampleModelTranslateY = sampleModelTranslate.y;
+ }
+
+ this.numBands = sampleModel.getNumBands();
+ this.numDataElements = sampleModel.getNumDataElements();
+ this.parent = parent;
+ }
+
+ public static WritableRaster createInterleavedRaster(int dataType,
+ int w, int h,
+ int bands,
+ Point location)
+ {
+ int[] bandOffsets = new int[bands];
+ // TODO: Maybe not generate this every time.
+ for (int b=0; b<bands; b++) bandOffsets[b] = b;
+
+ int scanlineStride = bands*w;
+ return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
+ bandOffsets, location);
+ }
+
+ public static WritableRaster createInterleavedRaster(int dataType,
+ int w, int h,
+ int scanlineStride,
+ int pixelStride,
+ int[] bandOffsets,
+ Point location)
+ {
+ SampleModel sm = new ComponentSampleModel(dataType,
+ w, h,
+ pixelStride,
+ scanlineStride,
+ bandOffsets);
+ return createWritableRaster(sm, location);
+ }
+
+ public static WritableRaster createBandedRaster(int dataType,
+ int w, int h, int bands,
+ Point location)
+ {
+ SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
+ return createWritableRaster(sm, location);
+ }
+
+ public static WritableRaster createBandedRaster(int dataType,
+ int w, int h,
+ int scanlineStride,
+ int[] bankIndices,
+ int[] bandOffsets,
+ Point location)
+ {
+ SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
+ bankIndices, bandOffsets);
+ return createWritableRaster(sm, location);
+ }
+
+ public static WritableRaster createPackedRaster(int dataType,
+ int w, int h,
+ int[] bandMasks,
+ Point location)
+ {
+ SampleModel sm = new SinglePixelPackedSampleModel(dataType,
+ w, h,
+ bandMasks);
+ return createWritableRaster(sm, location);
+ }
+
+ public static WritableRaster createPackedRaster(int dataType,
+ int w, int h,
+ int bands, int bitsPerBand,
+ Point location)
+ {
+ if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
+ throw new IllegalArgumentException();
+
+ SampleModel sm;
+
+ if (bands == 1)
+ sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
+ else
+ {
+ int[] bandMasks = new int[bands];
+ int mask = 0x1;
+ for (int bits = bitsPerBand; --bits != 0;)
+ mask = (mask << 1) | 0x1;
+ for (int i = 0; i < bands; i++)
+ {
+ bandMasks[i] = mask;
+ mask <<= bitsPerBand;
+ }
+
+ sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
+ }
+ return createWritableRaster(sm, location);
+ }
+
+ public static WritableRaster
+ createInterleavedRaster(DataBuffer dataBuffer, int w, int h,
+ int scanlineStride, int pixelStride,
+ int[] bandOffsets, Point location)
+ {
+ SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
+ w, h,
+ scanlineStride,
+ pixelStride,
+ bandOffsets);
+ return createWritableRaster(sm, dataBuffer, location);
+ }
+
+ public static
+ WritableRaster createBandedRaster(DataBuffer dataBuffer,
+ int w, int h,
+ int scanlineStride,
+ int[] bankIndices,
+ int[] bandOffsets,
+ Point location)
+ {
+ SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
+ w, h, scanlineStride,
+ bankIndices, bandOffsets);
+ return createWritableRaster(sm, dataBuffer, location);
+ }
+
+ public static WritableRaster
+ createPackedRaster(DataBuffer dataBuffer,
+ int w, int h,
+ int scanlineStride,
+ int[] bandMasks,
+ Point location)
+ {
+ SampleModel sm =
+ new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
+ w, h,
+ scanlineStride,
+ bandMasks);
+ return createWritableRaster(sm, dataBuffer, location);
+ }
+
+ public static WritableRaster
+ createPackedRaster(DataBuffer dataBuffer,
+ int w, int h,
+ int bitsPerPixel,
+ Point location)
+ {
+ SampleModel sm =
+ new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
+ w, h,
+ bitsPerPixel);
+ return createWritableRaster(sm, dataBuffer, location);
+ }
+
+ public static Raster createRaster(SampleModel sm, DataBuffer db,
+ Point location)
+ {
+ return new Raster(sm, db, location);
+ }
+
+ public static WritableRaster createWritableRaster(SampleModel sm,
+ Point location)
+ {
+ return new WritableRaster(sm, location);
+ }
+
+ public static WritableRaster createWritableRaster(SampleModel sm,
+ DataBuffer db,
+ Point location)
+ {
+ return new WritableRaster(sm, db, location);
+ }
+
+ public Raster getParent()
+ {
+ return parent;
+ }
+
+ public final int getSampleModelTranslateX()
+ {
+ return sampleModelTranslateX;
+ }
+
+ public final int getSampleModelTranslateY()
+ {
+ return sampleModelTranslateY;
+ }
+
+ public WritableRaster createCompatibleWritableRaster()
+ {
+ return new WritableRaster(getSampleModel(), new Point(minX, minY));
+ }
+
+ public WritableRaster createCompatibleWritableRaster(int w, int h)
+ {
+ return createCompatibleWritableRaster(minX, minY, w, h);
+ }
+
+ public WritableRaster createCompatibleWritableRaster(Rectangle rect)
+ {
+ return createCompatibleWritableRaster(rect.x, rect.y,
+ rect.width, rect.height);
+ }
+
+ public WritableRaster createCompatibleWritableRaster(int x, int y,
+ int w, int h)
+ {
+ SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
+ return new WritableRaster(sm, sm.createDataBuffer(),
+ new Point(x, y));
+ }
+
+ public Raster createTranslatedChild(int childMinX, int childMinY) {
+ int tcx = sampleModelTranslateX - minX + childMinX;
+ int tcy = sampleModelTranslateY - minY + childMinY;
+
+ return new Raster(sampleModel, dataBuffer,
+ new Rectangle(childMinX, childMinY,
+ width, height),
+ new Point(tcx, tcy),
+ this);
+ }
+
+ public Raster createChild(int parentX, int parentY, int width,
+ int height, int childMinX, int childMinY,
+ int[] bandList)
+ {
+ /* FIXME: Throw RasterFormatException if child bounds extends
+ beyond the bounds of this raster. */
+
+ SampleModel sm = (bandList == null) ?
+ sampleModel :
+ sampleModel.createSubsetSampleModel(bandList);
+
+ /*
+ data origin
+ /
+ +-------------------------
+ |\. __ parent trans
+ | \`.
+ | \ `. parent origin
+ | \ `. /
+ | /\ +-------- - -
+ |trans\ /<\-- deltaTrans
+ |child +-+-\---- - -
+ | /|`| \__ parent [x, y]
+ |child | |`. \
+ |origin| : `.\
+ | | / `\
+ | : / +
+ | child [x, y]
+
+ parent_xy - parent_trans = child_xy - child_trans
+
+ child_trans = parent_trans + child_xy - parent_xy
+ */
+
+ return new Raster(sm, dataBuffer,
+ new Rectangle(childMinX, childMinY,
+ width, height),
+ new Point(sampleModelTranslateX+childMinX-parentX,
+ sampleModelTranslateY+childMinY-parentY),
+ this);
+ }
+
+ public Rectangle getBounds()
+ {
+ return new Rectangle(minX, minY, width, height);
+ }
+
+ public final int getMinX()
+ {
+ return minX;
+ }
+
+ public final int getMinY()
+ {
+ return minY;
+ }
+
+ public final int getWidth()
+ {
+ return width;
+ }
+
+ public final int getHeight()
+ {
+ return height;
+ }
+
+ public final int getNumBands()
+ {
+ return numBands;
+ }
+
+ public final int getNumDataElements()
+ {
+ return numDataElements;
+ }
+
+ public final int getTransferType()
+ {
+ return sampleModel.getTransferType();
+ }
+
+ public DataBuffer getDataBuffer()
+ {
+ return dataBuffer;
+ }
+
+ public SampleModel getSampleModel()
+ {
+ return sampleModel;
+ }
+
+ public Object getDataElements(int x, int y, Object outData)
+ {
+ return sampleModel.getDataElements(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ outData, dataBuffer);
+ }
+
+ public Object getDataElements(int x, int y, int w, int h,
+ Object outData)
+ {
+ return sampleModel.getDataElements(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, outData, dataBuffer);
+ }
+
+ public int[] getPixel(int x, int y, int[] iArray)
+ {
+ return sampleModel.getPixel(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ iArray, dataBuffer);
+ }
+
+ public float[] getPixel(int x, int y, float[] fArray)
+ {
+ return sampleModel.getPixel(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ fArray, dataBuffer);
+ }
+
+ public double[] getPixel(int x, int y, double[] dArray)
+ {
+ return sampleModel.getPixel(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ dArray, dataBuffer);
+ }
+
+ public int[] getPixels(int x, int y, int w, int h, int[] iArray)
+ {
+ return sampleModel.getPixels(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, iArray, dataBuffer);
+ }
+
+ public float[] getPixels(int x, int y, int w, int h,
+ float[] fArray)
+ {
+ return sampleModel.getPixels(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, fArray, dataBuffer);
+ }
+
+ public double[] getPixels(int x, int y, int w, int h,
+ double[] dArray)
+ {
+ return sampleModel.getPixels(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, dArray, dataBuffer);
+ }
+
+ public int getSample(int x, int y, int b)
+ {
+ return sampleModel.getSample(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ b, dataBuffer);
+ }
+
+ public float getSampleFloat(int x, int y, int b)
+ {
+ return sampleModel.getSampleFloat(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ b, dataBuffer);
+ }
+
+ public double getSampleDouble(int x, int y, int b)
+ {
+ return sampleModel.getSampleDouble(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ b, dataBuffer);
+ }
+
+ public int[] getSamples(int x, int y, int w, int h, int b,
+ int[] iArray)
+ {
+ return sampleModel.getSamples(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, b, iArray, dataBuffer);
+ }
+
+ public float[] getSamples(int x, int y, int w, int h, int b,
+ float[] fArray)
+ {
+ return sampleModel.getSamples(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, b, fArray, dataBuffer);
+ }
+
+ public double[] getSamples(int x, int y, int w, int h, int b,
+ double[] dArray)
+ {
+ return sampleModel.getSamples(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, b, dArray, dataBuffer);
+ }
+
+ /**
+ * Create a String representing the stat of this Raster.
+ * @return A String representing the stat of this Raster.
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+
+ result.append(getClass().getName());
+ result.append("[(");
+ result.append(minX).append(",").append(minY).append("), ");
+ result.append(width).append(" x ").append(height).append(",");
+ result.append(sampleModel).append(",");
+ result.append(dataBuffer);
+ result.append("]");
+
+ return result.toString();
+ }
+
+ // Map from datatype to bits
+ private static int getTypeBits(int dataType)
+ {
+ switch (dataType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ return 8;
+ case DataBuffer.TYPE_USHORT:
+ case DataBuffer.TYPE_SHORT:
+ return 16;
+ case DataBuffer.TYPE_INT:
+ case DataBuffer.TYPE_FLOAT:
+ return 32;
+ case DataBuffer.TYPE_DOUBLE:
+ return 64;
+ default:
+ return 0;
+ }
+ }
+}
diff --git a/libjava/classpath/java/awt/image/RasterFormatException.java b/libjava/classpath/java/awt/image/RasterFormatException.java
new file mode 100644
index 0000000..582c2ae
--- /dev/null
+++ b/libjava/classpath/java/awt/image/RasterFormatException.java
@@ -0,0 +1,65 @@
+/* RasterFormatException.java -- indicates invalid layout in Raster
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * This exception is thrown when there is invalid layout information in
+ * <code>Raster</code>
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Raster
+ * @status updated to 1.4
+ */
+public class RasterFormatException extends RuntimeException
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 96598996116164315L;
+
+ /**
+ * Create a new instance with a descriptive error message.
+ *
+ * @param message the descriptive error message
+ */
+ public RasterFormatException(String message)
+ {
+ super(message);
+ }
+} // class RasterFormatException
diff --git a/libjava/classpath/java/awt/image/RasterOp.java b/libjava/classpath/java/awt/image/RasterOp.java
new file mode 100644
index 0000000..e081ca3
--- /dev/null
+++ b/libjava/classpath/java/awt/image/RasterOp.java
@@ -0,0 +1,57 @@
+/* RasterOp.java --
+ Copyright (C) 2000, 2002, 2004, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+public interface RasterOp
+{
+ WritableRaster filter(Raster src, WritableRaster dest);
+
+ Rectangle2D getBounds2D(Raster src);
+
+ WritableRaster createCompatibleDestRaster(Raster src);
+
+ Point2D getPoint2D(Point2D srcPoint, Point2D destPoint);
+
+ RenderingHints getRenderingHints();
+}
+
diff --git a/libjava/classpath/java/awt/image/RenderedImage.java b/libjava/classpath/java/awt/image/RenderedImage.java
new file mode 100644
index 0000000..b35f860
--- /dev/null
+++ b/libjava/classpath/java/awt/image/RenderedImage.java
@@ -0,0 +1,70 @@
+/* RenderedImage.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Rectangle;
+import java.util.Vector;
+
+/**
+ * NEEDS DOCUMENTATION
+ */
+public interface RenderedImage
+{
+ Vector getSources();
+ Object getProperty(String name);
+ String[] getPropertyNames();
+ ColorModel getColorModel();
+ SampleModel getSampleModel();
+ int getWidth();
+ int getHeight();
+ int getMinX();
+ int getMinY();
+ int getNumXTiles();
+ int getNumYTiles();
+ int getMinTileX();
+ int getMinTileY();
+ int getTileWidth();
+ int getTileHeight();
+ int getTileGridXOffset();
+ int getTileGridYOffset();
+ Raster getTile(int x, int y);
+ Raster getData();
+ Raster getData(Rectangle r);
+ WritableRaster copyData(WritableRaster raster);
+} // interface RenderedImage
diff --git a/libjava/classpath/java/awt/image/ReplicateScaleFilter.java b/libjava/classpath/java/awt/image/ReplicateScaleFilter.java
new file mode 100644
index 0000000..3841e49
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ReplicateScaleFilter.java
@@ -0,0 +1,244 @@
+/* ReplicateScaleFilter.java -- Java class for filtering images
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * This filter should be used for fast scaling of images where the result
+ * does not need to ensure straight lines are still straight, etc. The
+ * exact method is not defined by Sun but some sort of fast Box filter should
+ * probably be correct.
+ * <br>
+ * Currently this filter does nothing and needs to be implemented.
+ *
+ * @author C. Brian Jones (cbj@gnu.org)
+ */
+public class ReplicateScaleFilter extends ImageFilter
+{
+ public ReplicateScaleFilter(int width, int height) {
+ destHeight = height;
+ destWidth = width;
+ }
+
+ /**
+ * The height of the destination image.
+ */
+ protected int destHeight;
+
+ /**
+ * The width of the destination image.
+ */
+ protected int destWidth;
+
+ /**
+ * The height of the source image.
+ */
+ protected int srcHeight;
+
+ /**
+ * The width of the source image.
+ */
+ protected int srcWidth;
+
+ /**
+ *
+ */
+ protected int srcrows[];
+
+ /**
+ *
+ */
+ protected int srccols[];
+
+ /**
+ *
+ */
+ protected Object outpixbuf;
+
+ /**
+ * An <code>ImageProducer</code> indicates the size of the image
+ * being produced using this method. A filter can override this
+ * method to intercept these calls from the producer in order to
+ * change either the width or the height before in turn calling
+ * the consumer's <code>setDimensions</code> method.
+ *
+ * @param width the width of the image
+ * @param height the height of the image
+ */
+ public void setDimensions(int width, int height)
+ {
+ srcWidth = width;
+ srcHeight = height;
+
+ /* If either destHeight or destWidth is < 0, the image should
+ maintain its original aspect ratio. When both are < 0,
+ just maintain the original width and height. */
+ if (destWidth < 0 && destHeight < 0)
+ {
+ destWidth = width;
+ destHeight = height;
+ }
+ else if (destWidth < 0)
+ {
+ destWidth = (int) (width * ((double) destHeight / srcHeight));
+ }
+ else if (destHeight < 0)
+ {
+ destHeight = (int) (height * ((double) destWidth / srcWidth));
+ }
+
+ consumer.setDimensions(destWidth, destHeight);
+ }
+
+ /**
+ * An <code>ImageProducer</code> can set a list of properties
+ * associated with this image by using this method.
+ *
+ * @param props the list of properties associated with this image
+ */
+ public void setProperties(Hashtable props)
+ {
+ props.put("filters", "ReplicateScaleFilter");
+ consumer.setProperties(props);
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as a <code>byte</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels, int offset, int scansize)
+ {
+ double rx = ((double) srcWidth) / destWidth;
+ double ry = ((double) srcHeight) / destHeight;
+
+ int destScansize = (int) Math.round(scansize / rx);
+
+ byte[] destPixels = replicatePixels(x, y, w, h,
+ model, pixels, offset, scansize,
+ rx, ry, destScansize);
+
+ consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry),
+ (int) Math.ceil(w/rx), (int) Math.ceil(h/ry),
+ model, destPixels, 0, destScansize);
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as an <code>int</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels, int offset, int scansize)
+ {
+ double rx = ((double) srcWidth) / destWidth;
+ double ry = ((double) srcHeight) / destHeight;
+
+ int destScansize = (int) Math.round(scansize / rx);
+
+ int[] destPixels = replicatePixels(x, y, w, h,
+ model, pixels, offset, scansize,
+ rx, ry, destScansize);
+
+ consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry),
+ (int) Math.ceil(w/rx), (int) Math.ceil(h/ry),
+ model, destPixels, 0, destScansize);
+ }
+
+ private byte[] replicatePixels(int srcx, int srcy, int srcw, int srch,
+ ColorModel model, byte[] srcPixels,
+ int srcOffset, int srcScansize,
+ double rx, double ry, int destScansize)
+ {
+ byte[] destPixels =
+ new byte[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)];
+
+ int a, b;
+ for (int i = 0; i < destPixels.length; i++)
+ {
+ a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize;
+ b = (int) ((i % destScansize) * rx);
+ if ((a + b + srcOffset) < srcPixels.length)
+ destPixels[i] = srcPixels[a + b + srcOffset];
+ }
+
+ return destPixels;
+ }
+
+ private int[] replicatePixels(int srcx, int srcy, int srcw, int srch,
+ ColorModel model, int[] srcPixels,
+ int srcOffset, int srcScansize,
+ double rx, double ry, int destScansize)
+ {
+ int[] destPixels =
+ new int[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)];
+
+ int a, b;
+ for (int i = 0; i < destPixels.length; i++)
+ {
+ a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize;
+ b = (int) ((i % destScansize) * rx);
+ if ((a + b + srcOffset) < srcPixels.length)
+ destPixels[i] = srcPixels[a + b + srcOffset];
+ }
+
+ return destPixels;
+ }
+}
+
diff --git a/libjava/classpath/java/awt/image/RescaleOp.java b/libjava/classpath/java/awt/image/RescaleOp.java
new file mode 100644
index 0000000..35b42f7
--- /dev/null
+++ b/libjava/classpath/java/awt/image/RescaleOp.java
@@ -0,0 +1,218 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+/**
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ */
+public class RescaleOp implements BufferedImageOp, RasterOp
+{
+ private float[] scale;
+ private float[] offsets;
+ private RenderingHints hints = null;
+
+ public RescaleOp(float[] scaleFactors,
+ float[] offsets,
+ RenderingHints hints)
+ {
+ this.scale = scaleFactors;
+ this.offsets = offsets;
+ this.hints = hints;
+ }
+
+ public RescaleOp(float scaleFactor,
+ float offset,
+ RenderingHints hints)
+ {
+ scale = new float[]{ scaleFactor };
+ offsets = new float[]{offset};
+ this.hints = hints;
+ }
+
+ public final float[] getScaleFactors(float[] scaleFactors)
+ {
+ if (scaleFactors == null)
+ scaleFactors = new float[scale.length];
+ System.arraycopy(scale, 0, scaleFactors, 0, scale.length);
+ return scaleFactors;
+ }
+
+ public final float[] getOffsets(float[] offsets)
+ {
+ if (offsets == null)
+ offsets = new float[this.offsets.length];
+ System.arraycopy(this.offsets, 0, offsets, 0, this.offsets.length);
+ return offsets;
+ }
+
+ public final int getNumFactors()
+ {
+ return scale.length;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getRenderingHints()
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage, java.awt.image.BufferedImage)
+ */
+ public final BufferedImage filter(BufferedImage src, BufferedImage dst)
+ {
+ // TODO Make sure premultiplied alpha is handled correctly.
+ // TODO See that color conversion is handled.
+ // TODO figure out how to use rendering hints.
+ if (scale.length != offsets.length)
+ throw new IllegalArgumentException();
+
+ ColorModel scm = src.getColorModel();
+ if (dst == null) dst = createCompatibleDestImage(src, null);
+
+ WritableRaster wsrc = src.getRaster();
+ WritableRaster wdst = dst.getRaster();
+
+ // Share constant across colors except alpha
+ if (scale.length == 1 || scale.length == scm.getNumColorComponents())
+ {
+ // Construct a raster that doesn't include an alpha band.
+ int[] subbands = new int[scm.getNumColorComponents()];
+ for (int i=0; i < subbands.length; i++) subbands[i] = i;
+ wsrc =
+ wsrc.createWritableChild(wsrc.minX, wsrc.minY, wsrc.width, wsrc.height,
+ wsrc.minX, wsrc.minY, subbands);
+ }
+ // else all color bands
+
+ filter(wsrc, wdst);
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
+ */
+ public final WritableRaster filter(Raster src, WritableRaster dest)
+ {
+ if (dest == null) dest = src.createCompatibleWritableRaster();
+
+ // Required sanity checks
+ if (src.numBands != dest.numBands || scale.length != offsets.length)
+ throw new IllegalArgumentException();
+ if (scale.length != 1 && scale.length != src.numBands)
+ throw new IllegalArgumentException();
+
+ // Create scaling arrays if needed
+ float[] lscale = scale;
+ float[] loff = offsets;
+ if (scale.length == 1)
+ {
+ lscale = new float[src.numBands];
+ Arrays.fill(lscale, scale[0]);
+ loff = new float[src.numBands];
+ Arrays.fill(loff, offsets[0]);
+ }
+
+ // TODO The efficiency here can be improved for various data storage
+ // patterns, aka SampleModels.
+ float[] pixel = new float[src.numBands];
+ for (int y = src.minY; y < src.height + src.minY; y++)
+ for (int x = src.minX; x < src.width + src.minX; x++)
+ {
+ src.getPixel(x, y, pixel);
+ for (int b = 0; b < src.numBands; b++)
+ pixel[b] = pixel[b] * lscale[b] + loff[b];
+ dest.setPixel(x, y, pixel);
+ }
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
+ */
+ public BufferedImage createCompatibleDestImage(BufferedImage src,
+ ColorModel dstCM)
+ {
+ if (dstCM == null) dstCM = src.getColorModel();
+ WritableRaster wr = src.getRaster().createCompatibleWritableRaster();
+ BufferedImage image
+ = new BufferedImage(dstCM, wr, src.isPremultiplied, null);
+ return image;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return src.createCompatibleWritableRaster();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
+ */
+ public final Rectangle2D getBounds2D(BufferedImage src)
+ {
+ return src.getRaster().getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public final Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
+ */
+ public final Point2D getPoint2D(Point2D src, Point2D dst) {
+ if (dst == null) dst = (Point2D) src.clone();
+ else dst.setLocation(src);
+ return dst;
+ }
+
+}
diff --git a/libjava/classpath/java/awt/image/SampleModel.java b/libjava/classpath/java/awt/image/SampleModel.java
new file mode 100644
index 0000000..257e30a
--- /dev/null
+++ b/libjava/classpath/java/awt/image/SampleModel.java
@@ -0,0 +1,477 @@
+/* Copyright (C) 2000, 2001, 2002, 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/**
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public abstract class SampleModel
+{
+ /** Width of image described. */
+ protected int width;
+
+ /** Height of image described. */
+ protected int height;
+
+ /** Number of bands in the image described. */
+ protected int numBands;
+
+ /**
+ * The DataBuffer type that is used to store the data of the image
+ * described.
+ */
+ protected int dataType;
+
+ public SampleModel(int dataType, int w, int h, int numBands)
+ {
+ if ((w <= 0) || (h <= 0))
+ throw new IllegalArgumentException((w <= 0 ? " width<=0" : " width is ok")
+ +(h <= 0 ? " height<=0" : " height is ok"));
+
+ // FIXME: How can an int be greater than Integer.MAX_VALUE?
+ // FIXME: How do we identify an unsupported data type?
+
+ this.dataType = dataType;
+ this.width = w;
+ this.height = h;
+ this.numBands = numBands;
+ }
+
+ public final int getWidth()
+ {
+ return width;
+ }
+
+ public final int getHeight()
+ {
+ return height;
+ }
+
+ public final int getNumBands()
+ {
+ return numBands;
+ }
+
+ public abstract int getNumDataElements();
+
+ public final int getDataType()
+ {
+ return dataType;
+ }
+
+ public int getTransferType()
+ {
+ // FIXME: Is this a reasonable default implementation?
+ return dataType;
+ }
+
+ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[numBands];
+ for (int b=0; b<numBands; b++) iArray[b] = getSample(x, y, b, data);
+ return iArray;
+ }
+
+ /**
+ *
+ * This method is provided as a faster alternative to getPixel(),
+ * that can be used when there is no need to decode the pixel into
+ * separate sample values.
+ *
+ * @param obj An array to return the pixel data in. If null, an
+ * array of the right type and size will be created.
+ *
+ * @return A single pixel as an array object of a primitive type,
+ * based on the transfer type. Eg. if transfer type is
+ * DataBuffer.TYPE_USHORT, then a short[] object is returned.
+ */
+ public abstract Object getDataElements(int x, int y, Object obj,
+ DataBuffer data);
+
+
+ public Object getDataElements(int x, int y, int w, int h, Object obj,
+ DataBuffer data)
+ {
+ int size = w*h;
+ int numDataElements = getNumDataElements();
+ int dataSize = numDataElements*size;
+
+ if (obj == null)
+ {
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ obj = new byte[dataSize];
+ break;
+ case DataBuffer.TYPE_USHORT:
+ obj = new short[dataSize];
+ break;
+ case DataBuffer.TYPE_INT:
+ obj = new int[dataSize];
+ break;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+ }
+ Object pixelData = null;
+ int outOffset = 0;
+ for (int yy = y; yy<(y+h); yy++)
+ {
+ for (int xx = x; xx<(x+w); xx++)
+ {
+ pixelData = getDataElements(xx, yy, pixelData, data);
+ System.arraycopy(pixelData, 0, obj, outOffset,
+ numDataElements);
+ outOffset += numDataElements;
+ }
+ }
+ return obj;
+ }
+
+ public abstract void setDataElements(int x, int y, Object obj,
+ DataBuffer data);
+
+ public void setDataElements(int x, int y, int w, int h,
+ Object obj, DataBuffer data)
+ {
+ int size = w*h;
+ int numDataElements = getNumDataElements();
+ int dataSize = numDataElements*size;
+
+ Object pixelData;
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ pixelData = new byte[numDataElements];
+ break;
+ case DataBuffer.TYPE_USHORT:
+ pixelData = new short[numDataElements];
+ break;
+ case DataBuffer.TYPE_INT:
+ pixelData = new int[numDataElements];
+ break;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+ int inOffset = 0;
+
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ System.arraycopy(obj, inOffset, pixelData, 0,
+ numDataElements);
+ setDataElements(xx, yy, pixelData, data);
+ inOffset += numDataElements;
+ }
+ }
+ }
+
+ public float[] getPixel(int x, int y, float[] fArray, DataBuffer data)
+ {
+ if (fArray == null) fArray = new float[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ fArray[b] = getSampleFloat(x, y, b, data);
+ }
+ return fArray;
+ }
+
+ public double[] getPixel(int x, int y, double[] dArray, DataBuffer data) {
+ if (dArray == null) dArray = new double[numBands];
+ for (int b=0; b<numBands; b++)
+ {
+ dArray[b] = getSampleDouble(x, y, b, data);
+ }
+ return dArray;
+ }
+
+ /* FIXME: Should it return a banded or pixel interleaved array of
+ samples? (Assume interleaved.) */
+ public int[] getPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int size = w*h;
+ int outOffset = 0;
+ int[] pixel = null;
+ if (iArray == null) iArray = new int[w*h*numBands];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ pixel = getPixel(xx, yy, pixel, data);
+ System.arraycopy(pixel, 0, iArray, outOffset, numBands);
+ outOffset += numBands;
+ }
+ }
+ return iArray;
+ }
+
+ /* FIXME: Should it return a banded or pixel interleaved array of
+ samples? (Assume interleaved.) */
+ public float[] getPixels(int x, int y, int w, int h, float[] fArray,
+ DataBuffer data)
+ {
+ int size = w*h;
+ int outOffset = 0;
+ float[] pixel = null;
+ if (fArray == null) fArray = new float[w*h*numBands];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ pixel = getPixel(xx, yy, pixel, data);
+ System.arraycopy(pixel, 0, fArray, outOffset, numBands);
+ outOffset += numBands;
+ }
+ }
+ return fArray;
+ }
+
+ /* FIXME: Should it return a banded or pixel interleaved array of
+ samples? (Assume interleaved.) */
+ public double[] getPixels(int x, int y, int w, int h, double[] dArray,
+ DataBuffer data)
+ {
+ int size = w*h;
+ int outOffset = 0;
+ double[] pixel = null;
+ if (dArray == null) dArray = new double[w*h*numBands];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ pixel = getPixel(xx, yy, pixel, data);
+ System.arraycopy(pixel, 0, dArray, outOffset, numBands);
+ outOffset += numBands;
+ }
+ }
+ return dArray;
+ }
+
+ public abstract int getSample(int x, int y, int b, DataBuffer data);
+
+ public float getSampleFloat(int x, int y, int b, DataBuffer data)
+ {
+ return getSample(x, y, b, data);
+ }
+
+ public double getSampleDouble(int x, int y, int b, DataBuffer data)
+ {
+ return getSampleFloat(x, y, b, data);
+ }
+
+ public int[] getSamples(int x, int y, int w, int h, int b,
+ int[] iArray, DataBuffer data)
+ {
+ int size = w*h;
+ int outOffset = 0;
+ if (iArray == null) iArray = new int[size];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ iArray[outOffset++] = getSample(xx, yy, b, data);
+ }
+ }
+ return iArray;
+ }
+
+ public float[] getSamples(int x, int y, int w, int h, int b,
+ float[] fArray, DataBuffer data)
+ {
+ int size = w*h;
+ int outOffset = 0;
+ if (fArray == null) fArray = new float[size];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ fArray[outOffset++] = getSampleFloat(xx, yy, b, data);
+ }
+ }
+ return fArray;
+ }
+
+ public double[] getSamples(int x, int y, int w, int h, int b,
+ double[] dArray, DataBuffer data)
+ {
+ int size = w*h;
+ int outOffset = 0;
+ if (dArray == null) dArray = new double[size];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ dArray[outOffset++] = getSampleDouble(xx, yy, b, data);
+ }
+ }
+ return dArray;
+ }
+
+ public void setPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ for (int b=0; b<numBands; b++) setSample(x, y, b, iArray[b], data);
+ }
+
+ public void setPixel(int x, int y, float[] fArray, DataBuffer data)
+ {
+ for (int b=0; b<numBands; b++) setSample(x, y, b, fArray[b], data);
+ }
+
+ public void setPixel(int x, int y, double[] dArray, DataBuffer data)
+ {
+ for (int b=0; b<numBands; b++) setSample(x, y, b, dArray[b], data);
+ }
+
+ public void setPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+ int[] pixel = new int[numBands];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ System.arraycopy(iArray, inOffset, pixel, 0, numBands);
+ setPixel(xx, yy, pixel, data);
+ inOffset += numBands;
+ }
+ }
+ }
+
+ public void setPixels(int x, int y, int w, int h, float[] fArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+ float[] pixel = new float[numBands];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ System.arraycopy(fArray, inOffset, pixel, 0, numBands);
+ setPixel(xx, yy, pixel, data);
+ inOffset += numBands;
+ }
+ }
+ }
+
+ public void setPixels(int x, int y, int w, int h, double[] dArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+ double[] pixel = new double[numBands];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ System.arraycopy(dArray, inOffset, pixel, 0, numBands);
+ setPixel(xx, yy, pixel, data);
+ inOffset += numBands;
+ }
+ }
+ }
+
+ public abstract void setSample(int x, int y, int b, int s,
+ DataBuffer data);
+
+ public void setSample(int x, int y, int b, float s,
+ DataBuffer data)
+ {
+ setSample(x, y, b, (int) s, data);
+ }
+
+ public void setSample(int x, int y, int b, double s,
+ DataBuffer data)
+ {
+ setSample(x, y, b, (float) s, data);
+ }
+
+ public void setSamples(int x, int y, int w, int h, int b,
+ int[] iArray, DataBuffer data)
+ {
+ int size = w*h;
+ int inOffset = 0;
+ for (int yy=y; yy<(y+h); yy++)
+ for (int xx=x; xx<(x+w); xx++)
+ setSample(xx, yy, b, iArray[inOffset++], data);
+ }
+
+ public void setSamples(int x, int y, int w, int h, int b,
+ float[] fArray, DataBuffer data)
+ {
+ int size = w*h;
+ int inOffset = 0;
+ for (int yy=y; yy<(y+h); yy++)
+ for (int xx=x; xx<(x+w); xx++)
+ setSample(xx, yy, b, fArray[inOffset++], data);
+
+ }
+
+ public void setSamples(int x, int y, int w, int h, int b,
+ double[] dArray, DataBuffer data) {
+ int size = w*h;
+ int inOffset = 0;
+ for (int yy=y; yy<(y+h); yy++)
+ for (int xx=x; xx<(x+w); xx++)
+ setSample(xx, yy, b, dArray[inOffset++], data);
+ }
+
+ public abstract SampleModel createCompatibleSampleModel(int w, int h);
+
+ /**
+ * Return a SampleModel with a subset of the bands in this model.
+ *
+ * Selects bands.length bands from this sample model. The bands chosen
+ * are specified in the indices of bands[]. This also permits permuting
+ * the bands as well as taking a subset. Thus, giving an array with
+ * 1, 2, 3, ..., numbands, will give an identical sample model.
+ *
+ * @param bands Array with band indices to include.
+ * @return A new sample model
+ */
+ public abstract SampleModel createSubsetSampleModel(int[] bands);
+
+ public abstract DataBuffer createDataBuffer();
+
+ public abstract int[] getSampleSize();
+
+ public abstract int getSampleSize(int band);
+}
diff --git a/libjava/classpath/java/awt/image/ShortLookupTable.java b/libjava/classpath/java/awt/image/ShortLookupTable.java
new file mode 100644
index 0000000..5915a79
--- /dev/null
+++ b/libjava/classpath/java/awt/image/ShortLookupTable.java
@@ -0,0 +1,162 @@
+/* ShortLookupTable.java -- Java class for a pixel translation table.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * ShortLookupTable represents translation arrays for pixel values. It wraps
+ * one or more data arrays for each layer (or component) in an image, such as
+ * Alpha, R, G, and B. When doing translation, the offset is subtracted from
+ * the pixel values to allow a subset of an array to be used.
+ *
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ * @version 1.0
+ */
+public class ShortLookupTable extends LookupTable
+{
+ // Array of translation tables.
+ private short data[][];
+
+ /**
+ * Creates a new <code>ShortLookupTable</code> instance.
+ *
+ * Offset is subtracted from pixel values when looking up in the translation
+ * tables. If data.length is one, the same table is applied to all pixel
+ * components.
+ *
+ * @param offset Offset to be subtracted.
+ * @param data Array of lookup tables.
+ * @exception IllegalArgumentException if offset &lt; 0 or data.length &lt; 1.
+ */
+ public ShortLookupTable(int offset, short[][] data)
+ throws IllegalArgumentException
+ {
+ super(offset, data.length);
+ this.data = data;
+ }
+
+ /**
+ * Creates a new <code>ShortLookupTable</code> instance.
+ *
+ * Offset is subtracted from pixel values when looking up in the translation
+ * table. The same table is applied to all pixel components.
+ *
+ * @param offset Offset to be subtracted.
+ * @param data Lookup table for all components.
+ * @exception IllegalArgumentException if offset &lt; 0.
+ */
+ public ShortLookupTable(int offset, short[] data)
+ throws IllegalArgumentException
+ {
+ super(offset, 1);
+ this.data = new short[][] {data};
+ }
+
+ /** Return the lookup tables. */
+ public final short[][] getTable()
+ {
+ return data;
+ }
+
+ /**
+ * Return translated values for a pixel.
+ *
+ * For each value in the pixel src, use the value minus offset as an index
+ * in the component array and copy the value there to the output for the
+ * component. If dest is null, the output is a new array, otherwise the
+ * translated values are written to dest. Dest can be the same array as
+ * src.
+ *
+ * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+ * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+ * translation arrays.
+ *
+ * @param src Component values of a pixel.
+ * @param dst Destination array for values, or null.
+ * @return Translated values for the pixel.
+ */
+ public int[] lookupPixel(int[] src, int[] dst)
+ throws ArrayIndexOutOfBoundsException
+ {
+ if (dst == null)
+ dst = new int[src.length];
+
+ if (data.length == 1)
+ for (int i=0; i < src.length; i++)
+ dst[i] = data[0][src[i] - offset];
+ else
+ for (int i=0; i < src.length; i++)
+ dst[i] = data[i][src[i] - offset];
+
+ return dst;
+ }
+
+ /**
+ * Return translated values for a pixel.
+ *
+ * For each value in the pixel src, use the value minus offset as an index
+ * in the component array and copy the value there to the output for the
+ * component. If dest is null, the output is a new array, otherwise the
+ * translated values are written to dest. Dest can be the same array as
+ * src.
+ *
+ * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+ * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+ * translation arrays.
+ *
+ * @param src Component values of a pixel.
+ * @param dst Destination array for values, or null.
+ * @return Translated values for the pixel.
+ */
+ public short[] lookupPixel(short[] src, short[] dst)
+ throws ArrayIndexOutOfBoundsException
+ {
+ if (dst == null)
+ dst = new short[src.length];
+
+ if (data.length == 1)
+ for (int i=0; i < src.length; i++)
+ dst[i] = data[0][((int)src[i]) - offset];
+ else
+ for (int i=0; i < src.length; i++)
+ dst[i] = data[i][((int)src[i]) - offset];
+
+ return dst;
+
+ }
+}
diff --git a/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java b/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java
new file mode 100644
index 0000000..6ccce75
--- /dev/null
+++ b/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java
@@ -0,0 +1,449 @@
+/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+import gnu.java.awt.BitMaskExtent;
+import gnu.java.awt.Buffers;
+
+/**
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public class SinglePixelPackedSampleModel extends SampleModel
+{
+ private int scanlineStride;
+ private int[] bitMasks;
+ private int[] bitOffsets;
+ private int[] sampleSize;
+
+ public SinglePixelPackedSampleModel(int dataType, int w, int h,
+ int[] bitMasks)
+ {
+ this(dataType, w, h, w, bitMasks);
+ }
+
+ public SinglePixelPackedSampleModel(int dataType, int w, int h,
+ int scanlineStride, int[] bitMasks)
+ {
+ super(dataType, w, h, bitMasks.length);
+
+ switch (dataType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ case DataBuffer.TYPE_USHORT:
+ case DataBuffer.TYPE_INT:
+ break;
+ default:
+ throw new IllegalArgumentException("SinglePixelPackedSampleModel unsupported dataType");
+ }
+
+ this.scanlineStride = scanlineStride;
+ this.bitMasks = bitMasks;
+
+ bitOffsets = new int[numBands];
+ sampleSize = new int[numBands];
+
+ BitMaskExtent extent = new BitMaskExtent();
+ for (int b=0; b<numBands; b++)
+ {
+ extent.setMask(bitMasks[b]);
+ sampleSize[b] = extent.bitWidth;
+ bitOffsets[b] = extent.leastSignificantBit;
+ }
+ }
+
+ public int getNumDataElements()
+ {
+ return 1;
+ }
+
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ /* FIXME: We can avoid recalculation of bit offsets and sample
+ sizes here by passing these from the current instance to a
+ special private constructor. */
+ return new SinglePixelPackedSampleModel(dataType, w, h, bitMasks);
+ }
+
+
+ /**
+ * Creates a DataBuffer for holding pixel data in the format and
+ * layout described by this SampleModel. The returned buffer will
+ * consist of one single bank.
+ */
+ public DataBuffer createDataBuffer()
+ {
+ int size;
+
+ // We can save (scanlineStride - width) pixels at the very end of
+ // the buffer. The Sun reference implementation (J2SE 1.3.1 and
+ // 1.4.1_01) seems to do this; tested with Mauve test code.
+ size = scanlineStride * (height - 1) + width;
+
+ return Buffers.createBuffer(getDataType(), size);
+ }
+
+
+ public int[] getSampleSize()
+ {
+ return sampleSize;
+ }
+
+ public int getSampleSize(int band)
+ {
+ return sampleSize[band];
+ }
+
+ public int getOffset(int x, int y)
+ {
+ return scanlineStride*y + x;
+ }
+
+ public int[] getBitOffsets()
+ {
+ return bitOffsets;
+ }
+
+ public int[] getBitMasks()
+ {
+ return bitMasks;
+ }
+
+ public int getScanlineStride()
+ {
+ return scanlineStride;
+ }
+
+ public SampleModel createSubsetSampleModel(int[] bands)
+ {
+ // FIXME: Is this the right way to interpret bands?
+
+ int numBands = bands.length;
+
+ int[] bitMasks = new int[numBands];
+
+ for (int b=0; b<numBands; b++)
+ bitMasks[b] = this.bitMasks[bands[b]];
+
+ return new SinglePixelPackedSampleModel(dataType, width, height,
+ scanlineStride, bitMasks);
+ }
+
+ public Object getDataElements(int x, int y, Object obj,
+ DataBuffer data)
+ {
+ int offset = scanlineStride*y + x + data.getOffset();
+
+ return Buffers.getData(data, offset, obj,
+ 0, // destination offset,
+ 1 // length
+ );
+ }
+
+ /**
+ * This is a more efficient implementation of the default implementation in the super
+ * class.
+ * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param w The width of the pixel rectangle to store in <code>obj</code>.
+ * @param h The height of the pixel rectangle to store in <code>obj</code>.
+ * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public Object getDataElements(int x, int y, int w, int h, Object obj,
+ DataBuffer data)
+ {
+ int size = w*h;
+ int dataSize = size;
+ Object pixelData = null;
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ pixelData = ((DataBufferByte) data).getData();
+ if (obj == null) obj = new byte[dataSize];
+ break;
+ case DataBuffer.TYPE_USHORT:
+ pixelData = ((DataBufferUShort) data).getData();
+ if (obj == null) obj = new short[dataSize];
+ break;
+ case DataBuffer.TYPE_INT:
+ pixelData = ((DataBufferInt) data).getData();
+ if (obj == null) obj = new int[dataSize];
+ break;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+ if(x==0 && scanlineStride == w)
+ {
+ // The full width need to be copied therefore we can copy in one shot.
+ System.arraycopy(pixelData, scanlineStride*y + data.getOffset(), obj, 0, size);
+ }
+ else
+ {
+ // Since we do not need the full width we need to copy line by line.
+ int outOffset = 0;
+ int dataOffset = scanlineStride*y + x + data.getOffset();
+ for (int yy = y; yy<(y+h); yy++)
+ {
+ System.arraycopy(pixelData, dataOffset, obj, outOffset, w);
+ dataOffset += scanlineStride;
+ outOffset += w;
+ }
+ }
+ return obj;
+ }
+
+
+ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ int offset = scanlineStride*y + x;
+ if (iArray == null) iArray = new int[numBands];
+ int samples = data.getElem(offset);
+
+ for (int b=0; b<numBands; b++)
+ iArray[b] = (samples & bitMasks[b]) >>> bitOffsets[b];
+
+ return iArray;
+ }
+
+ public int[] getPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int offset = scanlineStride*y + x;
+ if (iArray == null) iArray = new int[numBands*w*h];
+ int outOffset = 0;
+ for (y=0; y<h; y++)
+ {
+ int lineOffset = offset;
+ for (x=0; x<w; x++)
+ {
+ int samples = data.getElem(lineOffset++);
+ for (int b=0; b<numBands; b++)
+ iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
+ }
+ offset += scanlineStride;
+ }
+ return iArray;
+ }
+
+ public int getSample(int x, int y, int b, DataBuffer data)
+ {
+ int offset = scanlineStride*y + x;
+ int samples = data.getElem(offset);
+ return (samples & bitMasks[b]) >>> bitOffsets[b];
+ }
+
+ /**
+ * This method implements a more efficient way to set data elements than the default
+ * implementation of the super class. It sets the data elements line by line instead
+ * of pixel by pixel.
+ * @param x The x-coordinate of the data elements in <code>obj</code>.
+ * @param y The y-coordinate of the data elements in <code>obj</code>.
+ * @param w The width of the data elements in <code>obj</code>.
+ * @param h The height of the data elements in <code>obj</code>.
+ * @param obj The primitive array containing the data elements to set.
+ * @param data The DataBuffer to store the data elements into.
+ * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public void setDataElements(int x, int y, int w, int h,
+ Object obj, DataBuffer data)
+ {
+
+ Object pixelData;
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ pixelData = ((DataBufferByte) data).getData();
+ break;
+ case DataBuffer.TYPE_USHORT:
+ pixelData = ((DataBufferUShort) data).getData();
+ break;
+ case DataBuffer.TYPE_INT:
+ pixelData = ((DataBufferInt) data).getData();
+ break;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+
+ int inOffset = 0;
+ int dataOffset = scanlineStride*y + x + data.getOffset();
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ System.arraycopy(obj,inOffset,pixelData,dataOffset,w);
+ dataOffset += scanlineStride;
+ inOffset += w;
+ }
+ }
+
+
+ public void setDataElements(int x, int y, Object obj, DataBuffer data)
+ {
+ int offset = scanlineStride*y + x + data.getOffset();
+
+ int transferType = getTransferType();
+ if (getTransferType() != data.getDataType())
+ {
+ throw new IllegalArgumentException("transfer type ("+
+ getTransferType()+"), "+
+ "does not match data "+
+ "buffer type (" +
+ data.getDataType() +
+ ").");
+ }
+
+ try
+ {
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ DataBufferByte out = (DataBufferByte) data;
+ byte[] in = (byte[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ DataBufferUShort out = (DataBufferUShort) data;
+ short[] in = (short[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ DataBufferInt out = (DataBufferInt) data;
+ int[] in = (int[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ // FIXME: Fill in the other possible types.
+ default:
+ throw new InternalError();
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException aioobe)
+ {
+ String msg = "While writing data elements" +
+ ", x="+x+", y="+y+
+ ", width="+width+", height="+height+
+ ", scanlineStride="+scanlineStride+
+ ", offset="+offset+
+ ", data.getSize()="+data.getSize()+
+ ", data.getOffset()="+data.getOffset()+
+ ": " +
+ aioobe;
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+ }
+
+ public void setPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ int offset = scanlineStride*y + x;
+
+ int samples = 0;
+ for (int b=0; b<numBands; b++)
+ samples |= (iArray[b] << bitOffsets[b]) & bitMasks[b];
+
+ data.setElem(offset, samples);
+ }
+
+ /**
+ * This method implements a more efficient way to set pixels than the default
+ * implementation of the super class. It copies the pixel components directly
+ * from the input array instead of creating a intermediate buffer.
+ * @param x The x-coordinate of the pixel rectangle in <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle in <code>obj</code>.
+ * @param w The width of the pixel rectangle in <code>obj</code>.
+ * @param h The height of the pixel rectangle in <code>obj</code>.
+ * @param iArray The primitive array containing the pixels to set.
+ * @param data The DataBuffer to store the pixels into.
+ * @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[], java.awt.image.DataBuffer)
+ */
+ public void setPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+ int[] pixel = new int[numBands];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ int offset = scanlineStride*yy + x;
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ int samples = 0;
+ for (int b=0; b<numBands; b++)
+ samples |= (iArray[inOffset+b] << bitOffsets[b]) & bitMasks[b];
+ data.setElem(0, offset, samples);
+ inOffset += numBands;
+ offset += 1;
+ }
+ }
+ }
+
+
+ public void setSample(int x, int y, int b, int s, DataBuffer data)
+ {
+ int offset = scanlineStride*y + x;
+ int samples = data.getElem(offset);
+ int bitMask = bitMasks[b];
+ samples &= ~bitMask;
+ samples |= (s << bitOffsets[b]) & bitMask;
+ data.setElem(offset, samples);
+ }
+
+ /**
+ * Creates a String with some information about this SampleModel.
+ * @return A String describing this SampleModel.
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+ result.append(getClass().getName());
+ result.append("[");
+ result.append("scanlineStride=").append(scanlineStride);
+ for(int i=0; i < bitMasks.length; i+=1)
+ {
+ result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+ }
+
+ result.append("]");
+ return result.toString();
+ }
+}
diff --git a/libjava/classpath/java/awt/image/TileObserver.java b/libjava/classpath/java/awt/image/TileObserver.java
new file mode 100644
index 0000000..99aafbc
--- /dev/null
+++ b/libjava/classpath/java/awt/image/TileObserver.java
@@ -0,0 +1,47 @@
+/* TileObserver.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * NEEDS DOCUMENTATION
+ */
+public interface TileObserver
+{
+ void tileUpdate(WritableRenderedImage src, int x, int y, boolean writable);
+} // interface TileObserver
diff --git a/libjava/classpath/java/awt/image/VolatileImage.java b/libjava/classpath/java/awt/image/VolatileImage.java
new file mode 100644
index 0000000..3086541
--- /dev/null
+++ b/libjava/classpath/java/awt/image/VolatileImage.java
@@ -0,0 +1,253 @@
+/* VolatileImage.java -- a hardware-accelerated image buffer
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.ImageCapabilities;
+
+/**
+ * VolatileImage represents a hardware-accelerated graphics buffer.
+ * The native graphics system may free or damage the resources
+ * occupied by a VolatileImage at any time. As such, one must
+ * frequently check the "validity" of the image buffer's resources.
+ *
+ * A volatile image's "validity" depends on multiple factors. Its
+ * resources may have become unavailble in which case you must
+ * reallocate them. If you move the image from one output device to
+ * another, you may need to recreate the image's resources if the new
+ * output device's capabilities don't match the old one's. Finally,
+ * if the contents of the image's buffer have been damaged you must
+ * re-render the image.
+ *
+ * VolatileImages should always be created using either
+ * Component.createVolatileImage or
+ * GraphicsConfiguration.createCompatibleVolatileImage.
+ */
+public abstract class VolatileImage extends Image
+ implements Transparency
+{
+ /**
+ * One of validate's possible return values. Indicates that the
+ * image buffer matches its graphics configuration's capabilities
+ * and that its resources are initialized and ready to be drawn
+ * into. Also implies that any existing image rendered to the
+ * buffer is intact and need not be re-rendered.
+ */
+ public static final int IMAGE_OK = 0;
+
+ /**
+ * One of validate's possible return values. Indicates that the
+ * image buffer has been restored, meaning that it is valid and
+ * ready-to-use but that its previous contents have been lost. This
+ * return value implies that the image needs to be re-rendered.
+ */
+ public static final int IMAGE_RESTORED = 1;
+
+ /**
+ * One of validate's possible return values. Indicates that the
+ * image buffer type is unsupported by the current graphics
+ * configuration. The graphics configuration may have changed, for
+ * example if the image moved from one output device to another.
+ * This return value implies that the image buffer's resources
+ * should be re-acquired.
+ */
+ public static final int IMAGE_INCOMPATIBLE = 2;
+
+ /**
+ * This image's transparency type. One of Transparency.BITMASK,
+ * Transparency.OPAQUE or Transparency.TRANSLUCENT.
+ *
+ * @since 1.5
+ */
+ protected int transparency;
+
+ /**
+ * Default constructor. VolatileImages should not be created
+ * directly. Rather, you should use Component.createVolatileImage
+ * or GraphicsConfiguration.createCompatibleVolatileImage.
+ */
+ public VolatileImage()
+ {
+ }
+
+ /**
+ * Returns an image representing the current state of the volatile
+ * image buffer. The returned image is static meaning that it is
+ * not updated after being created. It is a snapshot of the
+ * volatile image buffer at the time getSnapshot is called.
+ *
+ * This method, which reads pixels from the volatile image buffer,
+ * may be less-performant than methods that write pixels since
+ * VolatileImages are typically optimized for writing.
+ *
+ * @return a BufferedImage representing this VolatileImage
+ */
+ public abstract BufferedImage getSnapshot();
+
+ /**
+ * Returns the width of this image buffer.
+ *
+ * @return the width of this VolatileImage
+ */
+ public abstract int getWidth();
+
+ /**
+ * Returns the height of this image buffer.
+ *
+ * @return the height of this VolatileImage
+ */
+ public abstract int getHeight();
+
+ /**
+ * Calling this method is equivalent to calling
+ * getSnapshot().getSource(). The ImageProducer produces pixels
+ * from the BufferedImage snapshot and not from the VolatileImage
+ * itself. Thus, changes to the VolatileImage that occur after this
+ * ImageProducer has been retrieved will not be reflected in the
+ * produced pixels.
+ *
+ * This method, which reads pixels from the volatile image buffer,
+ * may be less-performant than methods that write pixels since
+ * VolatileImages are typically optimized for writing.
+ *
+ * @return an ImageProducer for a static BufferedImage snapshot of
+ * this image buffer
+ */
+ public ImageProducer getSource()
+ {
+ return getSnapshot().getSource();
+ }
+
+ /**
+ * Releases the system resources taken by this image.
+ */
+ public void flush()
+ {
+ }
+
+ /**
+ * Returns a Graphics2D object that can be used to draw onto this
+ * image. This method is present for backwards-compatibility. It
+ * simply returns the result of createGraphics.
+ *
+ * @return a Graphics2D object that can be used to draw onto this
+ * image
+ */
+ public Graphics getGraphics()
+ {
+ return createGraphics();
+ }
+
+ /**
+ * Returns a Graphics2D object that can be used to draw onto this
+ * image.
+ *
+ * @return a Graphics2D object that can be used to draw onto this
+ * image
+ */
+ public abstract Graphics2D createGraphics();
+
+ /**
+ * Validates and restores this image. If the image buffer has
+ * become unavailable for further use since the last call to
+ * validate, validate will allocate a new image buffer. The image
+ * is also "validated" against the GraphicsConfiguration parameter.
+ *
+ * "Validating" the image means checking that the capabilities it
+ * requires of the output device are indeed supported by the given
+ * output device. If the image's characteristics, which can be
+ * highly output device-specific, are not supported by the graphics
+ * configuration, then IMAGE_INCOMPATIBLE will be returned. This
+ * can happen, for example, if this image was created on one output
+ * device, then validated against a different output device with
+ * different capabilities. Calling validate with a NULL gc argument
+ * causes validate to skip the validation test.
+ *
+ * @param gc graphics configuration against which to validate or
+ * NULL
+ *
+ * @return a code indicating the result of validation. One of:
+ * <ul>
+ * <li><code>IMAGE_OK</code> if the image did not need to be
+ * validated and didn't need to be restored</li>
+ * <li><code>IMAGE_RESTORED</code> if the image may need to be
+ * re-rendered.</li>
+ * <li><code>IMAGE_INCOMPATIBLE</code> if this image's
+ * requirements are not fulfilled by the graphics configuration
+ * parameter. This implies that you need to create a new
+ * VolatileImage for the different GraphicsConfiguration or
+ * Component. This return value implies nothing about whether the
+ * image is valid or needs to be re-rendered.</li>
+ * </ul>
+ */
+ public abstract int validate(GraphicsConfiguration gc);
+
+ /**
+ * Returns true if the contents of the image buffer have been
+ * damaged or if the image buffer's resources have been reclaimed by
+ * the graphics system. You should call this method after a series
+ * of rendering operations to or from the image, to see if the image
+ * buffer needs to be revalidated or the image re-rendered.
+ *
+ * @return true if the validate should be called, false otherwise
+ */
+ public abstract boolean contentsLost();
+
+ /**
+ * Returns the capabilities of this image buffer.
+ *
+ * @return the capabilities of this image buffer
+ */
+ public abstract ImageCapabilities getCapabilities();
+
+ /**
+ * Returns the transparency type of this image.
+ *
+ * @return Transparency.OPAQUE, Transparency.BITMASK or
+ * Transparency.TRANSLUCENT
+ */
+ public int getTransparency()
+ {
+ return transparency;
+ }
+}
diff --git a/libjava/classpath/java/awt/image/WritableRaster.java b/libjava/classpath/java/awt/image/WritableRaster.java
new file mode 100644
index 0000000..2e5462f
--- /dev/null
+++ b/libjava/classpath/java/awt/image/WritableRaster.java
@@ -0,0 +1,265 @@
+/* Copyright (C) 2000, 2002, 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+/**
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public class WritableRaster extends Raster
+{
+ protected WritableRaster(SampleModel sampleModel, Point origin)
+ {
+ this(sampleModel, sampleModel.createDataBuffer(), origin);
+ }
+
+ protected WritableRaster(SampleModel sampleModel,
+ DataBuffer dataBuffer, Point origin)
+ {
+ this(sampleModel, dataBuffer,
+ new Rectangle(origin != null ? origin.x : 0,
+ origin != null ? origin.y : 0,
+ sampleModel.getWidth(), sampleModel.getHeight()),
+ origin,
+ null);
+ }
+
+ protected WritableRaster(SampleModel sampleModel,
+ DataBuffer dataBuffer,
+ Rectangle aRegion,
+ Point sampleModelTranslate,
+ WritableRaster parent)
+ {
+ super(sampleModel, dataBuffer, aRegion, sampleModelTranslate,
+ parent);
+ }
+
+ public WritableRaster getWritableParent()
+ {
+ return (WritableRaster) getParent();
+ }
+
+ public WritableRaster createWritableTranslatedChild(int childMinX,
+ int childMinY)
+ {
+ // This mirrors the code from the super class
+ int tcx = sampleModelTranslateX - minX + childMinX;
+ int tcy = sampleModelTranslateY - minY + childMinY;
+
+ return new WritableRaster(sampleModel, dataBuffer,
+ new Rectangle(childMinX, childMinY,
+ width, height),
+ new Point(tcx, tcy),
+ this);
+ }
+
+ public WritableRaster createWritableChild(int parentX,
+ int parentY,
+ int w, int h,
+ int childMinX,
+ int childMinY,
+ int[] bandList)
+ {
+ // This mirrors the code from the super class
+
+ // FIXME: Throw RasterFormatException if child bounds extends
+ // beyond the bounds of this raster.
+
+ SampleModel sm = (bandList == null) ?
+ sampleModel :
+ sampleModel.createSubsetSampleModel(bandList);
+
+ return new
+ WritableRaster(sm, dataBuffer,
+ new Rectangle(childMinX, childMinY,
+ w, h),
+ new Point(sampleModelTranslateX+childMinX-parentX,
+ sampleModelTranslateY+childMinY-parentY),
+ this);
+ }
+
+ public void setDataElements(int x, int y, Object inData)
+ {
+ sampleModel.setDataElements(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ inData, dataBuffer);
+ }
+
+ public void setDataElements(int x, int y, Raster inRaster)
+ {
+ Object dataElements = getDataElements(0, 0,
+ inRaster.getWidth(),
+ inRaster.getHeight(),
+ null);
+ setDataElements(x, y, dataElements);
+ }
+
+ public void setDataElements(int x, int y, int w, int h,
+ Object inData)
+ {
+ sampleModel.setDataElements(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, inData, dataBuffer);
+ }
+
+ public void setRect(Raster srcRaster)
+ {
+ setRect(0, 0, srcRaster);
+ }
+
+ public void setRect(int dx, int dy, Raster srcRaster)
+ {
+ Rectangle targetUnclipped = new Rectangle(srcRaster.getMinX()+dx,
+ srcRaster.getMinY()+dy,
+ srcRaster.getWidth(),
+ srcRaster.getHeight());
+
+ Rectangle target = getBounds().intersection(targetUnclipped);
+
+ if (target.isEmpty()) return;
+
+ int sx = target.x - dx;
+ int sy = target.y - dy;
+
+ // FIXME: Do tests on rasters and use get/set data instead.
+
+ /* The JDK documentation seems to imply this implementation.
+ (the trucation of higher bits), but an implementation using
+ get/setDataElements would be more efficient. None of the
+ implementations would do anything sensible when the sample
+ models don't match.
+
+ But this is probably not the place to consider such
+ optimizations.*/
+
+ int[] pixels = srcRaster.getPixels(sx, sy,
+ target.width, target.height,
+ (int[]) null);
+
+ setPixels(target.x, target.y, target.width, target.height, pixels);
+ }
+
+ public void setPixel(int x, int y, int[] iArray)
+ {
+ sampleModel.setPixel(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ iArray, dataBuffer);
+ }
+
+ public void setPixel(int x, int y, float[] fArray)
+ {
+ sampleModel.setPixel(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ fArray, dataBuffer);
+ }
+
+ public void setPixel(int x, int y, double[] dArray)
+ {
+ sampleModel.setPixel(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ dArray, dataBuffer);
+ }
+
+ public void setPixels(int x, int y, int w, int h, int[] iArray)
+ {
+ sampleModel.setPixels(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, iArray, dataBuffer);
+ }
+
+ public void setPixels(int x, int y, int w, int h, float[] fArray)
+ {
+ sampleModel.setPixels(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, fArray, dataBuffer);
+ }
+
+ public void setPixels(int x, int y, int w, int h, double[] dArray)
+ {
+ sampleModel.setPixels(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, dArray, dataBuffer);
+ }
+
+ public void setSample(int x, int y, int b, int s)
+ {
+ sampleModel.setSample(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ b, s, dataBuffer);
+ }
+
+ public void setSample(int x, int y, int b, float s)
+ {
+ sampleModel.setSample(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ b, s, dataBuffer);
+ }
+
+ public void setSample(int x, int y, int b, double s)
+ {
+ sampleModel.setSample(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ b, s, dataBuffer);
+ }
+
+ public void setSamples(int x, int y, int w, int h, int b,
+ int[] iArray)
+ {
+ sampleModel.setSamples(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, b, iArray, dataBuffer);
+ }
+
+ public void setSamples(int x, int y, int w, int h, int b,
+ float[] fArray)
+ {
+ sampleModel.setSamples(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, b, fArray, dataBuffer);
+ }
+
+ public void setSamples(int x, int y, int w, int h, int b,
+ double[] dArray)
+ {
+ sampleModel.setSamples(x-sampleModelTranslateX,
+ y-sampleModelTranslateY,
+ w, h, b, dArray, dataBuffer);
+ }
+}
diff --git a/libjava/classpath/java/awt/image/WritableRenderedImage.java b/libjava/classpath/java/awt/image/WritableRenderedImage.java
new file mode 100644
index 0000000..4ed9f10
--- /dev/null
+++ b/libjava/classpath/java/awt/image/WritableRenderedImage.java
@@ -0,0 +1,56 @@
+/* WritableRenderedImage.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import java.awt.Point;
+
+/**
+ * NEEDS DOCUMENTATION
+ */
+public interface WritableRenderedImage extends RenderedImage
+{
+ void addTileObserver(TileObserver to);
+ void removeTileObserver(TileObserver to);
+ WritableRaster getWritableTile(int x, int y);
+ void releaseWritableTile(int x, int y);
+ boolean isTileWritable(int x, int y);
+ Point[] getWritableTileIndices();
+ boolean hasTileWriters();
+ void setData(Raster r);
+} // interface WritableRenderedImage
diff --git a/libjava/classpath/java/awt/image/package.html b/libjava/classpath/java/awt/image/package.html
new file mode 100644
index 0000000..50fa99d
--- /dev/null
+++ b/libjava/classpath/java/awt/image/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.image package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.image</title></head>
+
+<body>
+<p>Image consumers, producers and filters.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/image/renderable/ContextualRenderedImageFactory.java b/libjava/classpath/java/awt/image/renderable/ContextualRenderedImageFactory.java
new file mode 100644
index 0000000..729d857
--- /dev/null
+++ b/libjava/classpath/java/awt/image/renderable/ContextualRenderedImageFactory.java
@@ -0,0 +1,56 @@
+/* ContextualRenderedImageFactory.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image.renderable;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+
+/**
+ * STUBBED
+ */
+public interface ContextualRenderedImageFactory extends RenderedImageFactory
+{
+ RenderContext mapRenderContext(int i, RenderContext context,
+ ParameterBlock block, RenderableImage image);
+ RenderedImage create(RenderContext context, ParameterBlock block);
+ Rectangle2D getBounds2D(ParameterBlock block);
+ Object getProperty(ParameterBlock block, String name);
+ String[] getPropertyNames();
+ boolean isDynamic();
+} // interface ContextualRenderedImageFactory
diff --git a/libjava/classpath/java/awt/image/renderable/ParameterBlock.java b/libjava/classpath/java/awt/image/renderable/ParameterBlock.java
new file mode 100644
index 0000000..879d3c4
--- /dev/null
+++ b/libjava/classpath/java/awt/image/renderable/ParameterBlock.java
@@ -0,0 +1,308 @@
+/* ParameterBlock.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image.renderable;
+
+import java.awt.image.RenderedImage;
+import java.io.Serializable;
+import java.util.Vector;
+
+public class ParameterBlock implements Cloneable, Serializable
+{
+ private static final long serialVersionUID = -7577115551785240750L;
+ protected Vector sources;
+ protected Vector parameters;
+
+ public ParameterBlock()
+ {
+ this(new Vector(), new Vector());
+ }
+
+ public ParameterBlock(Vector sources)
+ {
+ this(sources, new Vector());
+ }
+
+ public ParameterBlock(Vector sources, Vector parameters)
+ {
+ this.sources = sources;
+ this.parameters = parameters;
+ }
+
+ public Object shallowClone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // impossible
+ }
+ }
+
+ public Object clone()
+ {
+ ParameterBlock pb = (ParameterBlock) shallowClone();
+ if (sources != null)
+ pb.sources = (Vector) sources.clone();
+ if (parameters != null)
+ pb.parameters = (Vector) parameters.clone();
+ return pb;
+ }
+
+ public ParameterBlock addSource(Object source)
+ {
+ sources.add(source);
+ return this;
+ }
+
+ public Object getSource(int index)
+ {
+ return sources.get(index);
+ }
+
+ public ParameterBlock setSource(Object source, int index)
+ {
+ sources.ensureCapacity(index);
+ sources.set(index, source);
+ return this;
+ }
+
+ public RenderedImage getRenderedSource(int index)
+ {
+ return (RenderedImage) sources.get(index);
+ }
+
+ public RenderableImage getRenderableSource(int index)
+ {
+ return (RenderableImage) sources.get(index);
+ }
+
+ public int getNumSources()
+ {
+ return sources.size();
+ }
+
+ public Vector getSources()
+ {
+ return sources;
+ }
+
+ public void setSources(Vector sources)
+ {
+ this.sources = sources;
+ }
+
+ public void removeSources()
+ {
+ if (sources != null)
+ sources.clear();
+ }
+
+ public int getNumParameters()
+ {
+ return parameters.size();
+ }
+
+ public Vector getParameters()
+ {
+ return parameters;
+ }
+
+ public void setParameters(Vector parameters)
+ {
+ this.parameters = parameters;
+ }
+
+ public void removeParameters()
+ {
+ if (parameters != null)
+ parameters.clear();
+ }
+
+ public ParameterBlock add(Object o)
+ {
+ parameters.add(o);
+ return this;
+ }
+
+ public ParameterBlock add(byte b)
+ {
+ return add(new Byte(b));
+ }
+
+ public ParameterBlock add(char c)
+ {
+ return add(new Character(c));
+ }
+
+ public ParameterBlock add(short s)
+ {
+ return add(new Short(s));
+ }
+
+ public ParameterBlock add(int i)
+ {
+ return add(new Integer(i));
+ }
+
+ public ParameterBlock add(long l)
+ {
+ return add(new Long(l));
+ }
+
+ public ParameterBlock add(float f)
+ {
+ return add(new Float(f));
+ }
+
+ public ParameterBlock add(double d)
+ {
+ return add(new Double(d));
+ }
+
+ public ParameterBlock set(Object o, int index)
+ {
+ parameters.ensureCapacity(index);
+ parameters.set(index, o);
+ return this;
+ }
+
+ public ParameterBlock set(byte b, int index)
+ {
+ return set(new Byte(b), index);
+ }
+
+ public ParameterBlock set(char c, int index)
+ {
+ return set(new Character(c), index);
+ }
+
+ public ParameterBlock set(short s, int index)
+ {
+ return set(new Short(s), index);
+ }
+
+ public ParameterBlock set(int i, int index)
+ {
+ return set(new Integer(i), index);
+ }
+
+ public ParameterBlock set(long l, int index)
+ {
+ return set(new Long(l), index);
+ }
+
+ public ParameterBlock set(float f, int index)
+ {
+ return set(new Float(f), index);
+ }
+
+ public ParameterBlock set(double d, int index)
+ {
+ return set(new Double(d), index);
+ }
+
+ public Object getObjectParameter(int index)
+ {
+ return parameters.get(index);
+ }
+
+ public byte getByteParameter(int index)
+ {
+ return ((Byte) parameters.get(index)).byteValue();
+ }
+
+ public char getCharParameter(int index)
+ {
+ return ((Character) parameters.get(index)).charValue();
+ }
+
+ public short getShortParameter(int index)
+ {
+ return ((Short) parameters.get(index)).shortValue();
+ }
+
+ public int getIntParameter(int index)
+ {
+ return ((Integer) parameters.get(index)).intValue();
+ }
+
+ public long getLongParameter(int index)
+ {
+ return ((Long) parameters.get(index)).longValue();
+ }
+
+ public float getFloatParameter(int index)
+ {
+ return ((Float) parameters.get(index)).floatValue();
+ }
+
+ public double getDoubleParameter(int index)
+ {
+ return ((Double) parameters.get(index)).doubleValue();
+ }
+
+ public Class[] getParamClasses()
+ {
+ int i = parameters.size();
+ Class[] result = new Class[i];
+ while (--i >= 0)
+ {
+ Class c = parameters.get(i).getClass();
+ if (c == Byte.class)
+ result[i] = byte.class;
+ else if (c == Character.class)
+ result[i] = char.class;
+ else if (c == Short.class)
+ result[i] = short.class;
+ else if (c == Integer.class)
+ result[i] = int.class;
+ else if (c == Long.class)
+ result[i] = long.class;
+ else if (c == Float.class)
+ result[i] = float.class;
+ else if (c == Double.class)
+ result[i] = double.class;
+ else
+ result[i] = c;
+ }
+ return result;
+ }
+} // class ParameterBlock
diff --git a/libjava/classpath/java/awt/image/renderable/RenderContext.java b/libjava/classpath/java/awt/image/renderable/RenderContext.java
new file mode 100644
index 0000000..67f0b8a
--- /dev/null
+++ b/libjava/classpath/java/awt/image/renderable/RenderContext.java
@@ -0,0 +1,141 @@
+/* RenderContext.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+
+public class RenderContext implements Cloneable
+{
+ private AffineTransform xform;
+ private Shape aoi;
+ private RenderingHints hints;
+
+ public RenderContext(AffineTransform xform, Shape aoi, RenderingHints hints)
+ {
+ this.xform = xform;
+ this.aoi = aoi;
+ this.hints = hints;
+ }
+
+ public RenderContext(AffineTransform xform)
+ {
+ this(xform, null, null);
+ }
+
+ public RenderContext(AffineTransform xform, RenderingHints hints)
+ {
+ this(xform, null, hints);
+ }
+
+ public RenderContext(AffineTransform xform, Shape aoi)
+ {
+ this(xform, aoi, null);
+ }
+
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ public void setRenderingHints(RenderingHints hints)
+ {
+ this.hints = hints;
+ }
+
+ public void setTransform(AffineTransform xform)
+ {
+ this.xform = xform;
+ }
+
+ public void preConcatenateTransform(AffineTransform pre)
+ {
+ preConcetenateTransform (pre);
+ }
+
+ /** @deprecated */
+ public void preConcetenateTransform(AffineTransform pre)
+ {
+ xform.preConcatenate (pre);
+ }
+
+ public void concatenateTransform(AffineTransform post)
+ {
+ concetenateTransform (post);
+ }
+
+ /** @deprecated */
+ public void concetenateTransform(AffineTransform post)
+ {
+ xform.concatenate (post);
+ }
+
+ public AffineTransform getTransform()
+ {
+ return xform;
+ }
+
+ public void setAreaOfInterest(Shape aoi)
+ {
+ this.aoi = aoi;
+ }
+
+ public Shape getAreaOfInterest()
+ {
+ return aoi;
+ }
+
+ public Object clone()
+ {
+ try
+ {
+ RenderContext copy = (RenderContext) super.clone();
+ if (xform != null)
+ copy.xform = (AffineTransform) xform.clone();
+ if (hints != null)
+ copy.hints = (RenderingHints) hints.clone();
+ return copy;
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw (Error) new InternalError().initCause(e); // impossible
+ }
+ }
+} // class RenderContext
diff --git a/libjava/classpath/java/awt/image/renderable/RenderableImage.java b/libjava/classpath/java/awt/image/renderable/RenderableImage.java
new file mode 100644
index 0000000..45d2eb7
--- /dev/null
+++ b/libjava/classpath/java/awt/image/renderable/RenderableImage.java
@@ -0,0 +1,62 @@
+/* RenderableImage.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+public interface RenderableImage
+{
+ String HINTS_OBSERVED = "HINTS_OBSERVED";
+
+ Vector getSources();
+ Object getProperty(String name);
+ String[] getPropertyNames();
+ boolean isDynamic();
+ float getWidth();
+ float getHeight();
+ float getMinX();
+ float getMinY();
+ RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
+ RenderedImage createDefaultRendering();
+ RenderedImage createRendering(RenderContext context);
+
+} // interface RenderableImage
+
diff --git a/libjava/classpath/java/awt/image/renderable/RenderableImageOp.java b/libjava/classpath/java/awt/image/renderable/RenderableImageOp.java
new file mode 100644
index 0000000..5385a82
--- /dev/null
+++ b/libjava/classpath/java/awt/image/renderable/RenderableImageOp.java
@@ -0,0 +1,157 @@
+/* RenderableImageOp.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+public class RenderableImageOp implements RenderableImage
+{
+ private final ContextualRenderedImageFactory crif;
+ private ParameterBlock block;
+
+ public RenderableImageOp(ContextualRenderedImageFactory crif,
+ ParameterBlock block)
+ {
+ this.crif = crif;
+ this.block = (ParameterBlock) block.clone();
+ }
+
+ public Vector getSources()
+ {
+ if (block.sources == null)
+ return null;
+ int size = block.sources.size();
+ Vector v = new Vector();
+ for (int i = 0; i < size; i++)
+ {
+ Object o = block.sources.get(i);
+ if (o instanceof RenderableImage)
+ v.add(o);
+ }
+ return v;
+ }
+
+ public Object getProperty(String name)
+ {
+ return crif.getProperty(block, name);
+ }
+
+ public String[] getPropertyNames()
+ {
+ return crif.getPropertyNames();
+ }
+
+ public boolean isDynamic()
+ {
+ return crif.isDynamic();
+ }
+
+ public float getWidth()
+ {
+ return (float) crif.getBounds2D(block).getWidth();
+ }
+
+ public float getHeight()
+ {
+ return (float) crif.getBounds2D(block).getHeight();
+ }
+
+ public float getMinX()
+ {
+ return (float) crif.getBounds2D(block).getX();
+ }
+
+ public float getMinY()
+ {
+ return (float) crif.getBounds2D(block).getY();
+ }
+
+ public ParameterBlock setParameterBlock(ParameterBlock block)
+ {
+ ParameterBlock result = this.block;
+ this.block = (ParameterBlock) block.clone();
+ return result;
+ }
+
+ public ParameterBlock getParameterBlock()
+ {
+ return block;
+ }
+
+ public RenderedImage createScaledRendering(int w, int h,
+ RenderingHints hints)
+ {
+ if (w == 0)
+ if (h == 0)
+ throw new IllegalArgumentException();
+ else
+ w = Math.round(h * getWidth() / getHeight());
+ if (h == 0)
+ h = Math.round(w * getHeight() / getWidth());
+ AffineTransform xform = AffineTransform.getScaleInstance(w * getWidth(),
+ h * getHeight());
+ return createRendering(new RenderContext(xform, hints));
+ }
+
+ public RenderedImage createDefaultRendering()
+ {
+ return createRendering(new RenderContext(new AffineTransform()));
+ }
+
+ public RenderedImage createRendering(RenderContext context)
+ {
+ ParameterBlock copy = (ParameterBlock) block.clone();
+ int i = block.sources.size();
+ while (--i >= 0)
+ {
+ Object o = block.sources.get(i);
+ if (o instanceof RenderableImage)
+ {
+ RenderableImage ri = (RenderableImage) o;
+ RenderContext rc = crif.mapRenderContext(i, context, block, ri);
+ copy.sources.set(i, ri.createRendering(rc));
+ }
+ }
+ // Now copy.sources should be only RenderedImages.
+ return crif.create(context, copy);
+ }
+} // class RenderableImageOp
diff --git a/libjava/classpath/java/awt/image/renderable/RenderableImageProducer.java b/libjava/classpath/java/awt/image/renderable/RenderableImageProducer.java
new file mode 100644
index 0000000..78f3051
--- /dev/null
+++ b/libjava/classpath/java/awt/image/renderable/RenderableImageProducer.java
@@ -0,0 +1,79 @@
+/* RenderableImageProducer.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image.renderable;
+
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+
+public class RenderableImageProducer implements ImageProducer, Runnable
+{
+ public RenderableImageProducer(RenderableImage image, RenderContext context)
+ {
+ throw new Error("not implemented");
+ }
+
+ public void setRenderContext(RenderContext context)
+ {
+ }
+
+ public void addConsumer(ImageConsumer consumer)
+ {
+ }
+
+ public boolean isConsumer(ImageConsumer consumer)
+ {
+ return false;
+ }
+
+ public void removeConsumer(ImageConsumer consumer)
+ {
+ }
+
+ public void startProduction(ImageConsumer consumer)
+ {
+ }
+
+ public void requestTopDownLeftRightResend(ImageConsumer consumer)
+ {
+ }
+
+ public void run()
+ {
+ }
+} // class RenderableImageProducer
diff --git a/libjava/classpath/java/awt/image/renderable/RenderedImageFactory.java b/libjava/classpath/java/awt/image/renderable/RenderedImageFactory.java
new file mode 100644
index 0000000..6ff4cb0
--- /dev/null
+++ b/libjava/classpath/java/awt/image/renderable/RenderedImageFactory.java
@@ -0,0 +1,47 @@
+/* RenderedImageFactory.java --
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+
+public interface RenderedImageFactory
+{
+ RenderedImage create(ParameterBlock block, RenderingHints hints);
+} // interface RenderedImageFactory
diff --git a/libjava/classpath/java/awt/image/renderable/package.html b/libjava/classpath/java/awt/image/renderable/package.html
new file mode 100644
index 0000000..a24237e
--- /dev/null
+++ b/libjava/classpath/java/awt/image/renderable/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.image.renderable package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.image.renderable</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/package.html b/libjava/classpath/java/awt/package.html
new file mode 100644
index 0000000..c5ff988
--- /dev/null
+++ b/libjava/classpath/java/awt/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt</title></head>
+
+<body>
+<p>Abstract Window Toolkit classes.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/peer/ButtonPeer.java b/libjava/classpath/java/awt/peer/ButtonPeer.java
new file mode 100644
index 0000000..a55fc22
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/ButtonPeer.java
@@ -0,0 +1,46 @@
+/* ButtonPeer.java -- Peer interface for buttons
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface ButtonPeer extends ComponentPeer
+{
+ void setLabel (String label);
+
+} // interface ButtonPeer
+
diff --git a/libjava/classpath/java/awt/peer/CanvasPeer.java b/libjava/classpath/java/awt/peer/CanvasPeer.java
new file mode 100644
index 0000000..4b33835
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/CanvasPeer.java
@@ -0,0 +1,45 @@
+/* CanvasPeer.java -- Peer interface for a canvas
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface CanvasPeer extends ComponentPeer
+{
+
+} // interface CanvasPeer
+
diff --git a/libjava/classpath/java/awt/peer/CheckboxMenuItemPeer.java b/libjava/classpath/java/awt/peer/CheckboxMenuItemPeer.java
new file mode 100644
index 0000000..5213dc9
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/CheckboxMenuItemPeer.java
@@ -0,0 +1,46 @@
+/* CheckboxMenuItemPeer.java -- Peer interface for checkbox menu items
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface CheckboxMenuItemPeer extends MenuItemPeer
+{
+ void setState (boolean state);
+
+} // interface CheckboxMenuItemPeer
+
diff --git a/libjava/classpath/java/awt/peer/CheckboxPeer.java b/libjava/classpath/java/awt/peer/CheckboxPeer.java
new file mode 100644
index 0000000..8b23b3f
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/CheckboxPeer.java
@@ -0,0 +1,52 @@
+/* CheckboxPeer.java -- Interface for checkbox peer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.CheckboxGroup;
+
+public interface CheckboxPeer extends ComponentPeer
+{
+ void setCheckboxGroup (CheckboxGroup group);
+
+ void setLabel (String label);
+
+ void setState (boolean state);
+
+} // interface CheckboxPeer
+
diff --git a/libjava/classpath/java/awt/peer/ChoicePeer.java b/libjava/classpath/java/awt/peer/ChoicePeer.java
new file mode 100644
index 0000000..8ed1107
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/ChoicePeer.java
@@ -0,0 +1,54 @@
+/* ChoicePeer.java -- Peer for choice box
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface ChoicePeer extends ComponentPeer
+{
+ void add (String item, int index);
+
+ void addItem (String item, int index);
+
+ void remove (int index);
+
+ void removeAll();
+
+ void select (int index);
+
+} // interface ChoicePeer
+
diff --git a/libjava/classpath/java/awt/peer/ComponentPeer.java b/libjava/classpath/java/awt/peer/ComponentPeer.java
new file mode 100644
index 0000000..7ed8f60
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/ComponentPeer.java
@@ -0,0 +1,187 @@
+/* ComponentPeer.java -- Toplevel component peer
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.BufferCapabilities;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.event.PaintEvent;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+
+public interface ComponentPeer
+{
+ int checkImage(Image img, int width, int height,
+ ImageObserver ob);
+ Image createImage(ImageProducer prod);
+ Image createImage(int width, int height);
+ void disable();
+ void dispose();
+ void enable();
+ ColorModel getColorModel();
+ FontMetrics getFontMetrics(Font f);
+ Graphics getGraphics();
+ Point getLocationOnScreen();
+ Dimension getMinimumSize();
+ Dimension getPreferredSize();
+ Toolkit getToolkit();
+ void handleEvent(AWTEvent e);
+ void hide();
+
+ /**
+ * Part of the earlier 1.1 API, replaced by isFocusable().
+ */
+ boolean isFocusTraversable();
+ boolean isFocusable();
+ Dimension minimumSize();
+ Dimension preferredSize();
+ void paint(Graphics graphics);
+ boolean prepareImage(Image img, int width, int height,
+ ImageObserver ob);
+ void print(Graphics graphics);
+ void repaint(long tm, int x, int y, int width, int height);
+
+ /**
+ * Part of the earlier 1.1 API, apparently replaced by argument
+ * form of the same method.
+ */
+ void requestFocus();
+ boolean requestFocus (Component source, boolean bool1, boolean bool2, long x);
+
+ void reshape(int x, int y, int width, int height);
+ void setBackground(Color color);
+ void setBounds(int x, int y, int width, int height);
+
+ /**
+ * Part of the earlier 1.1 API, apparently no longer needed.
+ */
+ void setCursor(Cursor cursor);
+
+ void setEnabled(boolean enabled);
+ void setFont(Font font);
+ void setForeground(Color color);
+ void setVisible(boolean visible);
+ void show();
+
+ /**
+ * Get the graphics configuration of the component. The color model
+ * of the component can be derived from the configuration.
+ */
+ GraphicsConfiguration getGraphicsConfiguration();
+
+ /**
+ * Part of an older API, no longer needed.
+ */
+ void setEventMask (long mask);
+
+ // Methods below are introduced since 1.1
+ boolean isObscured();
+ boolean canDetermineObscurity();
+ void coalescePaintEvent(PaintEvent e);
+ void updateCursorImmediately();
+ boolean handlesWheelScrolling();
+
+ /**
+ * A convenience method that creates a volatile image. The volatile
+ * image is created on the screen device on which this component is
+ * displayed, in the device's current graphics configuration.
+ *
+ * @param width width of the image
+ * @param height height of the image
+ *
+ * @see VolatileImage
+ *
+ * @since 1.2
+ */
+ VolatileImage createVolatileImage(int width, int height);
+
+ /**
+ * Create a number of image buffers that implement a buffering
+ * strategy according to the given capabilities.
+ *
+ * @param numBuffers the number of buffers
+ * @param caps the buffering capabilities
+ *
+ * @throws AWTException if the specified buffering strategy is not
+ * implemented
+ *
+ * @since 1.2
+ */
+ void createBuffers(int numBuffers, BufferCapabilities caps)
+ throws AWTException;
+
+ /**
+ * Return the back buffer of this component.
+ *
+ * @return the back buffer of this component.
+ *
+ * @since 1.2
+ */
+ Image getBackBuffer();
+
+ /**
+ * Perform a page flip, leaving the contents of the back buffer in
+ * the specified state.
+ *
+ * @param contents the state in which to leave the back buffer
+ *
+ * @since 1.2
+ */
+ void flip(BufferCapabilities.FlipContents contents);
+
+ /**
+ * Destroy the resources created by createBuffers.
+ *
+ * @since 1.2
+ */
+ void destroyBuffers();
+}
diff --git a/libjava/classpath/java/awt/peer/ContainerPeer.java b/libjava/classpath/java/awt/peer/ContainerPeer.java
new file mode 100644
index 0000000..f1373a1
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/ContainerPeer.java
@@ -0,0 +1,59 @@
+/* ContainerPeer.java -- Interface for container peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.peer;
+
+import java.awt.Insets;
+
+public interface ContainerPeer extends ComponentPeer
+{
+ Insets insets();
+
+ Insets getInsets();
+
+ void beginValidate();
+
+ void endValidate();
+
+ void beginLayout();
+
+ void endLayout();
+
+ boolean isPaintPending();
+
+} // interface ContainerPeer
+
diff --git a/libjava/classpath/java/awt/peer/DialogPeer.java b/libjava/classpath/java/awt/peer/DialogPeer.java
new file mode 100644
index 0000000..e26d64f
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/DialogPeer.java
@@ -0,0 +1,48 @@
+/* DialogPeer.java -- Interface for dialog box peer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface DialogPeer extends WindowPeer
+{
+ void setResizable (boolean resizeable);
+
+ void setTitle (String title);
+
+} // interface DialogPeer
+
diff --git a/libjava/classpath/java/awt/peer/FileDialogPeer.java b/libjava/classpath/java/awt/peer/FileDialogPeer.java
new file mode 100644
index 0000000..7db1798
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/FileDialogPeer.java
@@ -0,0 +1,52 @@
+/* FileDialogPeer.java -- Interface for file selection dialog box peer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.io.FilenameFilter;
+
+public interface FileDialogPeer extends DialogPeer
+{
+ void setFile (String file);
+
+ void setDirectory (String dir);
+
+ void setFilenameFilter (FilenameFilter ff);
+
+} // interface FileDialogPeer
+
diff --git a/libjava/classpath/java/awt/peer/FontPeer.java b/libjava/classpath/java/awt/peer/FontPeer.java
new file mode 100644
index 0000000..f0ba6d8
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/FontPeer.java
@@ -0,0 +1,45 @@
+/* FontPeer.java -- Interface for font peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface FontPeer
+{
+
+} // interface FontPeer
+
diff --git a/libjava/classpath/java/awt/peer/FramePeer.java b/libjava/classpath/java/awt/peer/FramePeer.java
new file mode 100644
index 0000000..13498ff
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/FramePeer.java
@@ -0,0 +1,55 @@
+/* FramePeer.java -- Interface for frame peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Image;
+import java.awt.MenuBar;
+import java.awt.Rectangle;
+
+public interface FramePeer extends WindowPeer
+{
+ void setIconImage(Image image);
+ void setMenuBar(MenuBar mb);
+ void setResizable(boolean resizable);
+ void setTitle(String title);
+ int getState();
+ void setState(int state);
+ void setMaximizedBounds(Rectangle r);
+} // interface FramePeer
+
diff --git a/libjava/classpath/java/awt/peer/LabelPeer.java b/libjava/classpath/java/awt/peer/LabelPeer.java
new file mode 100644
index 0000000..d0fca46
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/LabelPeer.java
@@ -0,0 +1,46 @@
+/* LabelPeer.java -- Interface for simple text lable peer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface LabelPeer extends ComponentPeer
+{
+ void setAlignment(int alignment);
+ void setText(String text);
+} // interface LabelPeer
+
diff --git a/libjava/classpath/java/awt/peer/LightweightPeer.java b/libjava/classpath/java/awt/peer/LightweightPeer.java
new file mode 100644
index 0000000..93cad7a
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/LightweightPeer.java
@@ -0,0 +1,45 @@
+/* LightweightPeer.java -- Interface for lightweight peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface LightweightPeer extends ComponentPeer
+{
+
+} // interface LightweightPeer
+
diff --git a/libjava/classpath/java/awt/peer/ListPeer.java b/libjava/classpath/java/awt/peer/ListPeer.java
new file mode 100644
index 0000000..c0f765d
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/ListPeer.java
@@ -0,0 +1,61 @@
+/* ListPeer.java -- Interface for list box peer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Dimension;
+
+public interface ListPeer extends ComponentPeer
+{
+ void add(String item, int index);
+ void addItem(String item, int index);
+ void clear();
+ void delItems(int start_index, int end_index);
+ void deselect(int index);
+ int[] getSelectedIndexes();
+ void makeVisible(int index);
+ Dimension minimumSize(int s);
+ Dimension preferredSize(int s);
+ void removeAll();
+ void select(int index);
+ void setMultipleMode(boolean multi);
+ void setMultipleSelections(boolean multi);
+ Dimension getPreferredSize(int s);
+ Dimension getMinimumSize(int s);
+} // interface ListPeer
+
diff --git a/libjava/classpath/java/awt/peer/MenuBarPeer.java b/libjava/classpath/java/awt/peer/MenuBarPeer.java
new file mode 100644
index 0000000..c5f7c58
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/MenuBarPeer.java
@@ -0,0 +1,48 @@
+/* MenuBarPeer.java -- Interface for menu bar peer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Menu;
+
+public interface MenuBarPeer extends MenuComponentPeer
+{
+ void addHelpMenu(Menu menu);
+ void delMenu(int index);
+} // interface MenuBarPeer
+
diff --git a/libjava/classpath/java/awt/peer/MenuComponentPeer.java b/libjava/classpath/java/awt/peer/MenuComponentPeer.java
new file mode 100644
index 0000000..1b10ca1
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/MenuComponentPeer.java
@@ -0,0 +1,45 @@
+/* MenuComponentPeer.java --
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface MenuComponentPeer
+{
+ void dispose();
+} // interface MenuComponentPeer
+
diff --git a/libjava/classpath/java/awt/peer/MenuItemPeer.java b/libjava/classpath/java/awt/peer/MenuItemPeer.java
new file mode 100644
index 0000000..3ba1027
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/MenuItemPeer.java
@@ -0,0 +1,48 @@
+/* MenuItemPeer.java -- Interface for menu item peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface MenuItemPeer extends MenuComponentPeer
+{
+ void disable();
+ void enable();
+ void setEnabled(boolean enabled);
+ void setLabel(String text);
+} // interface MenuItemPeer
+
diff --git a/libjava/classpath/java/awt/peer/MenuPeer.java b/libjava/classpath/java/awt/peer/MenuPeer.java
new file mode 100644
index 0000000..c51ea73
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/MenuPeer.java
@@ -0,0 +1,48 @@
+/* MenuPeer.java -- Interface for menu peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.MenuItem;
+
+public interface MenuPeer extends MenuItemPeer
+{
+ void addItem (MenuItem item);
+ void delItem (int index);
+}
+
diff --git a/libjava/classpath/java/awt/peer/PanelPeer.java b/libjava/classpath/java/awt/peer/PanelPeer.java
new file mode 100644
index 0000000..192632e
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/PanelPeer.java
@@ -0,0 +1,45 @@
+/* PanelPeer.java -- Interface for panel peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface PanelPeer extends ContainerPeer
+{
+
+} // interface PanelPeer
+
diff --git a/libjava/classpath/java/awt/peer/PopupMenuPeer.java b/libjava/classpath/java/awt/peer/PopupMenuPeer.java
new file mode 100644
index 0000000..2e8f4bb
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/PopupMenuPeer.java
@@ -0,0 +1,53 @@
+/* PopupMenuPeer.java -- Interface for popup menu peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Component;
+import java.awt.Event;
+
+public interface PopupMenuPeer extends MenuPeer
+{
+ /**
+ * Part of the older API, replaced by event version instead.
+ */
+ void show (Component origin, int x, int y);
+
+ void show (Event e);
+} // interface PopupMenuPeer
+
diff --git a/libjava/classpath/java/awt/peer/RobotPeer.java b/libjava/classpath/java/awt/peer/RobotPeer.java
new file mode 100644
index 0000000..db81c80
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/RobotPeer.java
@@ -0,0 +1,54 @@
+/* RobotPeer.java -- Interface for programatically driving GUI
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Rectangle;
+
+public interface RobotPeer
+{
+ void mouseMove (int x, int y);
+ void mousePress (int buttons);
+ void mouseRelease (int buttons);
+ void mouseWheel (int wheelAmt);
+ void keyPress (int keycode);
+ void keyRelease (int keycode);
+ int getRGBPixel (int x, int y);
+ int[] getRGBPixels (Rectangle screen);
+} // interface RobotPeer
+
diff --git a/libjava/classpath/java/awt/peer/ScrollPanePeer.java b/libjava/classpath/java/awt/peer/ScrollPanePeer.java
new file mode 100644
index 0000000..de4331e
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/ScrollPanePeer.java
@@ -0,0 +1,52 @@
+/* ScrollPanePeer.java -- Interface for scrollable panes
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Adjustable;
+
+public interface ScrollPanePeer extends ContainerPeer
+{
+ int getHScrollbarHeight();
+ int getVScrollbarWidth();
+ void setScrollPosition(int h, int v);
+ void childResized(int width, int height);
+ void setUnitIncrement(Adjustable item, int inc);
+ void setValue(Adjustable item, int value);
+} // interface ScollPanePeer
+
diff --git a/libjava/classpath/java/awt/peer/ScrollbarPeer.java b/libjava/classpath/java/awt/peer/ScrollbarPeer.java
new file mode 100644
index 0000000..fe4f24d
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/ScrollbarPeer.java
@@ -0,0 +1,47 @@
+/* ScrollbarPeer.java -- Interface for scrollbar peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface ScrollbarPeer extends ComponentPeer
+{
+ void setLineIncrement(int inc);
+ void setPageIncrement(int inc);
+ void setValues(int value, int visible, int min, int max);
+} // interface ScrollbarPeer
+
diff --git a/libjava/classpath/java/awt/peer/TextAreaPeer.java b/libjava/classpath/java/awt/peer/TextAreaPeer.java
new file mode 100644
index 0000000..354e46d
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/TextAreaPeer.java
@@ -0,0 +1,53 @@
+/* TextAreaPeer.java -- Interface for text area peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Dimension;
+
+public interface TextAreaPeer extends TextComponentPeer
+{
+ void insert(String text, int pos);
+ void insertText(String text, int pos);
+ Dimension minimumSize(int rows, int cols);
+ Dimension getMinimumSize(int rows, int cols);
+ Dimension preferredSize(int rows, int cols);
+ Dimension getPreferredSize(int rows, int cols);
+ void replaceRange(String text, int start_pos, int end_pos);
+ void replaceText(String text, int start_pos, int end_pos);
+} // interface TextAreaPeer
diff --git a/libjava/classpath/java/awt/peer/TextComponentPeer.java b/libjava/classpath/java/awt/peer/TextComponentPeer.java
new file mode 100644
index 0000000..cacc7d8
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/TextComponentPeer.java
@@ -0,0 +1,57 @@
+/* TextComponentPeer.java -- Superclass interface for text components
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Rectangle;
+
+public interface TextComponentPeer extends ComponentPeer
+{
+ int getSelectionEnd();
+ int getSelectionStart();
+ String getText();
+ void setText(String text);
+ void select(int start_pos, int end_pos);
+ void setEditable(boolean editable);
+ int getCaretPosition();
+ void setCaretPosition(int pos);
+ int getIndexAtPoint(int x, int y);
+ Rectangle getCharacterBounds(int pos);
+ long filterEvents(long filter);
+} // interface TextComponentPeer
+
diff --git a/libjava/classpath/java/awt/peer/TextFieldPeer.java b/libjava/classpath/java/awt/peer/TextFieldPeer.java
new file mode 100644
index 0000000..e68d666
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/TextFieldPeer.java
@@ -0,0 +1,52 @@
+/* TextFieldPeer.java -- Interface for text field peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+import java.awt.Dimension;
+
+public interface TextFieldPeer extends TextComponentPeer
+{
+ Dimension minimumSize(int len);
+ Dimension preferredSize(int len);
+ Dimension getMinimumSize(int len);
+ Dimension getPreferredSize(int len);
+ void setEchoChar(char echo_char);
+ void setEchoCharacter(char echo_char);
+} // interface TextFieldPeer
+
diff --git a/libjava/classpath/java/awt/peer/WindowPeer.java b/libjava/classpath/java/awt/peer/WindowPeer.java
new file mode 100644
index 0000000..8f136dd
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/WindowPeer.java
@@ -0,0 +1,46 @@
+/* WindowPeer.java -- Interface for window peers
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.peer;
+
+public interface WindowPeer extends ContainerPeer
+{
+ void toBack();
+ void toFront();
+} // interface WindowPeer
+
diff --git a/libjava/classpath/java/awt/peer/package.html b/libjava/classpath/java/awt/peer/package.html
new file mode 100644
index 0000000..7a7458c
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.peer package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.peer</title></head>
+
+<body>
+<p>Interfaces for using native interface components.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/java/awt/print/Book.java b/libjava/classpath/java/awt/print/Book.java
new file mode 100644
index 0000000..b084a17
--- /dev/null
+++ b/libjava/classpath/java/awt/print/Book.java
@@ -0,0 +1,159 @@
+/* Book.java -- A mixed group of pages to print.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+import java.util.Vector;
+
+/**
+ * This class allows documents to be created with different paper types,
+ * page formatters, and painters.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class Book implements Pageable
+{
+ /**
+ * Painter objects for the book.
+ */
+ Vector printables = new Vector();
+
+ /**
+ * Page formats for the book.
+ */
+ Vector page_formats = new Vector();
+
+ /**
+ * Initializes a new instance of <code>Book</code> that is empty.
+ */
+ public Book()
+ {
+ }
+
+ /**
+ * Returns the number of pages in this book.
+ *
+ * @return The number of pages in this book.
+ */
+ public int getNumberOfPages()
+ {
+ return printables.size();
+ }
+
+ /**
+ * This method returns the <code>PageFormat</code> object for the
+ * specified page.
+ *
+ * @param page_number The number of the page to get information for, where
+ * page numbers start at 0.
+ *
+ * @return The <code>PageFormat</code> object for the specified page.
+ *
+ * @exception IndexOutOfBoundsException If the page number is not valid.
+ */
+ public PageFormat getPageFormat(int page_number)
+ {
+ return (PageFormat) page_formats.elementAt(page_number);
+ }
+
+ /**
+ * This method returns the <code>Printable</code> object for the
+ * specified page.
+ *
+ * @param page_number The number of the page to get information for, where
+ * page numbers start at 0.
+ *
+ * @return The <code>Printable</code> object for the specified page.
+ *
+ * @exception IndexOutOfBoundsException If the page number is not valid.
+ */
+ public Printable getPrintable(int page_number)
+ {
+ return (Printable) printables.elementAt(page_number);
+ }
+
+ /**
+ * This method appends a page to the end of the book.
+ *
+ * @param printable The <code>Printable</code> for this page.
+ * @param page_format The <code>PageFormat</code> for this page.
+ *
+ * @exception NullPointerException If either argument is <code>null</code>.
+ */
+ public void append(Printable printable, PageFormat page_format)
+ {
+ append(printable, page_format, 1);
+ }
+
+ /**
+ * This method appends the specified number of pages to the end of the book.
+ * Each one will be associated with the specified <code>Printable</code>
+ * and <code>PageFormat</code>.
+ *
+ * @param printable The <code>Printable</code> for this page.
+ * @param page_format The <code>PageFormat</code> for this page.
+ * @param num_pages The number of pages to append.
+ *
+ * @exception NullPointerException If any argument is <code>null</code>.
+ */
+ public void append(Printable printable, PageFormat page_format, int num_pages)
+ {
+ for (int i = 0; i < num_pages; i++)
+ {
+ printables.addElement(printable);
+ page_formats.addElement(page_format);
+ }
+ }
+
+ /**
+ * This method changes the <code>Printable</code> and <code>PageFormat</code>
+ * for the specified page. The page must already exist or an exception
+ * will be thrown.
+ *
+ * @param page_num The page number to alter.
+ * @param printable The new <code>Printable</code> for the page.
+ * @param page_format The new <code>PageFormat</code> for the page.
+ *
+ * @throws IndexOutOfBoundsException If the specified page does not exist.
+ */
+ public void setPage(int page_num, Printable printable, PageFormat page_format)
+ {
+ printables.setElementAt(printable, page_num);
+ page_formats.setElementAt(page_format, page_num);
+ }
+}
diff --git a/libjava/classpath/java/awt/print/PageFormat.java b/libjava/classpath/java/awt/print/PageFormat.java
new file mode 100644
index 0000000..6399552
--- /dev/null
+++ b/libjava/classpath/java/awt/print/PageFormat.java
@@ -0,0 +1,292 @@
+/* PageFormat.java -- Information about the page format
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+/**
+ * This class contains information about the desired page format to
+ * use for printing a particular set of pages.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class PageFormat implements Cloneable
+{
+
+/*
+ * Static Variables
+ */
+
+/**
+ * A constant for a landscaped page orientation. Used by
+ * <code>getOrientation</code> and <code>setOrientation</code>.
+ */
+public static final int LANDSCAPE = 0;
+
+/**
+ * A constant for a portrait page orientation. Used by
+ * <code>getOrientation</code> and <code>setOrientation</code>.
+ */
+public static final int PORTRAIT = 1;
+
+/**
+ * A constant for a reversed landscaped page orientation. This is
+ * the orientation used by Macintosh's for landscape. The origin is
+ * in the upper right hand corner instead of the upper left. The
+ * X and Y axes are reversed. Used by <code>getOrientation</code> and
+ * <code>setOrientation</code>.
+ */
+public static final int REVERSE_LANDSCAPE = 2;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+// The page orientation
+private int orientation;
+
+// The paper type
+private Paper paper;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * This method creates a default page layout, which will be in portrait
+ * format.
+ */
+public
+PageFormat()
+{
+ this.paper = new Paper();
+ this.orientation = PORTRAIT;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method returns the width of the page, in 1/72nd's of an inch. The
+ * "width" measured depends on orientation.
+ *
+ * @return The width of the page.
+ */
+public double
+getWidth()
+{
+ return(paper.getWidth());
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the height of the page, in 1/72nd's of an inch.
+ * The "height" measured depends on the orientation.
+ *
+ * @return The height of the page.
+ */
+public double
+getHeight()
+{
+ return(paper.getHeight());
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the X coordinate value of the upper leftmost
+ * drawable area of the paper.
+ *
+ * @return The upper leftmost imageable X coordinate.
+ */
+public double
+getImageableX()
+{
+ return(paper.getImageableX());
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the Y coordinate value of the upper leftmost
+ * drawable area of the paper.
+ *
+ * @return The upper leftmost imageable Y coordinate.
+ */
+public double
+getImageableY()
+{
+ return(paper.getImageableY());
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the imageable width of the paper, in 1/72nd's of
+ * an inch.
+ *
+ * @return The imageable width of the paper.
+ */
+public double
+getImageableWidth()
+{
+ return(paper.getImageableWidth());
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the imageable height of the paper, in 1/72nd's of
+ * an inch.
+ *
+ * @return The imageable height of the paper.
+ */
+public double getImageableHeight()
+{
+ return(paper.getImageableHeight());
+}
+
+/*************************************************************************/
+
+/**
+ * Returns a copy of the <code>paper</code> object being used for this
+ * page format.
+ *
+ * @return A copy of the <code>Paper</code> object for this format.
+ */
+public Paper
+getPaper()
+{
+ return((Paper)paper.clone());
+}
+
+/*************************************************************************/
+
+/**
+ * Sets the <code>Paper</code> object to be used by this page format.
+ *
+ * @param paper The new <code>Paper</code> object for this page format.
+ */
+public void
+setPaper(Paper paper)
+{
+ this.paper = paper;
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the current page orientation. The value returned
+ * will be one of the page orientation constants from this class.
+ *
+ * @return The current page orientation.
+ */
+public int
+getOrientation()
+{
+ return(orientation);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the page orientation for this format to the
+ * specified value. It must be one of the page orientation constants
+ * from this class or an exception will be thrown.
+ *
+ * @param orientation The new page orientation.
+ *
+ * @exception IllegalArgumentException If the specified page orientation
+ * value is not one of the constants from this class.
+ */
+public void
+setOrientation(int orientation) throws IllegalArgumentException
+{
+ if ((orientation != PORTRAIT) &&
+ (orientation != LANDSCAPE) &&
+ (orientation != REVERSE_LANDSCAPE))
+ throw new IllegalArgumentException("Bad page orientation value: " +
+ orientation);
+
+ this.orientation = orientation;
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns a matrix used for transforming user space
+ * coordinates to page coordinates. The value returned will be six
+ * doubles as described in <code>java.awt.geom.AffineTransform</code>.
+ *
+ * @return The transformation matrix for this page format.
+ */
+public double[]
+getMatrix()
+{
+ throw new RuntimeException("Not implemented since I don't know what to do");
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns a copy of this object.
+ *
+ * @return A copy of this object.
+ */
+public Object
+clone()
+{
+ try
+ {
+ return(super.clone());
+ }
+ catch(CloneNotSupportedException e)
+ {
+ return(null);
+ }
+}
+
+} // class PageFormat
+
diff --git a/libjava/classpath/java/awt/print/Pageable.java b/libjava/classpath/java/awt/print/Pageable.java
new file mode 100644
index 0000000..12fa542
--- /dev/null
+++ b/libjava/classpath/java/awt/print/Pageable.java
@@ -0,0 +1,113 @@
+/* Pageable.java -- Pages to be printed
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+/**
+ * This interface represents pages that are to be printed.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Pageable
+{
+
+/*
+ * Static Variables
+ */
+
+/**
+ * This constant is returned when <code>getNumberOfPages()</code>
+ * cannot determine the number of pages available for printing.
+ */
+int UNKNOWN_NUMBER_OF_PAGES = -1;
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method returns the number of pages this object contains, or
+ * <code>UNKNOWN_NUMBER_OF_PAGES</code> if it cannot determine the number
+ * of pages to be printed.
+ *
+ * @return The number of pages to be printed, or
+ * <code>UNKNOWN_NUMBER_OF_PAGES</code> if this is unknown.
+ */
+int
+getNumberOfPages();
+
+/*************************************************************************/
+
+/**
+ * This method returns the <code>PageFormat</code> instance for the
+ * specified page. Page numbers start at zero. An exception is thrown if
+ * the requested page does not exist.
+ *
+ * @param pageIndex The index of the page to return the
+ * <code>PageFormat</code> for.
+ *
+ * @return The <code>PageFormat</code> for the requested page.
+ *
+ * @exception IndexOutOfBoundsException If the requested page number does
+ * not exist.
+ */
+PageFormat
+getPageFormat(int pageIndex) throws IndexOutOfBoundsException;
+
+/*************************************************************************/
+
+/**
+ * This method returns the <code>Printable</code> instance for the
+ * specified page. Page numbers start at zero. An exception is thrown if
+ * the requested page does not exist.
+ *
+ * @param pageIndex The index of the page to return the
+ * <code>Printable</code> for.
+ *
+ * @return The <code>Printable</code> for the requested page.
+ *
+ * @exception IndexOutOfBoundsException If the requested page number does
+ * not exist.
+ */
+Printable
+getPrintable(int pageIndex) throws IndexOutOfBoundsException;
+
+} // interface Pageable
+
diff --git a/libjava/classpath/java/awt/print/Paper.java b/libjava/classpath/java/awt/print/Paper.java
new file mode 100644
index 0000000..4579da3
--- /dev/null
+++ b/libjava/classpath/java/awt/print/Paper.java
@@ -0,0 +1,236 @@
+/* Paper.java -- Information about a paper type.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+/**
+ * This class describes a particular type of paper.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class Paper implements Cloneable
+{
+
+/*
+ * Instance Variables
+ */
+
+// Height of the paper
+private double height;
+
+// Width of the paper
+private double width;
+
+// Upper left imageable X coordinate
+private double imageableX;
+
+// Upper left imageable Y coordinate
+private double imageableY;
+
+// Imageable width of the page
+private double imageableWidth;
+
+// Imageable height of the page
+private double imageableHeight;
+
+/*************************************************************************/
+
+/*
+ * Constructor
+ */
+
+/**
+ * This method creates a letter sized paper with one inch margins
+ */
+public
+Paper()
+{
+ width = 8.5 * 72;
+ height = 11 * 72;
+ imageableX = 72;
+ imageableY = 72;
+ imageableWidth = width - (2 * 72);
+ imageableHeight = height - (2 * 72);
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the height of the paper in 1/72nds of an inch.
+ *
+ * @return The height of the paper in 1/72nds of an inch.
+ */
+public double
+getHeight()
+{
+ return(height);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the width of the paper in 1/72nds of an inch.
+ *
+ * @return The width of the paper in 1/72nds of an inch.
+ */
+public double
+getWidth()
+{
+ return(width);
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the X coordinate of the upper left hand corner
+ * of the imageable area of the paper.
+ *
+ * @return The X coordinate of the upper left hand corner of the imageable
+ * area of the paper.
+ */
+public double
+getImageableX()
+{
+ return(imageableX);
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the Y coordinate of the upper left hand corner
+ * of the imageable area of the paper.
+ *
+ * @return The Y coordinate of the upper left hand corner of the imageable
+ * area of the paper.
+ */
+public double
+getImageableY()
+{
+ return(imageableY);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the width of the imageable area of the paper.
+ *
+ * @return The width of the imageable area of the paper.
+ */
+public double
+getImageableWidth()
+{
+ return(imageableWidth);
+}
+
+/*************************************************************************/
+
+/**
+ * Returns the height of the imageable area of the paper.
+ *
+ * @return The height of the imageable area of the paper.
+ */
+public double
+getImageableHeight()
+{
+ return(imageableHeight);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the size of the paper to the specified width and
+ * height, which are specified in 1/72nds of an inch.
+ *
+ * @param width The width of the paper in 1/72nds of an inch.
+ * @param height The height of the paper in 1/72nds of an inch.
+ */
+public void
+setSize(double width, double height)
+{
+ this.width = width;
+ this.height = height;
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the imageable area of the paper by specifying the
+ * coordinates of the upper left hand corner of that area, and its
+ * length and height. All values are in 1/72nds of an inch.
+ *
+ * @param imageableX The X coordinate of the upper left hand corner of
+ * the imageable area, in 1/72nds of an inch.
+ * @param imageableY The Y coordinate of the upper left hand corner of
+ * the imageable area, in 1/72nds of an inch.
+ * @param imageableWidth The width of the imageable area of the paper,
+ * in 1/72nds of an inch.
+ * @param imageableHeight The heigth of the imageable area of the paper,
+ * in 1/72nds of an inch.
+ */
+public void
+setImageableArea(double imageableX, double imageableY,
+ double imageableWidth, double imageableHeight)
+{
+ this.imageableX = imageableX;
+ this.imageableY = imageableY;
+ this.imageableWidth = imageableWidth;
+ this.imageableHeight = imageableHeight;
+}
+
+/*************************************************************************/
+
+/**
+ * This method creates a copy of this object.
+ *
+ * @return A copy of this object.
+ */
+public Object
+clone()
+{
+ try
+ {
+ return(super.clone());
+ }
+ catch(CloneNotSupportedException e)
+ {
+ return(null);
+ }
+}
+
+} // class Paper
+
diff --git a/libjava/classpath/java/awt/print/Printable.java b/libjava/classpath/java/awt/print/Printable.java
new file mode 100644
index 0000000..775167e
--- /dev/null
+++ b/libjava/classpath/java/awt/print/Printable.java
@@ -0,0 +1,80 @@
+/* Printable.java -- Renders a page to the print device
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.print;
+
+import java.awt.Graphics;
+
+
+/**
+ * This interface provides a mechanism for the actual printing of pages to the
+ * printer. The object implementing this interface performs the page
+ * rendering.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Printable
+{
+ /**
+ * This value is returned by the <code>print()</code> method to indicate
+ * that the requested page exists and has been printed.
+ */
+ int PAGE_EXISTS = 0;
+
+ /**
+ * This value is returned by the <code>print()</code> method to indicate
+ * that the requested page number does not exist.
+ */
+ int NO_SUCH_PAGE = 1;
+
+ /**
+ * This method prints the specified page to the specified graphics
+ * context in the specified format. The pages are numbered starting
+ * from zero.
+ *
+ * @param graphics The graphics context to render the pages on.
+ * @param format The format in which to print the page.
+ * @param page_number The page number to print, where numbers start at zero.
+ *
+ * @return <code>PAGE_EXISTS</code> if the requested page exists and was
+ * successfully printed, <code>NO_SUCH_PAGE</code> otherwise.
+ *
+ * @exception PrinterException If an error occurs during printing.
+ */
+ int print(Graphics graphics, PageFormat format, int page_number)
+ throws PrinterException;
+}
diff --git a/libjava/classpath/java/awt/print/PrinterAbortException.java b/libjava/classpath/java/awt/print/PrinterAbortException.java
new file mode 100644
index 0000000..4580630
--- /dev/null
+++ b/libjava/classpath/java/awt/print/PrinterAbortException.java
@@ -0,0 +1,71 @@
+/* PrinterAbortException.java -- Indicates the print job was aborted
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+/**
+ * This exception is thrown when the print job is aborted, either by the
+ * user or by the application.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @status updated to 1.4
+ */
+public class PrinterAbortException extends PrinterException
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 4725169026278854136L;
+
+ /**
+ * Create a new instance with no detailed error message.
+ */
+ public PrinterAbortException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message.
+ *
+ * @param message the descriptive error message
+ */
+ public PrinterAbortException(String message)
+ {
+ super(message);
+ }
+} // class PrinterAbortException
diff --git a/libjava/classpath/java/awt/print/PrinterException.java b/libjava/classpath/java/awt/print/PrinterException.java
new file mode 100644
index 0000000..c105f54
--- /dev/null
+++ b/libjava/classpath/java/awt/print/PrinterException.java
@@ -0,0 +1,71 @@
+/* PrinterException.java -- generic problem in the printing subsystem
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+/**
+ * This is the generic toplevel exception for printing errors. Subclasses
+ * provide more detailed descriptions of the problem.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @status updated to 1.4
+ */
+public class PrinterException extends Exception
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = -3757589981158265819L;
+
+ /**
+ * Create a new instance with no detailed error message.
+ */
+ public PrinterException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message.
+ *
+ * @param message the descriptive error message
+ */
+ public PrinterException(String message)
+ {
+ super(message);
+ }
+} // class PrinterException
diff --git a/libjava/classpath/java/awt/print/PrinterGraphics.java b/libjava/classpath/java/awt/print/PrinterGraphics.java
new file mode 100644
index 0000000..5ca6419
--- /dev/null
+++ b/libjava/classpath/java/awt/print/PrinterGraphics.java
@@ -0,0 +1,61 @@
+/* PrinterGraphics.java -- Hook to return print job controller.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+/**
+ * This interface is implemented by the <code>Graphics</code> instance
+ * that is used for rendering pages. It provides a hook to return the
+ * object that is controlling the print job.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface PrinterGraphics
+{
+
+/**
+ * This method returns the instance of <code>PrinterJob</code> that is
+ * controlling this print job.
+ *
+ * @return The <code>PrinterJob</code> that is controlling this print job.
+ */
+PrinterJob
+getPrinterJob();
+
+} // interface PrinterGraphics
+
diff --git a/libjava/classpath/java/awt/print/PrinterIOException.java b/libjava/classpath/java/awt/print/PrinterIOException.java
new file mode 100644
index 0000000..c646acd
--- /dev/null
+++ b/libjava/classpath/java/awt/print/PrinterIOException.java
@@ -0,0 +1,98 @@
+/* PrinterIOException.java -- The print job encountered an I/O error
+ Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+import java.io.IOException;
+
+/**
+ * This exception is thrown when the print job encounters an I/O problem
+ * of some kind.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @status updated to 1.4
+ */
+public class PrinterIOException extends PrinterException
+{
+ /**
+ * Compatible with JDK 1.2+.
+ */
+ private static final long serialVersionUID = 5850870712125932846L;
+
+ /**
+ * The exception that caused this (duplicates Throwable).
+ *
+ * @serial the I/O exception that terminated the job
+ */
+ private final IOException mException;
+
+ /**
+ * Initializes a new instance with the given cause.
+ *
+ * @param mException the cause
+ */
+ public PrinterIOException(IOException mException)
+ {
+ super(mException == null ? null : mException.toString());
+ initCause(mException);
+ this.mException = mException;
+ }
+
+ /**
+ * Gets the underlying <code>IOException</code> that caused this exception.
+ * This legacy method has been replaced by {@link #getCause()}.
+ *
+ * @return the cause
+ */
+ public IOException getIOException()
+ {
+ return mException;
+ }
+
+ /**
+ * Gets the cause.
+ *
+ * @return the cause
+ */
+ public Throwable getCause()
+ {
+ return mException;
+ }
+} // class PrinterIOException
+
diff --git a/libjava/classpath/java/awt/print/PrinterJob.java b/libjava/classpath/java/awt/print/PrinterJob.java
new file mode 100644
index 0000000..e61ab61
--- /dev/null
+++ b/libjava/classpath/java/awt/print/PrinterJob.java
@@ -0,0 +1,299 @@
+/* PrinterJob.java -- This job is the printer control class
+ Copyright (C) 1999, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.print;
+
+import java.awt.HeadlessException;
+
+import javax.print.PrintService;
+import javax.print.attribute.PrintRequestAttributeSet;
+
+/**
+ * This class controls printing.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract class PrinterJob
+{
+ // The print service associated with this job
+ private PrintService printer = null;
+
+ /**
+ * Creates a new print job.
+ *
+ * @return A <code>PrinterJob</code> object for the newly created print job.
+ */
+ public static PrinterJob getPrinterJob()
+ {
+ // FIXME: Need to fix this to load a default implementation instance.
+ return null;
+ }
+
+ /**
+ * Initializes a new instance of <code>PrinterJob</code>.
+ */
+ public PrinterJob()
+ {
+ }
+
+ /**
+ * Returns the number of copies to be printed.
+ *
+ * @return The number of copies to be printed.
+ */
+ public abstract int getCopies();
+
+ /**
+ * Sets the number of copies to be printed.
+ *
+ * @param copies The number of copies to be printed.
+ */
+ public abstract void setCopies(int copies);
+
+ /**
+ * Returns the name of the print job.
+ *
+ * @return The name of the print job.
+ */
+ public abstract String getJobName();
+
+ /**
+ * Sets the name of the print job.
+ *
+ * @param job_name The name of the print job.
+ */
+ public abstract void setJobName(String job_name);
+
+ /**
+ * Returns the printing user name.
+ *
+ * @return The printing username.
+ */
+ public abstract String getUserName();
+
+ /**
+ * Cancels an in progress print job.
+ */
+ public abstract void cancel();
+
+ /**
+ * Tests whether or not this job has been cancelled.
+ *
+ * @return <code>true</code> if this job has been cancelled, <code>false</code>
+ * otherwise.
+ */
+ public abstract boolean isCancelled();
+
+ /**
+ * Returns an instance of the default page which will have the default
+ * paper and orientation.
+ *
+ * @return A default instance of <code>PageFormat</code>.
+ */
+ public PageFormat defaultPage()
+ {
+ return new PageFormat();
+ }
+
+ /**
+ * Clones the specified <code>PageFormat</code> object then alters the
+ * clone so that it represents the default page format.
+ *
+ * @param page_format The <code>PageFormat</code> to clone.
+ *
+ * @return A new default page format.
+ */
+ public abstract PageFormat defaultPage(PageFormat page_format);
+
+ /**
+ * Displays a dialog box to the user which allows the page format
+ * attributes to be modified.
+ *
+ * @param page_format The <code>PageFormat</code> object to modify.
+ *
+ * @return The modified <code>PageFormat</code>.
+ */
+ public abstract PageFormat pageDialog(PageFormat page_format)
+ throws HeadlessException;
+
+ /**
+ * @since 1.4
+ */
+ public PageFormat pageDialog(PrintRequestAttributeSet attributes)
+ throws HeadlessException
+ {
+ // FIXME: Implement this for real.
+ return pageDialog((PageFormat) null);
+ }
+
+ /**
+ * Prints the pages.
+ */
+ public abstract void print () throws PrinterException;
+
+ /**
+ * Prints the page with given attributes.
+ */
+ public abstract void print (PrintRequestAttributeSet attributes)
+ throws PrinterException;
+
+ /**
+ * Displays a dialog box to the user which allows the print job
+ * attributes to be modified.
+ *
+ * @return <code>false</code> if the user cancels the dialog box,
+ * <code>true</code> otherwise.
+ */
+ public abstract boolean printDialog()
+ throws HeadlessException;
+
+ /**
+ * Displays a dialog box to the user which allows the print job
+ * attributes to be modified.
+ *
+ * @return <code>false</code> if the user cancels the dialog box,
+ * <code>true</code> otherwise.
+ */
+ public boolean printDialog(PrintRequestAttributeSet attributes)
+ throws HeadlessException
+ {
+ // FIXME: Implement this for real.
+ return printDialog();
+ }
+
+ /**
+ * This sets the pages that are to be printed.
+ *
+ * @param pageable The pages to be printed, which may not be <code>null</code>.
+ */
+ public abstract void setPageable(Pageable pageable);
+
+ /**
+ * Sets this specified <code>Printable</code> as the one to use for
+ * rendering the pages on the print device.
+ *
+ * @param printable The <code>Printable</code> for the print job.
+ */
+ public abstract void setPrintable(Printable printable);
+
+ /**
+ * Sets the <code>Printable</code> and the page format for the pages
+ * to be printed.
+ *
+ * @param printable The <code>Printable</code> for the print job.
+ * @param page_format The <code>PageFormat</code> for the print job.
+ */
+ public abstract void setPrintable(Printable printable, PageFormat page_format);
+
+ /**
+ * Makes any alterations to the specified <code>PageFormat</code>
+ * necessary to make it work with the current printer. The alterations
+ * are made to a clone of the input object, which is then returned.
+ *
+ * @param page_format The <code>PageFormat</code> to validate.
+ *
+ * @return The validated <code>PageFormat</code>.
+ */
+ public abstract PageFormat validatePage(PageFormat page_format);
+
+ /**
+ * Find and return 2D image print services.
+ *
+ * This is the same as calling PrintServiceLookup.lookupPrintServices()
+ * with Pageable service-specified DocFlavor.
+ * @return Array of PrintService objects, could be empty.
+ * @since 1.4
+ */
+ public static PrintService[] lookupPrintServices()
+ {
+ return new PrintService[0];
+ // FIXME:
+ // Enable this when javax.print has this implemented.
+// return PrintServiceLookup.lookupPrintServices(
+// new DocFlavor("application/x-java-jvm-local-objectref",
+// "java.awt.print.Pageable"),
+// null);
+ }
+
+ /**
+ * Find and return 2D image stream print services.
+ *
+ * This is the same as calling
+ * StreamPrintServiceFactory.lookupStreamPrintServices()
+ * with Pageable service-specified DocFlavor.
+ * @param mimeType The output format mime type, or null for any type.
+ * @return Array of stream print services, could be empty.
+ * @since 1.4
+ */
+ // FIXME:
+ // Enable when javax.print has StreamPrintServiceFactory
+// public static StreamPrintServiceFactory[] lookupStreamPrintServices(String mimeType)
+// {
+// return StreamPrintServiceFactory.lookupStreamServiceFactories(
+// new DocFlavor("application/x-java-jvm-local-objectref",
+// "java.awt.print.Pageable"),
+// mimeType);
+// }
+
+ /**
+ * Return the printer for this job. If print services aren't supported by
+ * the subclass, returns null.
+ *
+ * @return The associated PrintService.
+ * @since 1.4
+ */
+ public PrintService getPrintService()
+ {
+ return null;
+ }
+
+ /**
+ * Change the printer for this print job to service. Subclasses that
+ * support setting the print service override this method. Throws
+ * PrinterException when the class doesn't support setting the printer,
+ * the service doesn't support Pageable or Printable interfaces for 2D
+ * print output.
+ * @param service The new printer to use.
+ * @throws PrinterException if service is not valid.
+ */
+ public void setPrintService(PrintService service)
+ throws PrinterException
+ {
+ throw new PrinterException();
+ }
+}
diff --git a/libjava/classpath/java/awt/print/package.html b/libjava/classpath/java/awt/print/package.html
new file mode 100644
index 0000000..50abcbf
--- /dev/null
+++ b/libjava/classpath/java/awt/print/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.awt.print package.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.awt.print</title></head>
+
+<body>
+<p>Classes for printer jobs, pages, paper sizes, graphics and formats.</p>
+
+</body>
+</html>