t3.portfolios.swing
Class SwingFramePortfolio

java.lang.Object
  extended by t3.portfolios.Portfolio
      extended by t3.portfolios.swing.SwingFramePortfolio

public class SwingFramePortfolio
extends Portfolio

A portfolio whose tile appears to be a frame into which you can place Java Swing components that respond to keyboard and point input device events. Some limitations apply.

The frame is created automatically when you call the constructor. The frame's RootPane (ie its contents) has the same width and height as the tile.

You can get the frame by calling the getFrame method, and then add JComponents in the usual way.

Repaint requests on the frame are trapped by the system. The frame is then painted into the tile's buffered image, which is then sent to the client, where it appears on the tabletop. Synchronization and endOfBurst calls are done automatically (see note on deadlock below).

PortfolioEvents are converted by the system into the corresponding AWT events and dispatched to the appropriate components in the frame. We use subclasses of the AWT event classes that give access to the underlying PortfolioEvent. Synchronization and endOfBurst calls are done automatically.

 

Threading Note 1: Manipulating Swing components in response to a Swing event

If you simply want to create/remove/manipulate Swing components in response to a Swing event (e.g. you want to make a radio button look checked in response to a MouseEvent) then the code should work just as it would under Swing and you do not need to modify your code at all.

 

Threading Note 2: Manipulating T3 in response to a Swing event

If you wish to manipulate T3 (e.g. create/destroy/move portfolios) in response to a Swing event then you need to take care. The swing event handling code runs in another thread, the swing repaint thread, so you need to follow the standard T3 practice for code that runs outside of T3's event handling routines, by calling myPortfolioServer.peformActionAsynchronously(...);

 

Threading Note 3: Manipulating Swing from T3

Here's how to do it. If you're just adding/removing/changing swing components, use:
runLaterFromSwingThread( new Runnable() { public void run() {
    YOUR CODE HERE
} } );

If you're also creating/destroying/repositioning portfolios, or if you're creating or destroying a swingframeportfolio use:
runLaterFromSwingThreadUsesPortfolios( myPortfolioServer, new Runnable() { public void run() {
        YOUR CODE HERE
    }
} } );

When using anonymous inner classes like this, don't forget that if you refer to variables that have been defined outside your anonymous class then you might have to declare the variables final to avoid compile errors.

Full gory details: When you manipulate a SwingFramePortfolio it generates swing repaint messages. These are caught by Swing's repaint thread which then tries to acquire the lock on stateManager before it sends the updates to the T3 portfolio server. If this lock is already held by another thread (A) then the repaint thread just waits until the other thread releases the lock. However, if thread A is blocked waiting for the swing thread to process another runnable on the event queue using invokeAndWait() then obviously the system is now deadlocked. This can happen - JEditorPane uses it. When this portfolio processes T3 events and dispatches them onto swing frames, it also uses the SwingUtilities.invokeLater method.

Author:
pjt40

Field Summary
 
Fields inherited from class t3.portfolios.Portfolio
childrenTopToBottomReadOnly, commonBehaviour, FLAG_PREALLOCATE_IMAGE_BUFFERS, FLAG_USES_UNWARPED_RECTANGLES, portfolioFlags, portfolioLinksFromThisReadOnly, portfolioServer, tileUpdateCompressionHints, unwarpedRectLinesList, unwarpedRectWordsList
 
Constructor Summary
SwingFramePortfolio(PortfolioServer pm, Portfolio parent, PortfolioCommonBehaviour c, int width, int height, int tileFlags, int portfolioFlags)
           
SwingFramePortfolio(PortfolioServer pm, Portfolio parent, PortfolioCommonBehaviour c, int width, int height, int tileFlags, int portfolioFlags, boolean bubbleEventsToParentPortfolio)
           
 
Method Summary
protected  void customProcessAboutToBeDestroyed()
          Called when the portfolio is about to be destroyed.
protected  void customProcessEndOfFDOPmode(PointInputDevice pen, int button)
          Implement this method to be notified when a PID stops being in FDOP mode.
protected  boolean customProcessEventForThisPortfolioNotChildren(PortfolioEvent e, boolean bubbled)
          Implement this method to receive events.
protected  void customProcessFDOPevent(PortfolioEvent e, double PORTxWhenEnteredFDOPmode, double PORTyWhenEnteredFDOPmode)
          Implement this method to receive FDOP mode events.
 void customRepaintTileForThisPortfolioNotChildren(java.awt.Rectangle r, java.awt.image.BufferedImage update, java.awt.Graphics2D g)
          Implement this method to draw into the portfolio's tile.
 FrameForPortfolio getFrame()
           
static void runLaterFromSwingThread(java.lang.Runnable r)
           
static void runLaterFromSwingThreadUsesPortfolios(PortfolioServer ps, java.lang.Runnable r)
           
 
Methods inherited from class t3.portfolios.Portfolio
bringChildrenToFront, bringChildToFront, createCompatibleBufferedImage, destroyThisAndAllDescendants, getAnscestorsList, getAnscestorsSet, getGpDESKoutlineOfOurTile, getIntegerTileSpaceCoordsFromDESK, getmDESKtoPORTReadOnly, getmDESKtoTILE, getParent, getPortfolioAtCoordinates, getRDESKboundingBoxOfOurTile, getRDESKboundingBoxOfOurTileAndAllDescendantsTiles, getThisAndAnscestorsList, getThisAndAnscestorsSet, getTileHeightInPORT, getTileHeightInTILE, getTileWidthInPORT, getTileWidthInTILE, gettPORTtoDESK, gettPORTtoPPORT, getUd2PORTfromUd2DESK, getVisibileWhenParentVisible, getVisibility, hasTile, isDestroyed, isRoot, setChildToPosition, setDESKtoPORT, setNewChildrenOrder, setPORTtoDESK, setPORTtoPPORT, setTileWidthAndHeightInPORT, setVisibleWhenParentVisible, triggerRepaintEntireTile, triggerRepaintTile, triggerRepaintTile, triggerRepaintTileByCopyingFromOtherPortfoliosTile, unhookFromParentAndMakeChildOf
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SwingFramePortfolio

public SwingFramePortfolio(PortfolioServer pm,
                           Portfolio parent,
                           PortfolioCommonBehaviour c,
                           int width,
                           int height,
                           int tileFlags,
                           int portfolioFlags)

SwingFramePortfolio

public SwingFramePortfolio(PortfolioServer pm,
                           Portfolio parent,
                           PortfolioCommonBehaviour c,
                           int width,
                           int height,
                           int tileFlags,
                           int portfolioFlags,
                           boolean bubbleEventsToParentPortfolio)
Method Detail

runLaterFromSwingThread

public static void runLaterFromSwingThread(java.lang.Runnable r)

runLaterFromSwingThreadUsesPortfolios

public static void runLaterFromSwingThreadUsesPortfolios(PortfolioServer ps,
                                                         java.lang.Runnable r)

getFrame

public FrameForPortfolio getFrame()

customProcessEventForThisPortfolioNotChildren

protected boolean customProcessEventForThisPortfolioNotChildren(PortfolioEvent e,
                                                                boolean bubbled)
Description copied from class: Portfolio
Implement this method to receive events. See PortfolioServer for more information on the event model. Note that any events handled by this portfolio's PortfolioCommonBehaviour object will not be passed to this method.

Specified by:
customProcessEventForThisPortfolioNotChildren in class Portfolio
Parameters:
e - Event
bubbled - True iff the event did not occur on this portfolio's tile but has been bubbled from one of its children.
Returns:
True iff the event should not be bubbled to this portfolio's parent.

customProcessFDOPevent

protected void customProcessFDOPevent(PortfolioEvent e,
                                      double PORTxWhenEnteredFDOPmode,
                                      double PORTyWhenEnteredFDOPmode)
Description copied from class: Portfolio
Implement this method to receive FDOP mode events. See PortfolioServer for more information on the event model. Note that any events handled by this portfolio's PortfolioCommonBehaviour object will not be passed to this method.

Specified by:
customProcessFDOPevent in class Portfolio
Parameters:
e - Event
PORTxWhenEnteredFDOPmode - PORT space coordinate of the PID when it entered FDOP mode.
PORTyWhenEnteredFDOPmode - PORT space coordinate of the PID when it entered FDOP mode.

customProcessEndOfFDOPmode

protected void customProcessEndOfFDOPmode(PointInputDevice pen,
                                          int button)
Description copied from class: Portfolio
Implement this method to be notified when a PID stops being in FDOP mode. See PortfolioServer for more information on the event model. Note that any notifications handled by this portfolio's PortfolioCommonBehaviour object will not be passed to this method.

Specified by:
customProcessEndOfFDOPmode in class Portfolio

customRepaintTileForThisPortfolioNotChildren

public void customRepaintTileForThisPortfolioNotChildren(java.awt.Rectangle r,
                                                         java.awt.image.BufferedImage update,
                                                         java.awt.Graphics2D g)
Description copied from class: Portfolio
Implement this method to draw into the portfolio's tile. The supplied Graphics2D is in the same coordinate space as TILE, with the specified rectangle set to draw into the supplied BufferedImage.

Specified by:
customRepaintTileForThisPortfolioNotChildren in class Portfolio
Parameters:
r - rectangle in TILE space that must be redrawn.
update - BufferedImage of same dimensions as r, into which you draw.
g - Graphics2D which is configured to draw into update.

customProcessAboutToBeDestroyed

protected void customProcessAboutToBeDestroyed()
Description copied from class: Portfolio
Called when the portfolio is about to be destroyed.

Overrides:
customProcessAboutToBeDestroyed in class Portfolio