concepts2.html
来自「jsf、swing的官方指南」· HTML 代码 · 共 705 行 · 第 1/2 页
HTML
705 行
<p><center><IMG SRC="../../figures/uiswing/painting/border.gif" WIDTH="384" HEIGHT="172" ALIGN="BOTTOM" ALT="Remember to account for the component's border."></center></p><font color=gray>[PENDING: This figure will change to match the previous one better,and to be clearer and more correct.]</font><p>You can get the width and height of any <code>JComponent</code>using its <code>getWidth</code> and <code>getHeight</code> methods.The <code>getSize</code> methodis another optionthat works for all <code>Component</code>s.To determine the border size,use the <code>getInsets</code> method.Here is some code that a component might useto determine the width and heightavailable for custom painting:<blockquote><pre>protected void paintComponent(Graphics g) { ... Insets insets = getInsets(); int currentWidth = getWidth() - insets.left - insets.right; int currentHeight = getHeight() - insets.top - insets.bottom; ... ...<em>/* First painting occurs at (x,y), where x is at least insets.left, and y is at least insets.top. */...</em>}</pre></blockquote><p>To familiarize yourself with the coordinate system,you can play with the CoordinatesDemo application,which features a component implemented usingan inner class named <code>CoordinateArea</code>.The <code>CoordinateArea</code> hasa preferred size of 400x75and a solid red border thatoccupies 5 pixels at the left and bottom,and 1 pixel at the top and right.Like any good component,it starts painting its innards (a 20x20-pixel gray grid)where the border ends —in this case, at (5,1).The <code>CoordinateArea</code> also paints a dot where the user clicks.As you can see from the following figure,a label at the bottom of the GUIdisplays information about the cursor and click location.<p><center><IMG SRC="../../figures/uiswing/painting/CoordinatesDemo.gif" WIDTH="410" HEIGHT="124" ALIGN="BOTTOM" ALT="CoordinatesDemo"></center></p><blockquote><hr><strong>Try this:</strong> <ol><li> <a href="http://java.sun.com/docs/books/tutorialJWS/uiswing/painting/examples/CoordinatesDemo.jnlp">Run CoordinatesDemo</a> using<a class="TutorialLink" target="_top" href="../../information/javawebstart.html">Java<sup><font size=-2>TM</font></sup> Web Start</a>. Or, to compile and run the example yourself, consult the <a href="examples/index.html#CoordinatesDemo">example index</a>.<li> Move the cursor over the <code>CoordinateArea</code>, including its red border. <br> Note the location of the cursor, as displayed at the bottom of the window. (Until bug #<a class="OutsideLink" target="_blank" href="http://developer.java.sun.com/developer/bugParade/bugs/4777616.html">4777616</a> is fixed, when you run CoordinatesDemo using Java Web Start the size of the main component won't be 400x75 — it'll be taller.)<li> Move the cursor to the center of the <code>CoordinateArea</code> and click. <br> A 7x7 dot appears, and the label at the bottom of the window displays its location, as well as the cursor's current location.<li> Move the cursor to be near or barely within the red border on the left or bottom and click. <br> The dot that appears looks smaller than 7x7 because it's obscured by the border. The component's painting code paints it fully, but because the <code>paintBorder</code> method is called after <code>paintComponent</code>, the border is painted on top of the dot. If the border didn't completely paint over its area in an opaque color, you would be able to see more of the dot.</ol><hr></blockquote><p>The SelectionDemo example shown in the following figureis another that can give you a feeling for coordinates.It paints a continuously updating rectangle,which the user sets by dragging the mouse.To avoid unnecessary painting,the component's mouse-dragged and mouse-released event handleruses a version of the <code>repaint</code> methodthat specifies which area of the component needs to be repainted.<p><center><IMG SRC="../../figures/uiswing/painting/SelectionDemo.gif" WIDTH="510" HEIGHT="149" ALIGN="BOTTOM" ALT="More fun with coordinates"></center></p>You can <b><a href=http://java.sun.com/docs/books/tutorialJWS/uiswing/painting/examples/SelectionDemo.jnlp>run SelectionDemo</a></b>using <a class="TutorialLink" target="_top" href="../../information/javawebstart.html">Java Web Start</a>. Or, to compile and run the example yourself, consult the <a href="examples/index.html#SelectionDemo">example index</a>.<p>The code is in<a class="SourceLink" target="_blank" href="examples/SelectionDemo.java"><code>SelectionDemo.java</code></a>.The following snippetshows how <code>repaint</code>is invoked by the event handler formouse-dragged and mouse-released events.The handler gets the current cursor location,updates the selection rectangle,calculates the total area to be repainted,and then specifies that area to the <code>repaint</code> method.Note that the total area to be repaintedis equal to the previously painted areaplus the newly selected area.This way, it cleans up the previous painting,avoiding the faux pas of leaving behind ghost images of the selection rectangle.<blockquote><pre>void updateSize(MouseEvent e) { int x = e.getX(); int y = e.getY(); <em>...//save previous selection rectangle (rectToDraw) //in previousRectDrawn... //calculate new values for rectToDraw...</em> Rectangle totalRepaint = rectToDraw.union(previousRectDrawn); repaint(totalRepaint.x, totalRepaint.y, totalRepaint.width, totalRepaint.height);}</pre></blockquote>Here is the code that paints the selection rectangleon top of the image:<blockquote><pre>g.drawRect(rectToDraw.x, rectToDraw.y, rectToDraw.width - 1, rectToDraw.height - 1)</pre></blockquote><blockquote><hr><strong>Note:</strong> The last two argumentsto <code>drawRect</code>have "- 1"because the painting system draws linesjust below the specified rectangle,instead of within the specified rectangle.The same rule of specifying one less than the desired widthapplies to other <code>draw<em>Xxx</em></code> methods.For <code>fill<em>Xxx</em></code> methods,on the other hand,you specify exactly the desired width and height in pixels.<p>Here are examples of painting two rectangles ofthe same size, one filled and one not:<blockquote><pre>g.fillRect(x, y, rectWidth, rectHeight);g.drawRect(x, y, rectWidth - 1, rectHeight - 1);</pre></blockquote> <hr></blockquote></blockquote><h3>The Graphics Object and Graphics2D</h3><blockquote>The<a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/awt/Graphics.html"><code>Graphics</code></a> object passed into the <code>paintComponent</code> methodprovides both a context and some methods for simple painting.In almost every case, <code>Graphics</code> objectsare actually <a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/awt/Graphics2D.html"><code>Graphics2D</code></a> objects.The <code>Graphics2D</code> classextends <code>Graphics</code>to provide more sophisticated controlover geometry, coordinate transformations, color management,and text layout.You can cast any <code>Graphics</code> parameterinto a <code>Graphics2D</code> objectas long as your program uses the Java 2 platform (1.2 or later)and doesn't use the old printing API.<blockquote><hr><strong>Version note:</strong> The old printing APIis centered around the<a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/awt/PrintJob.html"><code>java.awt.PrintJob</code></a> class.A <a class="TutorialLink" target="_top" href="../../2d/printing/index.html">newer printing API</a> centered around<a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/awt/print/PrinterJob.html"><code>java.awt.print.PrinterJob</code></a> was introduced in 1.2;it uses <code>Graphics2D</code>.In 1.4.1, Java Plug-inprinting was updated to use the newer printing API.<hr></blockquote></ul><p>The painting methods defined by <code>Graphics</code>include such standbys as<code>drawRect</code>, <code>fillRect</code>, and<code>drawLine</code>.The <code>Graphics2D</code> class adds more flexible methods such as <code>draw(Shape)</code> and<code>fill(Shape)</code>.<p>The graphics context provided by a <code>Graphics</code> objectconsists of statesuch asthe current painting color,the current font,andthe current painting area.The <code>Graphics2D</code> classadds more state, such asthe alpha compositing mode,stroke, rendering hints, and color patternssuch as textures and gradients.<p>In <code>JComponent</code>s,the <code>Graphics</code> objectis initializedjust before it's passed to<code>paintComponent</code>,so that its color and font are set to the foreground color and font of the component.The same <code>Graphics</code> objectis then passed to the <code>paintBorder</code>and <code>paintChildren</code> methods.This reuse is efficientbut can lead to trouble if painting codepermanently changes the <code>Graphics</code> object's state.For example, permanently changing the alpha compositing mode of a <code>Graphics2D</code> objectcould cause the component's border or children to be painted incorrectly.To avoid problems, remember this rule:<blockquote><hr> <b>The <code>Graphics</code> object should have the same state when you're finished painting as it had when you started.</b><hr></blockquote><p>You can take two approachesto avoid permanently changing the <code>Graphics</code> object:either restore the <code>Graphics</code> object's original state,or use a copy of the original object.If you take the first approach,you don't need to bother restoring the font and color,since those properties are usually set before painting.Here's an example of the first approach:<blockquote><pre><em>//Example of restoring the Graphics object's state</em>Graphics2D g2d = (Graphics2D)g;g2d.translate(x, y); //set the transform...g2d.translate(-x, -y); //go back to the original transform</pre></blockquote>Here's an example of the second approach:<blockquote><pre><em>//Example of copying the Graphics object</em>Graphics2D g2d = (Graphics2D)g.create(); //copy gg2d.translate(x, y);...g2d.dispose(); //release the copy's resources</pre></blockquote>The advantage of the first approach isthat it doesn't create extra objects.The advantage of the secondis that it's easy and guaranteed to succeed,no matter how much state you change.<p><p>When writing your painting code,keep in mind that you can't depend onany graphics context except what's providedby the <code>Graphics</code> object.For example, if you specify a painting area to <code>repaint</code>,you can't rely onthe same painting area being specified in the next callto <code>paintComponent</code>.For one thing, multiple repaint requests can be coalesced into a single <code>paintComponent</code> call.For another,the painting system occasionally calls <code>paintComponent</code>on its own, without any repaint request from your program —for example,in response to first being shownor to a window that obscured it being moved. </blockquote> <div class=NavBit> <a target=_top href=concepts.html>« Previous</a> • <a target=_top href=../TOC.html>Trail</a> • <a target=_top href=practice.html>Next »</a> </div> </div> <div id=Footer><div id=TagNotes> Problems with the examples? Try <a target="_blank" href=../../information/run-examples.html>Compiling and Running the Examples: FAQs</a>. <br> Complaints? Compliments? Suggestions? <a target="_blank" href="http://developer.sun.com/contact/tutorial_feedback.jsp">Give us your feedback</a>.<br><br> <a target="_blank" href="../../information/copyright.html">Copyright</a> 1995-2006 Sun Microsystems, Inc. All rights reserved. <span id=Download></span></div> </div> <div class=PrintHeaders> <b>Previous page:</b> How Swing Components Are Displayed <br><b>Next page:</b> Implementing a Custom Component </div> </body></html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?