How To Draw On Panel Java
- Click to view our Accessibility Policy
- Skip to content
Painting in AWT and Swing
Skillful Painting Code Is the Fundamental to App Operation
In a graphical system, a windowing toolkit is unremarkably responsible for providing a framework to brand it relatively painless for a graphical user interface (GUI) to render the right bits to the screen at the correct time.
Both the AWT (abstruse windowing toolkit) and Swing provide such a framework. But the APIs that implement it are not well understood past some developers -- a trouble that has led to programs non performing equally well equally they could. - By Amy Fowler
This article explains the AWT and Swing paint mechanisms in detail. Its purpose is to help developers write correct and efficient GUI painting code. While the article covers the general pigment mechanism ( where and when to render), it does not tell how to utilize Swing'due south graphics APIs to render a right output.
The main topics covered in this article are:
- Development of Paint System
- Painting in the AWT
- Organisation-Triggered vs. App-Triggered Painting
- The Paint Method
- Painting & Lightweight Components
- "Smart" Painting
- AWT Painting Guidelines
- Painting in Swing
- Double Buffering Support
- Boosted Paint Backdrop
- The Paint Methods
- Paint Processing
- The Repaint Director
- Swing Painting Guidelines
- Summary
Development of the Swing Paint Organization
When the original AWT API was developed for JDK one.0, simply heavyweight components existed ("heavyweight" means that the component has information technology'south own opaque native window). This allowed the AWT to rely heavily on the paint subsystem in each native platform. This scheme took intendance of details such equally impairment detection, prune calculation, and z-ordering. With the introduction of lightweight components in JDK 1.ane (a "lightweight" component is one that reuses the native window of its closest heavyweight ancestor), the AWT needed to implement the paint processing for lightweight components in the shared Java code. Consequently, there are subtle differences in how painting works for heavyweight and lightweight components.
Afterwards JDK 1.one, when the Swing toolkit was released, it introduced its ain spin on painting components. For the most part, the Swing painting mechanism resembles and relies on the AWT'due south. Only it besides introduces some differences in the mechanism, also every bit new APIs that make it easier for applications to customize how painting works.
Painting in AWT
To empathise how AWT's painting API works, helps to know what triggers a paint operation in a windowing environment. In AWT, there are ii kinds of painting operations: system-triggered painting, and application-triggered painting.
System-triggered Painting
In a arrangement-triggered painting performance, the system requests a component to render its contents, usually for i of the following reasons:
- The component is kickoff made visible on the screen.
- The component is resized.
- The component has damage that needs to be repaired. (For instance, something that previously obscured the component has moved, and a previously obscured portion of the component has become exposed).
App-triggered Painting
In an application-triggered painting performance, the component decides it needs to update its contents because its internal state has changed. (For example,. a button detects that a mouse push button has been pressed and determines that it needs to paint a "depressed" button visual).
The Paint Method
Regardless of how a paint asking is triggered, the AWT uses a "callback" mechanism for painting, and this machinery is the same for both heavyweight and lightweight components. This means that a program should place the component's rendering lawmaking inside a particular overridden method, and the toolkit will invoke this method when information technology's fourth dimension to pigment. The method to exist overridden is in java.awt.Component:
public void paint(Graphics g)
When AWT invokes this method, the Graphics object parameter is pre-configured with the advisable state for drawing on this particular component:
- The
Graphicsobject's colour is prepare to the component'sforegroundproperty. - The
Graphicsobject's font is set to the component'sfontproperty. - The
Graphicsobject's translation is set up such that the coordinate (0,0) represents the upper left corner of the component. - The
Graphicsobject's clip rectangle is set to the surface area of the component that is in need of repainting.
Programs must utilize this Graphics object (or ane derived from it) to render output. They are gratuitous to modify the state of the Graphics object as necessary.
Hither is a simple example of a paint callback which renders a filled circumvolve in the bounds of a component:
public void pigment(Graphics chiliad) { // Dynamically calculate size information Dimension size = getSize(); // diameter int d = Math.min(size.width, size.height); int x = (size.width - d)/2; int y = (size.height - d)/2; // draw circumvolve (color already set to foreground) g.fillOval(x, y, d, d); m.setColor(Color.black); g.drawOval(x, y, d, d); } Developers who are new to AWT might want to take a peek at the PaintDemo example, which provides a runnable program case of how to use the paint callback in an AWT program.
In general, programs should avoid placing rendering code at any bespeak where information technology might be invoked exterior the scope of the paint callback. Why? Considering such code may be invoked at times when it is not advisable to paint -- for example, before the component is visible or has access to a valid Graphics object. It is not recommended that programs invoke pigment() directly.
To enable app-triggered painting, the AWT provides the following java.awt.Component methods to allow programs to asynchronously request a paint functioning:
public void repaint() public void repaint(long tm) public void repaint(int x, int y, int width, int height) public void repaint(long tm, int 10, int y, int width, int height) The post-obit code shows a unproblematic example of a mouse listener that uses repaint() to trigger updates on a theoretical button component when the mouse is pressed and released:
MouseListener l = new MouseAdapter() { public void mousePressed(MouseEvent east) { MyButton b = (MyButton)e.getSource(); b.setSelected(truthful); b.repaint(); } public void mouseReleased(MouseEvent e) { MyButton b = (MyButton)eastward.getSource(); b.setSelected(false); b.repaint(); } }; Components that render circuitous output should invoke repaint() with arguments defining only the region that requires updating. A mutual mistake is to always invoke the no-arg version, which causes a repaint of the entire component, often resulting in unnecessary paint processing.
paint() vs. update()
Why exercise we make a distinction between "system-triggered" and. "app-triggered" painting? Because AWT treats each of these cases slightly differently for heavyweight components (the lightweight case will be discussed later on), which is unfortunately a source of not bad confusion.
For heavyweight components, these two types of painting happen in the 2 distinct ways, depending on whether a painting operation is system-triggered or app-triggered.
System-triggered painting
This is how a system-triggered painting functioning takes place:
- The AWT determines that either role or all of a component needs to be painted.
- The AWT causes the issue dispatching thread to invoke
pigment()on the component.
App-triggered painting
An app-triggered painting operation takes place as follows:
The plan determines that either part or all of a component needs to be repainted in response to some internal state change.
The plan invokes repaint() on the component, which registers an asynchronous asking to the AWT that this component needs to be repainted.
The AWT causes the event dispatching thread to invoke update() on the component.
NOTE: If multiple calls to repaint() occur on a component before the initial repaint request is candy, the multiple requests may be collapsed into a single call to update(). The algorithm for determining when multiple requests should be collapsed is implementation-dependent. If multiple requests are collapsed, the resulting update rectangle volition exist equal to the union of the rectangles contained in the collapsed requests.
If the component did not override update(), the default implementation of update() clears the component's background (if it's not a lightweight component) and simply calls pigment().Since by default, the concluding result is the same ( paint() is called), many people don't understand the purpose of having a separate update() method at all. While it's true that the default implementation of update() turns effectually and calls paint(), this update "claw" enables a programme to handle the app-triggered painting case differently, if desired. A program must assume that a telephone call to paint() implies that the surface area divers by the graphic's prune rectangle is "damaged" and must be completely repainted, all the same a call to update() does not imply this, which enables a program to practice incremental painting.
Incremental painting is useful if a programme wishes to layer additional rendering on top of the existing $.25 of that component. The UpdateDemo example demonstrates a programme which benefits from using update() to do incremental painting.
In truth, the bulk of GUI components do not need to practise incremental drawing, and so most programs can ignore the update() method and simply override paint() to render the component in it's current state. This means that both system-triggered and app-triggered rendering volition essentially be equivelent for almost component implementations.
Painting & Lightweight Components
From an application developer's perspective, the paint API is basically the same for lightweights every bit it is for heavyweights (that is, you just override pigment() and invoke repaint() to trigger updates). However, since AWT's lightweight component framework is written entirely in common Java code, at that place are some subtle differences in the style the machinery is implemented for lightweights.
How Lightweights Become Painted
For a lightweight to exist, it needs a heavyweight somewhere up the containment hierarchy in order to have a place to pigment. When this heavyweight ancestor is told to paint its window, it must interpret that paint call to paint calls on all of its lightweight descendents. This is handled by java.awt.Container's pigment() method , which calls paint() on whatever of its visible, lightweight children which intersect with the rectangle to be painted. So it's disquisitional for all Container subclasses (lightweight or heavyweight) that override paint() to practice the following:
public course MyContainer extends Container { public void pigment(Graphics g) { // pigment my contents kickoff... // then, make certain lightweight children pigment super.pigment(g); } } If the telephone call to super.paint() is missing, then the container'southward lightweight descendents won't show up (a very mutual problem when JDK i.ane first introduced lightweights).
It'due south worth noting that the default implementation of Container.update() does non use recursion to invoke update() or paint() on lightweight descendents. This means that any heavyweight Container subclass that uses update() to exercise incremental painting must ensure that lightweight descendents are recursively repainted if necessary. Fortunately, few heavyweight container components need incremental painting, so this consequence doesn't affect well-nigh programs.
Lightweights & System-triggered Painting
The lightweight framework code that implements the windowing behaviors (showing, hiding, moving, resizing, etc.) for lightweight components is written entirely in Coffee. Often, within the Java implementation of these functions, the AWT must explicitly tell various lightweight components to paint (substantially organization-triggered painting, even though it's no longer originating from the native system). Even so, the lightweight framework uses repaint() to tell components to pigment, which we previously explained results in a call to update() instead of a straight phone call to pigment(). Therefore, for lightweights, organisation-triggered painting tin can follow 2 paths:
- The system-triggered paint request originates from the native system (i.e. the lightweight's heavyweight ancestor is outset shown), which results in a direct call to
paint(). - The system-triggered paint asking originates from the lightweight framework (i.e., the lightweight is resized), which results in a call to
update(), which past default is forwarded topigment().
In a nutshell, this ways that for lightweight components there is no real distinction between update() and paint(), which further implies that the incremental painting technique should not be used for lightweight components.
Lightweights and Transparency
Since lightweight components "borrow" the screen real estate of a heavyweight ancestor, they support the characteristic of transparency. This works considering lightweight components are painted from back to forepart and therefore if a lightweight component leaves some or all of its associated $.25 unpainted, the underlying component volition "show through." This is likewise the reason that the default implementation of update() will non clear the background if the component is lightweight.
The LightweightDemo sample program demonstrates the transparency feature of lightweight components.
"Smart" Painting
While the AWT attempts to make the process of rendering components as efficient every bit possible, a component's pigment() implementation itself can have a significant impact on overall functioning. Two cardinal areas that tin impact this process are:
- Using the clip region to narrow the scope of what is rendered.
- Using internal noesis of the layout to narrow the scope of what children are painted (lightweights only).
If your component is simple -- for instance, if it's a pushbutton -- then it's not worth the effort to factor the rendering in social club to only paint the portion that intersects the clip rectangle; it's preferable to simply paint the entire component and permit the graphics clip appropriately. However, if you've created a component that renders complex output, similar a text component, then it'south critical that your code employ the clip information to narrow the amount of rendering.
Further, if you're writing a complex lightweight container that houses numerous components, where the component and/or its layout manager has information well-nigh the layout, then it's worth using that layout knowledge to be smarter about determining which of the children must exist painted. The default implementation of Container.paint() only looks through the children sequentially and tests for visibility and intersection -- an operation that may be unnecessarily inefficient with sure layouts. For instance, if a container layed out the components in a 100x100 grid, then that grid information could be used to determine more quickly which of those x,000 components intersect the clip rectangle and actually need to exist painted.
AWT Painting Guidelines
The AWT provides a uncomplicated callback API for painting components. When yous use it, the post-obit guidelines utilise:
- For most programs, all client paint code should exist placed inside the scope of the component's
paint()method. - Programs may trigger a time to come call to
paint()by invokingrepaint(), but shouldn't telephone callpigment()directly. - On components with circuitous output,
repaint()should be invoked with arguments which define only the rectangle that needs updating, rather than the no-arg version, which causes the entire component to be repainted. - Since a call to
repaint()results first in a call toupdate(), which is forwarded topaint()by default, heavyweight components may overrideupdate()to do incremental drawing if desired (lightweights practice non back up incremental drawing) - Extensions of
java.awt.Containerwhich overridepaint()should always invokesuper.paint()to ensure children are painted. - Components which render complex output should make smart use of the prune rectangle to narrow the drawing operations to those which intersects with the clip area.
Painting in Swing
Swing starts with AWT'southward basic painting model and extends it further in order to maximize operation and better extensibility. Like AWT, Swing supports the paint callback and the use of repaint() to trigger updates. Additionally, Swing provides built-in support for double-buffering as well as changes to support Swing'southward additional structure (like borders and the UI consul). And finally, Swing provides the RepaintManager API for those programs who desire to customize the pigment mechanism further.
Double Buffering Support
Ane of the most notable features of Swing is that information technology builds support for double-buffering right into the toolkit. It does the by providing a "doubleBuffered" property on javax.swing.JComponent:
public boolean isDoubleBuffered() public void setDoubleBuffered(boolean o) Swing'southward double buffer mechanism uses a single offscreen buffer per containment hierarchy (usually per top-level window) where double-buffering has been enabled. And although this belongings can be set on a per-component basis, the result of setting it on a item container volition have the effect of causing all lightweight components underneath that container to be rendered into the offscreen buffer, regardless of their individual "doubleBuffered" property values.
By default, this holding is set to truthful for all Swing components. But the setting that really matters is on JRootPane, because that setting effectively turns on double-buffering for everything underneath the top-level Swing component. For the virtually part, Swing programs don't need to do annihilation special to deal with double-buffering, except to make up one's mind whether it should be on or off (and for smooth GUI rendering, you'll want information technology on!). Swing ensures that the appropriate type of Graphics object (offscreen paradigm Graphics for double-buffering, regular Graphics otherwise) is passed to the component'south paint callback, so all the component needs to do is draw with it. This mechanism is explained in greater item subsequently in this article, in the section on Pigment Processing.
Additional Paint Properties
Swing introduces a couple of additional properties on JComponent in order to improve the efficiency of the internal paint algorithms. These properties were introduced in order to bargain with the following two issues, which can make painting lightweight components an expensive operation:
- Transparency: If a lightweight component is painted, it's possible that the component will not pigment all of its associated bits if partially or totally transparent; this ways that whenever it is repainted, whatever lies underneath it must be repainted kickoff. This requires the arrangement to walk upwards the containment hierarchy to notice the first underlying heavyweight ancestor from which to begin the back-to-front paint operation.
- Overlapping components: If a lightweight component is painted, its possible that some other lightweight component partially overlaps it; this means that whenever the original lightweight component is painted, whatever components which overlap the original component (where the clip rectangle intersects with the overlapping area) the overlapping component must also exist partially repainted. This requires the system to traverse much of the containment hierarchy, checking for overlapping components on each paint operation.
Opacity
To amend functioning in the common example of opaque components, Swing adds a read-write opaque property to javax.swing.JComponent:
public boolean isOpaque() public void setOpaque(boolean o) The settings are:
-
true: The component agrees to paint all of the bits contained inside its rectangular bounds. -
false: The component makes no guarantees about painting all the bits within its rectangular bounds.
The opaque property allows Swing'south paint system to detect whether a repaint request on a particular component will require the additional repainting of underlying ancestors or not. The default value of the opaque property for each standard Swing component is set by the current look and experience UI object. The value is true for well-nigh components.
One of the most common mistakes component implementations make is that they allow the opaque property to default to true, nonetheless they exercise not completely render the surface area defined by their bounds, the result is occasional screen garbage in the unrendered areas. When a component is designed, careful idea should exist given to its handling of the opaque property, both to ensure that transparency is used wisely, since information technology costs more at paint fourth dimension, and that the contract with the pigment system is honored.
The meaning of the opaque property is ofttimes misunderstood. Sometimes information technology is taken to mean, "Make the component's background transparent." Still, this is non Swing'due south strict interpretation of opacity. Some components, such as a pushbutton, may set the opaque property to imitation in gild to give the component a non-rectangular shape, or to go out room around the component for transient visuals, such equally a focus indicator. In these cases, the component is not opaque, but a major portion of its background is still filled in.
Equally divers previously, the opaque property is primarily a contract with the repaint organization. If a component also uses the opaque property to ascertain how transparency is practical to a component's visuals, then this use of the property should be documented. (Information technology may be preferable for some components to define additional backdrop to control the visual aspects of how transparency is applied. For case, javax.swing.AbstractButton provides the ContentAreaFilled property for this purpose.)
Another issue worth noting is how opacity relates to a Swing component's border property. The surface area rendered by a Border object set up on a component is withal considered to exist part of that component's geometry. This means that if a component is opaque, it is however responsible for filling the area occupied past the edge. (The border then just layers its rendering on top of the opaque component).
If you lot want a component to allow the underlying component to show through its border expanse -- that is, if the edge supports transparency via isBorderOpaque() returning false -- then the component must define itself to be non-opaque and ensure information technology leaves the border area unpainted.
"Optimized" Drawing
The overlapping component issue is more catchy. Even if none of a component's firsthand siblings overlaps the component, it's always possible that a not-antecedent relative (such equally a "cousin" or "aunt") could overlap it. In such a instance the repainting of a single component inside a circuitous hierarchy could require a lot of treewalking to ensure 'correct' painting occurs. To reduce unnecessary traversal, Swing adds a read-merely isOptimizedDrawingEnabled property to javax.swing.JComponent:
public boolean isOptimizedDrawingEnabled()
The settings are:
-
true: The component indicates that none of its firsthand children overlap. -
false: The component makes no guarantees about whether or not its immediate children overlap
Past checking the isOptimizedDrawingEnabled property, Swing can quickly narrow its search for overlapping components at repaint time.
Since the isOptimizedDrawingEnabled property is read-only, so the simply way components can change the default value is to subclass and override this method to return the desired value. All standard Swing components return true for this holding, except for JLayeredPane, JDesktopPane, and JViewPort.
The Paint Methods
The rules that apply to AWT'south lightweight components also utilise to Swing components -- for example, paint() gets called when it's fourth dimension to render -- except that Swing farther factors the paint() telephone call into three separate methods, which are invoked in the post-obit lodge:
protected void paintComponent(Graphics g) protected void paintBorder(Graphics k) protected void paintChildren(Graphics g) Swing programs should override paintComponent() instead of overriding paint(). Although the API allows it, there is more often than not no reason to override paintBorder() or paintComponents() (and if you do, make sure y'all know what yous're doing!). This factoring makes it easier for programs to override only the portion of the painting which they demand to extend. For example, this solves the AWT problem mentioned previously where a failure to invoke super.paint() prevented whatever lightweight children from appearing.
The SwingPaintDemo sample program demonstrates the uncomplicated use of Swing'south paintComponent() callback.
Painting and the UI Consul
Most of the standard Swing components have their look and feel implemented by separate wait-and-experience objects (called "UI delegates") for Swing's Pluggable await and experience characteristic. This means that most or all of the painting for the standard components is delegated to the UI delegate and this occurs in the following manner:
-
paint()invokespaintComponent(). - If the
uiproperty is not-zero,paintComponent()invokesui.update(). - If the component's
opaqueholding is truthful,ui.udpate()fills the component's background with the groundwork color and invokesui.paint(). -
ui.paint()renders the content of the component.
This means that subclasses of Swing components which have a UI consul (vs. direct subclasses of JComponent), should invoke super.paintComponent() within their paintComponent override:
public grade MyPanel extends JPanel { protected void paintComponent(Graphics thousand) { // Let UI delegate paint first // (including background filling, if I'm opaque) super.paintComponent(g); // paint my contents next.... } } If for some reason the compone nt extension does not want to allow the UI delegate to paint (if, for example, it is completely replacing the component's visuals), it may skip calling super.paintComponent(), but it must be responsible for filling in its own background if the opaque holding is truthful, equally discussed in the section on the opaque belongings.
Paint Processing
Swing processes "repaint" requests in a slightly unlike mode from the AWT, although the final result for the application programmer is essentially the same -- pigment() is invoked. Swing doesthis to support its RepaintManager API (discussed after), as well as to improve paint functioning. In Swing, painting can follow two paths, every bit described below:
(A) The paint request originates on the starting time heavyweight ancestor (usually JFrame, JDialog, JWindow, or JApplet):
- the result dispatching thread invokes
paint()on that ancestor - The default implementation of
Container.paint()recursively callspigment()on any lightweight descendents - When the first Swing component is reached, the default implementation of
JComponent.pigment()does the post-obit:- if the component'south
doubleBufferedholding istrueand double-buffering is enabled on the component'due southRepaintManager, will convert theGraphicsobject to an advisable offscreen graphics. - invokes
paintComponent()(passing in offscreen graphics if doubled-buffered) - invokes
paintBorder()(passing in offscreen graphics if doubled-buffered) - invokes
paintChildren()(passing in offscreen graphics if doubled-buffered), which uses the clip and theopaqueandoptimizedDrawingEnabledbackdrop to determine exactly which descendents to recursively invokepigment()on. - if the component'due south
doubleBufferedbelongings istrueand double-buffering is enabled on the component'southRepaintManager, copies the offscreen image to the component using the original on-screenGraphicsobject.
Note: the
JComponent.paint()steps #1 and #5 are skipped in the recursive calls topaint()(frompaintChildren(), described in footstep#4) considering all the lightweight components within a Swing window bureaucracy will share the same offscreen image for double-buffering. - if the component'south
(B) The pigment request originates from a call to repaint() on an extension of javax.swing.JComponent:
-
JComponent.repaint()registers an asynchronous repaint request to the component'sRepaintManager, which usesinvokeLater()to queue aRunnableto afterwards process the request on the event dispatching thread. - The runnable executes on the event dispatching thread and causes the component'south
RepaintManagerto invokepaintImmediately()on the component, which does the following:- uses the clip rectangle and the
opaqueandoptimizedDrawingEnabledbackdrop to decide the 'root' component from which the paint operation must begin (to bargain with transparency and potentially overlapping components). - if the root component's
doubleBufferedproperty istruthful, and double-buffering is enabled on the root'sRepaintManager, will convert theGraphicsobject to an appropriate offscreen graphics. - invokes
paint()on the root component (which executes (A)'due southJComponent.pigment()steps #2-4 in a higher place), causing everything under the root which intersects with the clip rectangle to be painted. - if the root component'due south
doubleBufferedbelongings istruthfuland double-buffering is enabled on the root'sRepaintManager, copies the offscreen image to the component using the original on-screenGraphicsobject.
Annotation: if multiple calls to
repaint()occur on a component or any of its Swing ancestors before the repaint request is processed, those multiple requests may be collapsed into a single call dorsum topaintImmediately()on the topmost Swing component on whichrepaint()was invoked. For example, if aJTabbedPanecontains aJTableand both issue calls torepaint()before whatsoever awaiting repaint requests on that hierarchy are processed, the outcome will be a single phone call topaintImmediately()on theJTabbedPane, which will crusadepaint()to be executed on both components. - uses the clip rectangle and the
This ways that for Swing components, update() is never invoked.
Although repaint() results in a call to paintImmediately(), information technology is non considered the paint "callback", and client paint code should not be placed inside of a paintImmediately(). In fact, there is no common reason to override paintImmediately() at all.
Synchronous Painting
Every bit described in the previous section, paintImmediately() acts every bit the entry point for telling a single Swing component to paint itself, making sure that all the required painting occurs appropriately. This method may also be used for making synchronous paint requests, as its name implies, which is sometimes required by components which need to ensure their visual advent 'keeps upwards' in real time with their internal country (due east.g. this is true for the JScrollPane during a roll operation).
Programs should not invoke this method directly unless there is a valid need for real-time painting. This is because the asynchronous repaint() will crusade multiple overlapping requests to be complanate efficiently, whereas direct calls to paintImmediately() will not. Additionally, the rule for invoking this method is that it must be invoked from the effect dispatching thread; it's not an api designed for multi-threading your pigment code!. For more details on Swing's single-threaded model, see the archived article "Threads and Swing."
The RepaintManager
The purpose of Swing'south RepaintManager class is to maximize the efficiency of repaint processing on a Swing containment hierarchy, and also to implement Swing'south 'revalidation' mechanism (the latter will exist a subject for a split up commodity). It implements the repaint mechanism past intercepting all repaint requests on Swing components (so they are no longer processed by the AWT) and maintaining its own state on what needs to be updated (known as "dirty regions"). Finally, it uses invokeLater() to process the awaiting requests on the result dispatching thread, as described in the section on "Repaint Processing" (option B).
For most programs, the RepaintManager tin be viewed as part of Swing's internal arrangement and can virtually be ignored. Even so, its API provides programs the option of gaining finer control over certain aspects of painting.
The "Current" RepaintManager
The RepaintManager is designed to be dynamically plugged, although past default there is a single instance. The following static methods allow programs to get and set the "current" RepaintManager:
public static RepaintManager currentManager(Component c) public static RepaintManager currentManager(JComponent c) public static void setCurrentManager(RepaintManager aRepaintManager) Replacing The "Current" RepaintManager
A programme would extend and supplant the RepaintManager globally past doing the following:
RepaintManager.setCurrentManager(new MyRepaintManager());
You lot can likewise run into RepaintManagerDemo for a elementary running example of installing a RepaintManager which prints out data about what is beingness repainted.
A more interesting reason for extending and replacing the RepaintManager would be to change how information technology processes repaint requests. Currently the internal state used by the default implementation to rails muddy regions is package private and therefore not accessible by subclasses. Even so, programs may implement their ain mechanisms for tracking muddied regions and for collapsing requests by overriding the following methods:
public synchronized void addDirtyRegion(JComponent c, int x, int y, int due west, int h) public Rectangle getDirtyRegion(JComponent aComponent) public void markCompletelyDirty(JComponent aComponent) public void markCompletelyClean(JComponent aComponent) { The addDirtyRegion() method is the one which is invoked when repaint() is called on a Swing component, and thus can exist hooked to catch all repaint requests. If a programme overrides this method (and does non call super.addDirtyRegion()) then it becomes its responsibility to utilize invokeLater() to place a Runnable on the EventQueue which will invoke paintImmediately() on an appropriate component (translation: not for the faint of eye).
Global Control Over Double-Buffering
The RepaintManager provides an API for globally enabling and disabling double-buffering:
public void setDoubleBufferingEnabled(boolean aFlag) public boolean isDoubleBufferingEnabled()
This property is checked within of JComponent during the processing of a pigment performance in social club to determine whether to employ the offscreen buffer for rendering. This belongings defaults to true, simply programs wishing to globally disable double-buffering for all Swing components tin can do the post-obit:
RepaintManager.currentManager(mycomponent). setDoubleBufferingEnabled(simulated);
Notation: since Swing's default implementation instantiates a single RepaintManager instance, the mycomponent argument is irrelevant.
Swing Painting Guidelines
Swing programs should understand these guidelines when writing paint code:
- For Swing components,
paint()is always invoked as a result of both system-triggered and app-triggered paint requests;update()is never invoked on Swing components. - Programs may trigger a future phone call to
paint()by invokingrepaint(), but shouldn't telephone callpaint()straight. - On components with circuitous output,
repaint()should be invoked with arguments which define only the rectangle that needs updating, rather than the no-arg version, which causes the entire component to exist repainted. - Swing's implementation of
paint()factors the phone call into 3 separate callbacks:-
paintComponent() -
paintBorder() -
paintChildren()
paintComponent()method ( not withinpaint()). -
- Swing introduces two properties to maximize painting efficiency:
-
opaque: volition the component paint all its bits or not? -
optimizedDrawingEnabled: may whatever of this component's children overlap?
-
- If a Swing component's
opaqueproperty is ready totruthful, then information technology is like-minded to pigment all of the $.25 contained within its bounds (this includes immigration it'southward own background withinpaintComponent()), otherwise screen garbage may result. - Setting either the
opaqueoroptimizedDrawingEnabledproperties tofalseon a component will crusade more processing on each pigment operation, therefore nosotros recommend judicious employ of both transparency and overlapping components. - Extensions of Swing components which accept UI delegates (including
JPanel), should typically invokesuper.paintComponent()inside their ownpaintComponent()implementation. Since the UI delegate volition take responsibility for clearing the groundwork on opaque components, this will take care of #five. - Swing supports built-in double-buffering via the
JComponentdoubleBufferedholding, and information technology defaults totruefor all Swing components, however setting it totrueon a Swing container has the general issue of turning information technology on for all lightweight descendents of that container, regardless of their individual property settings. - It is strongly recommended that double-buffering be enabled for all Swing components.
- Components which return complex output should brand smart use of the clip rectangle to narrow the drawing operations to those which intersect with the clip surface area.
Summary
To get the best functioning from these APIs, application programs must besides accept responsibleness for writing programs which use the guidelines outlined in this document.
Source: https://www.oracle.com/java/technologies/painting.html
Posted by: alexanderthowas1943.blogspot.com

0 Response to "How To Draw On Panel Java"
Post a Comment