| /* GtkComponentPeer.java -- Implements ComponentPeer with GTK |
| Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006 |
| Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package gnu.java.awt.peer.gtk; |
| |
| import java.awt.AWTEvent; |
| import java.awt.AWTException; |
| import java.awt.BufferCapabilities; |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Container; |
| import java.awt.Cursor; |
| import java.awt.Dimension; |
| import java.awt.EventQueue; |
| import java.awt.Font; |
| import java.awt.FontMetrics; |
| import java.awt.Graphics; |
| import java.awt.GraphicsConfiguration; |
| import java.awt.GraphicsDevice; |
| import java.awt.GraphicsEnvironment; |
| import java.awt.Image; |
| import java.awt.Insets; |
| import java.awt.ItemSelectable; |
| import java.awt.KeyboardFocusManager; |
| import java.awt.Point; |
| import java.awt.Rectangle; |
| import java.awt.Toolkit; |
| import java.awt.Window; |
| import java.awt.event.FocusEvent; |
| import java.awt.event.ItemEvent; |
| import java.awt.event.KeyEvent; |
| import java.awt.event.MouseEvent; |
| import java.awt.event.MouseWheelEvent; |
| import java.awt.event.PaintEvent; |
| import java.awt.event.TextEvent; |
| 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.ContainerPeer; |
| import java.awt.peer.LightweightPeer; |
| import java.awt.peer.WindowPeer; |
| import java.util.Timer; |
| import java.util.TimerTask; |
| |
| public class GtkComponentPeer extends GtkGenericPeer |
| implements ComponentPeer |
| { |
| VolatileImage backBuffer; |
| BufferCapabilities caps; |
| |
| Component awtComponent; |
| |
| Insets insets; |
| |
| /* this isEnabled differs from Component.isEnabled, in that it |
| knows if a parent is disabled. In that case Component.isEnabled |
| may return true, but our isEnabled will always return false */ |
| native boolean isEnabled (); |
| static native boolean modalHasGrab(); |
| |
| native int[] gtkWidgetGetForeground (); |
| native int[] gtkWidgetGetBackground (); |
| native void gtkWidgetGetDimensions (int[] dim); |
| native void gtkWidgetGetPreferredDimensions (int[] dim); |
| native void gtkWindowGetLocationOnScreen (int[] point); |
| native void gtkWidgetGetLocationOnScreen (int[] point); |
| native void gtkWidgetSetCursor (int type, GtkImage image, int x, int y); |
| native void gtkWidgetSetCursorUnlocked (int type, GtkImage image, |
| int x, int y); |
| native void gtkWidgetSetBackground (int red, int green, int blue); |
| native void gtkWidgetSetForeground (int red, int green, int blue); |
| native void gtkWidgetSetSensitive (boolean sensitive); |
| native void gtkWidgetSetParent (ComponentPeer parent); |
| native void gtkWidgetRequestFocus (); |
| native void gtkWidgetDispatchKeyEvent (int id, long when, int mods, |
| int keyCode, int keyLocation); |
| native boolean gtkWidgetHasFocus(); |
| native boolean gtkWidgetCanFocus(); |
| |
| native void realize(); |
| native void setNativeEventMask (); |
| |
| void create () |
| { |
| throw new RuntimeException (); |
| } |
| |
| native void connectSignals (); |
| |
| protected GtkComponentPeer (Component awtComponent) |
| { |
| super (awtComponent); |
| this.awtComponent = awtComponent; |
| insets = new Insets (0, 0, 0, 0); |
| |
| create (); |
| |
| connectSignals (); |
| |
| if (awtComponent.getForeground () != null) |
| setForeground (awtComponent.getForeground ()); |
| if (awtComponent.getBackground () != null) |
| setBackground (awtComponent.getBackground ()); |
| if (awtComponent.getFont() != null) |
| setFont(awtComponent.getFont()); |
| |
| Component parent = awtComponent.getParent (); |
| |
| setParentAndBounds (); |
| |
| setNativeEventMask (); |
| |
| // This peer is guaranteed to have an X window upon construction. |
| // That is, native methods such as those in GdkGraphics can rely |
| // on this component's widget->window field being non-null. |
| realize (); |
| |
| if (awtComponent.isCursorSet()) |
| setCursor (); |
| } |
| |
| void setParentAndBounds () |
| { |
| setParent (); |
| |
| setComponentBounds (); |
| |
| setVisibleAndEnabled (); |
| } |
| |
| void setParent () |
| { |
| ComponentPeer p; |
| Component component = awtComponent; |
| do |
| { |
| component = component.getParent (); |
| p = component.getPeer (); |
| } |
| while (p instanceof java.awt.peer.LightweightPeer); |
| |
| if (p != null) |
| gtkWidgetSetParent (p); |
| } |
| |
| /* |
| * Set the bounds of this peer's AWT Component based on dimensions |
| * returned by the native windowing system. Most Components impose |
| * their dimensions on the peers which is what the default |
| * implementation does. However some peers, like GtkFileDialogPeer, |
| * need to pass their size back to the AWT Component. |
| */ |
| void setComponentBounds () |
| { |
| Rectangle bounds = awtComponent.getBounds (); |
| setBounds (bounds.x, bounds.y, bounds.width, bounds.height); |
| } |
| |
| void setVisibleAndEnabled () |
| { |
| setVisible (awtComponent.isVisible ()); |
| setEnabled (awtComponent.isEnabled ()); |
| } |
| |
| public int checkImage (Image image, int width, int height, |
| ImageObserver observer) |
| { |
| return getToolkit().checkImage(image, width, height, observer); |
| } |
| |
| public Image createImage (ImageProducer producer) |
| { |
| return new GtkImage (producer); |
| } |
| |
| public Image createImage (int width, int height) |
| { |
| return CairoSurface.getBufferedImage(width, height); |
| } |
| |
| public void disable () |
| { |
| setEnabled (false); |
| } |
| |
| public void enable () |
| { |
| setEnabled (true); |
| } |
| |
| public ColorModel getColorModel () |
| { |
| return ColorModel.getRGBdefault (); |
| } |
| |
| public FontMetrics getFontMetrics (Font font) |
| { |
| return getToolkit().getFontMetrics(font); |
| } |
| |
| // getGraphics may be overridden by derived classes but it should |
| // never return null. |
| public Graphics getGraphics () |
| { |
| return ComponentGraphics.getComponentGraphics(this); |
| } |
| |
| public Point getLocationOnScreen () |
| { |
| int point[] = new int[2]; |
| if( this instanceof WindowPeer ) |
| gtkWindowGetLocationOnScreen (point); |
| else |
| gtkWidgetGetLocationOnScreen (point); |
| return new Point (point[0], point[1]); |
| } |
| |
| public Dimension getMinimumSize () |
| { |
| return minimumSize (); |
| } |
| |
| public Dimension getPreferredSize () |
| { |
| return preferredSize (); |
| } |
| |
| public Toolkit getToolkit () |
| { |
| return Toolkit.getDefaultToolkit(); |
| } |
| |
| public void handleEvent (AWTEvent event) |
| { |
| int id = event.getID(); |
| KeyEvent ke = null; |
| |
| switch (id) |
| { |
| case PaintEvent.PAINT: |
| paintComponent((PaintEvent) event); |
| break; |
| case PaintEvent.UPDATE: |
| updateComponent((PaintEvent) event); |
| break; |
| case KeyEvent.KEY_PRESSED: |
| ke = (KeyEvent) event; |
| gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (), |
| ke.getKeyCode (), ke.getKeyLocation ()); |
| break; |
| case KeyEvent.KEY_RELEASED: |
| ke = (KeyEvent) event; |
| gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (), |
| ke.getKeyCode (), ke.getKeyLocation ()); |
| break; |
| } |
| } |
| |
| // This method and its overrides are the only methods in the peers |
| // that should call awtComponent.paint. |
| protected void paintComponent (PaintEvent event) |
| { |
| // Do not call Component.paint if the component is not showing or |
| // if its bounds form a degenerate rectangle. |
| if (!awtComponent.isShowing() |
| || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1)) |
| return; |
| |
| // Creating and disposing a GdkGraphics every time paint is called |
| // seems expensive. However, the graphics state does not carry |
| // over between calls to paint, and resetting the graphics object |
| // may even be more costly than simply creating a new one. |
| Graphics g = getGraphics(); |
| |
| g.setClip(event.getUpdateRect()); |
| |
| awtComponent.paint(g); |
| |
| g.dispose(); |
| } |
| |
| // This method and its overrides are the only methods in the peers |
| // that should call awtComponent.update. |
| protected void updateComponent (PaintEvent event) |
| { |
| // Do not call Component.update if the component is not showing or |
| // if its bounds form a degenerate rectangle. |
| if (!awtComponent.isShowing() |
| || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1)) |
| return; |
| |
| Graphics g = getGraphics(); |
| |
| g.setClip(event.getUpdateRect()); |
| |
| awtComponent.update(g); |
| |
| g.dispose(); |
| } |
| |
| public boolean isFocusTraversable () |
| { |
| return true; |
| } |
| |
| public Dimension minimumSize () |
| { |
| int dim[] = new int[2]; |
| |
| gtkWidgetGetPreferredDimensions (dim); |
| |
| return new Dimension (dim[0], dim[1]); |
| } |
| |
| public void paint (Graphics g) |
| { |
| } |
| |
| public Dimension preferredSize () |
| { |
| int dim[] = new int[2]; |
| |
| gtkWidgetGetPreferredDimensions (dim); |
| |
| return new Dimension (dim[0], dim[1]); |
| } |
| |
| public boolean prepareImage (Image image, int width, int height, |
| ImageObserver observer) |
| { |
| return getToolkit().prepareImage(image, width, height, observer); |
| } |
| |
| public void print (Graphics g) |
| { |
| g.drawImage( ComponentGraphics.grab( this ), 0, 0, null ); |
| } |
| |
| public void repaint (long tm, int x, int y, int width, int height) |
| { |
| if (width < 1 || height < 1) |
| return; |
| |
| if (tm <= 0) |
| q().postEvent(new PaintEvent(awtComponent, PaintEvent.UPDATE, |
| new Rectangle(x, y, width, height))); |
| else |
| RepaintTimerTask.schedule(tm, x, y, width, height, awtComponent); |
| } |
| |
| /** |
| * Used for scheduling delayed paint updates on the event queue. |
| */ |
| private static class RepaintTimerTask extends TimerTask |
| { |
| private static final Timer repaintTimer = new Timer(true); |
| |
| private int x, y, width, height; |
| private Component awtComponent; |
| |
| RepaintTimerTask(Component c, int x, int y, int width, int height) |
| { |
| this.x = x; |
| this.y = y; |
| this.width = width; |
| this.height = height; |
| this.awtComponent = c; |
| } |
| |
| public void run() |
| { |
| q().postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE, |
| new Rectangle (x, y, width, height))); |
| } |
| |
| static void schedule(long tm, int x, int y, int width, int height, |
| Component c) |
| { |
| repaintTimer.schedule(new RepaintTimerTask(c, x, y, width, height), tm); |
| } |
| } |
| |
| public void requestFocus () |
| { |
| assert false: "Call new requestFocus() method instead"; |
| } |
| |
| public void reshape (int x, int y, int width, int height) |
| { |
| setBounds (x, y, width, height); |
| } |
| |
| public void setBackground (Color c) |
| { |
| gtkWidgetSetBackground (c.getRed(), c.getGreen(), c.getBlue()); |
| } |
| |
| native void setNativeBounds (int x, int y, int width, int height); |
| |
| public void setBounds (int x, int y, int width, int height) |
| { |
| int new_x = x; |
| int new_y = y; |
| |
| Component parent = awtComponent.getParent (); |
| |
| // Heavyweight components that are children of one or more |
| // lightweight containers have to be handled specially. Because |
| // calls to GLightweightPeer.setBounds do nothing, GTK has no |
| // knowledge of the lightweight containers' positions. So we have |
| // to add the offsets manually when placing a heavyweight |
| // component within a lightweight container. The lightweight |
| // container may itself be in a lightweight container and so on, |
| // so we need to continue adding offsets until we reach a |
| // container whose position GTK knows -- that is, the first |
| // non-lightweight. |
| Insets i; |
| while (parent.isLightweight()) |
| { |
| i = ((Container) parent).getInsets(); |
| |
| new_x += parent.getX() + i.left; |
| new_y += parent.getY() + i.top; |
| |
| parent = parent.getParent(); |
| } |
| // We only need to convert from Java to GTK coordinates if we're |
| // placing a heavyweight component in a Window. |
| if (parent instanceof Window) |
| { |
| GtkWindowPeer peer = (GtkWindowPeer) parent.getPeer (); |
| // important: we want the window peer's insets here, not the |
| // window's, since user sub-classes of Window can override |
| // getInset and we only want to correct for the frame borders, |
| // not for any user-defined inset values |
| Insets insets = peer.getInsets (); |
| |
| int menuBarHeight = 0; |
| if (peer instanceof GtkFramePeer) |
| menuBarHeight = ((GtkFramePeer) peer).getMenuBarHeight (); |
| |
| new_x -= insets.left; |
| new_y -= insets.top; |
| new_y += menuBarHeight; |
| } |
| |
| setNativeBounds (new_x, new_y, width, height); |
| |
| // If the height or width were (or are now) smaller than zero |
| // then we want to adjust the visibility. |
| setVisible(awtComponent.isVisible()); |
| } |
| |
| void setCursor () |
| { |
| setCursor (awtComponent.getCursor ()); |
| } |
| |
| public void setCursor (Cursor cursor) |
| { |
| int x, y; |
| GtkImage image; |
| int type = cursor.getType(); |
| if (cursor instanceof GtkCursor) |
| { |
| GtkCursor gtkCursor = (GtkCursor) cursor; |
| image = gtkCursor.getGtkImage(); |
| Point hotspot = gtkCursor.getHotspot(); |
| x = hotspot.x; |
| y = hotspot.y; |
| } |
| else |
| { |
| image = null; |
| x = 0; |
| y = 0; |
| } |
| |
| if (Thread.currentThread() == GtkToolkit.mainThread) |
| gtkWidgetSetCursorUnlocked(cursor.getType(), image, x, y); |
| else |
| gtkWidgetSetCursor(cursor.getType(), image, x, y); |
| } |
| |
| public void setEnabled (boolean b) |
| { |
| gtkWidgetSetSensitive (b); |
| } |
| |
| public void setFont (Font f) |
| { |
| // FIXME: This should really affect the widget tree below me. |
| // Currently this is only handled if the call is made directly on |
| // a text widget, which implements setFont() itself. |
| gtkWidgetModifyFont(f.getName(), f.getStyle(), f.getSize()); |
| } |
| |
| public void setForeground (Color c) |
| { |
| gtkWidgetSetForeground (c.getRed(), c.getGreen(), c.getBlue()); |
| } |
| |
| public Color getForeground () |
| { |
| int rgb[] = gtkWidgetGetForeground (); |
| return new Color (rgb[0], rgb[1], rgb[2]); |
| } |
| |
| public Color getBackground () |
| { |
| int rgb[] = gtkWidgetGetBackground (); |
| return new Color (rgb[0], rgb[1], rgb[2]); |
| } |
| |
| public native void setVisibleNative (boolean b); |
| public native void setVisibleNativeUnlocked (boolean b); |
| |
| public void setVisible (boolean b) |
| { |
| // Only really set visible when component is bigger than zero pixels. |
| if (b && ! (awtComponent instanceof Window)) |
| { |
| Rectangle bounds = awtComponent.getBounds(); |
| b = (bounds.width > 0) && (bounds.height > 0); |
| } |
| |
| if (Thread.currentThread() == GtkToolkit.mainThread) |
| setVisibleNativeUnlocked (b); |
| else |
| setVisibleNative (b); |
| } |
| |
| public void hide () |
| { |
| setVisible (false); |
| } |
| |
| public void show () |
| { |
| setVisible (true); |
| } |
| |
| protected void postMouseEvent(int id, long when, int mods, int x, int y, |
| int clickCount, boolean popupTrigger) |
| { |
| q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y, |
| clickCount, popupTrigger)); |
| } |
| |
| /** |
| * Callback for component_scroll_cb. |
| */ |
| protected void postMouseWheelEvent(int id, long when, int mods, |
| int x, int y, int clickCount, |
| boolean popupTrigger, |
| int type, int amount, int rotation) |
| { |
| q().postEvent(new MouseWheelEvent(awtComponent, id, when, mods, |
| x, y, clickCount, popupTrigger, |
| type, amount, rotation)); |
| } |
| |
| protected void postExposeEvent (int x, int y, int width, int height) |
| { |
| q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, |
| new Rectangle (x, y, width, height))); |
| } |
| |
| protected void postKeyEvent (int id, long when, int mods, |
| int keyCode, char keyChar, int keyLocation) |
| { |
| KeyEvent keyEvent = new KeyEvent (awtComponent, id, when, mods, |
| keyCode, keyChar, keyLocation); |
| |
| EventQueue q = q(); |
| |
| // Also post a KEY_TYPED event if keyEvent is a key press that |
| // doesn't represent an action or modifier key. |
| if (keyEvent.getID () == KeyEvent.KEY_PRESSED |
| && (!keyEvent.isActionKey () |
| && keyCode != KeyEvent.VK_SHIFT |
| && keyCode != KeyEvent.VK_CONTROL |
| && keyCode != KeyEvent.VK_ALT)) |
| { |
| synchronized(q) |
| { |
| q.postEvent(keyEvent); |
| keyEvent = new KeyEvent(awtComponent, KeyEvent.KEY_TYPED, when, |
| mods, KeyEvent.VK_UNDEFINED, keyChar, |
| keyLocation); |
| q.postEvent(keyEvent); |
| } |
| } |
| else |
| q.postEvent(keyEvent); |
| } |
| |
| /** |
| * Referenced from native code. |
| * |
| * @param id |
| * @param temporary |
| */ |
| protected void postFocusEvent (int id, boolean temporary) |
| { |
| q().postEvent (new FocusEvent (awtComponent, id, temporary)); |
| } |
| |
| protected void postItemEvent (Object item, int stateChange) |
| { |
| q().postEvent (new ItemEvent ((ItemSelectable)awtComponent, |
| ItemEvent.ITEM_STATE_CHANGED, |
| item, stateChange)); |
| } |
| |
| protected void postTextEvent () |
| { |
| q().postEvent (new TextEvent (awtComponent, TextEvent.TEXT_VALUE_CHANGED)); |
| } |
| |
| public GraphicsConfiguration getGraphicsConfiguration () |
| { |
| // FIXME: The component might be showing on a non-default screen. |
| GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); |
| GraphicsDevice dev = env.getDefaultScreenDevice(); |
| return dev.getDefaultConfiguration(); |
| } |
| |
| public void setEventMask (long mask) |
| { |
| // FIXME: just a stub for now. |
| } |
| |
| public boolean isFocusable () |
| { |
| return false; |
| } |
| |
| public boolean requestFocus (Component request, boolean temporary, |
| boolean allowWindowFocus, long time) |
| { |
| assert request == awtComponent || isLightweightDescendant(request); |
| boolean retval = false; |
| if (gtkWidgetHasFocus()) |
| { |
| KeyboardFocusManager kfm = |
| KeyboardFocusManager.getCurrentKeyboardFocusManager(); |
| Component currentFocus = kfm.getFocusOwner(); |
| if (currentFocus == request) |
| // Nothing to do in this trivial case. |
| retval = true; |
| else |
| { |
| // Requested component is a lightweight descendant of this one |
| // or the actual heavyweight. |
| // Since this (native) component is already focused, we simply |
| // change the actual focus and be done. |
| postFocusEvent(FocusEvent.FOCUS_GAINED, temporary); |
| retval = true; |
| } |
| } |
| else |
| { |
| if (gtkWidgetCanFocus()) |
| { |
| if (allowWindowFocus) |
| { |
| Window window = getWindowFor(request); |
| GtkWindowPeer wPeer = (GtkWindowPeer) window.getPeer(); |
| if (! wPeer.gtkWindowHasFocus()) |
| wPeer.requestWindowFocus(); |
| } |
| // Store requested focus component so that the corresponding |
| // event is dispatched correctly. |
| gtkWidgetRequestFocus(); |
| retval = true; |
| } |
| } |
| return retval; |
| } |
| |
| private Window getWindowFor(Component c) |
| { |
| Component comp = c; |
| while (! (comp instanceof Window)) |
| comp = comp.getParent(); |
| return (Window) comp; |
| } |
| |
| /** |
| * Returns <code>true</code> if the component is a direct (== no intermediate |
| * heavyweights) lightweight descendant of this peer's component. |
| * |
| * @param c the component to check |
| * |
| * @return <code>true</code> if the component is a direct (== no intermediate |
| * heavyweights) lightweight descendant of this peer's component |
| */ |
| protected boolean isLightweightDescendant(Component c) |
| { |
| Component comp = c; |
| while (comp.getPeer() instanceof LightweightPeer) |
| comp = comp.getParent(); |
| return comp == awtComponent; |
| } |
| |
| public boolean isObscured () |
| { |
| return false; |
| } |
| |
| public boolean canDetermineObscurity () |
| { |
| return false; |
| } |
| |
| public void coalescePaintEvent (PaintEvent e) |
| { |
| |
| } |
| |
| public void updateCursorImmediately () |
| { |
| if (awtComponent.getCursor() != null) |
| setCursor(awtComponent.getCursor()); |
| } |
| |
| public boolean handlesWheelScrolling () |
| { |
| return false; |
| } |
| |
| // Convenience method to create a new volatile image on the screen |
| // on which this component is displayed. |
| public VolatileImage createVolatileImage (int width, int height) |
| { |
| return new GtkVolatileImage (this, width, height, null); |
| } |
| |
| // Creates buffers used in a buffering strategy. |
| public void createBuffers (int numBuffers, BufferCapabilities caps) |
| throws AWTException |
| { |
| // numBuffers == 2 implies double-buffering, meaning one back |
| // buffer and one front buffer. |
| if (numBuffers == 2) |
| backBuffer = new GtkVolatileImage(this, awtComponent.getWidth(), |
| awtComponent.getHeight(), |
| caps.getBackBufferCapabilities()); |
| else |
| throw new AWTException("GtkComponentPeer.createBuffers:" |
| + " multi-buffering not supported"); |
| this.caps = caps; |
| } |
| |
| // Return the back buffer. |
| public Image getBackBuffer () |
| { |
| return backBuffer; |
| } |
| |
| // FIXME: flip should be implemented as a fast native operation |
| public void flip (BufferCapabilities.FlipContents contents) |
| { |
| getGraphics().drawImage(backBuffer, |
| awtComponent.getWidth(), |
| awtComponent.getHeight(), |
| null); |
| |
| // create new back buffer and clear it to the background color. |
| if (contents == BufferCapabilities.FlipContents.BACKGROUND) |
| { |
| backBuffer = createVolatileImage(awtComponent.getWidth(), |
| awtComponent.getHeight()); |
| backBuffer.getGraphics().clearRect(0, 0, |
| awtComponent.getWidth(), |
| awtComponent.getHeight()); |
| } |
| // FIXME: support BufferCapabilities.FlipContents.PRIOR |
| } |
| |
| // Release the resources allocated to back buffers. |
| public void destroyBuffers () |
| { |
| backBuffer.flush(); |
| } |
| |
| public String toString () |
| { |
| return "peer of " + awtComponent.toString(); |
| } |
| public Rectangle getBounds() |
| { |
| // FIXME: implement |
| return null; |
| } |
| public void reparent(ContainerPeer parent) |
| { |
| // FIXME: implement |
| |
| } |
| public void setBounds(int x, int y, int width, int height, int z) |
| { |
| // FIXME: implement |
| setBounds (x, y, width, height); |
| |
| } |
| public boolean isReparentSupported() |
| { |
| // FIXME: implement |
| |
| return false; |
| } |
| public void layout() |
| { |
| // FIXME: implement |
| |
| } |
| } |