Bug in java.awt.geom.Line2D?

The method,
public static double ptLineDistSq(double X1,
                                  double Y1,
                                  double X2,
                                  double Y2,
                                  double PX,
                                  double PY)calculates the squared distance between a line segment and a point.
If however you pass in a line segment of zero length (X1=X2, Y1=Y2), the method performs a div by zero, which causes NaN to be returned.
I believe this is a bug, as the method makes no exceptions to valid input, also mathmatically the distance from a point to a line segment still has a value even if the line segment has a zero length.
A simple sanity check at the start of the method would fix it,
if(X1==X2 && Y1==Y2) return (X1-PX)*(X1-PX)+(Y1-PY)*(Y1-PY);

Yeah, im already working around it (i've actually just stolen their code, and switched it all from doubles to floats :D - it isn't a serious app. just a problem I encountered when answering a question in this Thread http://forum.java.sun.com/thread.jsp?forum=406&thread=420363&start=30&range=15&tstart=0&trange=15)
I was realy just posting here for confirmation that it is a bug, before I reported it.

Similar Messages

  • Bug in java.awt.geom.Rectangle2D.contains method

    I cannot understand why not awt.geom.Rectangle2D.contains() return the right value??? Or maybe i don�t understand it properly. Check out this code snippet
    import java.awt.geom.*;
    public class Test
        public static void main(String[] args)
           //Rectangle has a width of 2 and a height of 2 and starts drawing on cordinate 1,1
           Rectangle2D rect = new Rectangle2D.Double(1,1,2,2);      
           if (rect.contains(1,3))
               System.out.println("The cordinate is inside rectangle");
           else
               System.out.println("The cordinate is NOT NOT NOT inside rectangle");
    }The cordinate (1,3) is clearly contained in the rectangle or not?
    When you change the cordinate to (1,1) the method works correctly, so why diesn�t it work right with the cordinate (1,3). Can somebody please enlight me?
    Edited by: ripper079 on Dec 6, 2007 4:27 AM

    The cordinate (1,3) is clearly contained in the rectangle or not?Actually, it's a matter of opinion whether a point on the perimeter of a shape is considered contained in the shape or not. This is the implementation of java.awt.geom.Rectangle2D.contains (double x, double y)   public boolean contains(double x, double y) {
         double x0 = getX();
         double y0 = getY();
         return (x >= x0 &&
              y >= y0 &&
              x < x0 + getWidth() &&
              y < y0 + getHeight());
        }As can be seen from the code, the design team adopted a philosophy of returning false for coordinates that lie along the bottom and right sides of the Rectangle.
    If you require different behavior, you can always extend Rectangle2D.Double and override the methodimport java.awt.geom.Rectangle2D;
    public class Test extends Rectangle2D.Double {
        public Test (double x, double y, double w, double h) {
            super (x, y, w, h);
        public boolean contains (double x, double y) {
            double x0 = getX ();
            double y0 = getY ();
            return (x >= x0 &&
                    y >= y0 &&
                    x <= x0 + getWidth () &&
                    y <= y0 + getHeight ());
        public static void main (String[] args) {
            //Rectangle has a width of 2 and a height of 2 and starts drawing on cordinate 1,1
            Rectangle2D rect = new Test (1, 1, 2, 2);
            //Rectangle2D rect = new Rectangle2D.Double (1, 1, 2, 2);
            if (rect.contains (1,3))
                System.out.println ("The cordinate is inside rectangle");
            else
                System.out.println ("The cordinate is NOT inside rectangle");
    }db

  • Will 2D objects in java.awt.geom.* be Serializable in next version of Java?

    I am pretty frustrated about having to write my own Serializable classes. I'm not sure if this is the right place to ask, but will the next version of Java supports Serializable 2D objects?
    Further, I was trying to write my own class to extend java.awt.geom.GeneralPath to become Serializable, but it's declared "final". What should I do? (I had no problems with Rectangle2D.Double, Line2D.Double, etc.)
    Any help is greatly appreciated.
    Selwyn

    Your code for serializing the state of the General path forgets two things:
    1. the winding rule
    2. the segments types!
    You could use a vector, but I just directly wrote to the file:
    private void writeObject(ObjectOutputStream oos) throws IOException
    {     out.defaultWriteObject();
         //write state of transient GeneralPath _gp;
         out.writeInt(_gp.getWindingRule());
         float[] coord = new float[6];
         PathIterator i = _gp.getPathIterator(null);
         while(!i.isDone())
         {     int seg = i.currentSegment(coords);
              writeInt(seg);
              //switch on seg, writing correct # of floats from coords
              i.next();
         out.writeInt(-1);     //sentinel for end-of-data: SEG_LINETO etc are [0,4]
    private void readObject(ObjectInputStream in)
    throws IOException, ClassNotFoundException
    {     in.defaultReadObject();
         int rule = in.readInt();
         _gp = new GeneralPath(rule);
         //etc...
    }3. I'm just winging this code -- haven't tested it
    --Nax                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • What use of having double precision in java.awt.geom?

    Hi,
    I am trying to draw a line using Line2D with this param:
    g2d.draw( new Line2D.Double( 1.1d, 1.5d, 1.9d, 1.5d ) );
    in my own JPanel paint method.
    However, the result is that the panel does not display a line nor a dot at all. Only when i change it to:
    g2d.draw( new Line2D.Double( 1.0d, 1.5d, 2.0d, 1.5d ) );
    that it draws a dot in the panel's first pixel.
    Can someone please guide or tell me why is this so? And what is the purpose of providing a double value for a geom ( such as Rentagle2D, Line2D, etc )?
    The actual case is that I have created a graph with x and y axis. I set the graph to be 400pixel * 400 pixels. And the scale for the graph is 1 million unit * 1 million unit which means a pixel would have contain (1000000/400) units, or 0.004 pixels represent 1 unit. The problem occurs when i try to draw a line that is only 10 unit.(which nothing is draw on the panel). I try to use all 2D geom with double precision, yet i could not get the result that I wanted. Isn't that java 2D will handle the double precision for graphing or drawing?
    Your help and reply is very much appreciated.
    Thank you.

    have in mind that you always have to fill 1 pixel to see anything as the panel has a 1 pixel grid.
    i guess the thing about double precision is in the contains(...) or crosses(...) methods of the geom.* objects.
    its nothing about drawing. how can you draw finer than the 1 pixel grid.
    even the antialias has to fill more pixel to make you thing the line is smooth. (BTW: antialias makes fonts widt less than 10px look terrible :))

  • Custom graphics in java.awt.ScrollPane

    Hi all,
    I have to draw a custom created image in a scroll pane. As the image is very large I want to display it in a scroll pane. As parts of the image may change within seconds, and drawing the whole image is very time consuming (several seconds) I want to draw only the part of the image that is currently visible to the user.
    My idea: creating a new class that extends from java.awt.ScrollPane, overwrite the paint(Graphics) method and do the drawings inside. Unfortunately, it does not work. The background of the scoll pane is blue, but it does not show the red box (the current viewport is not shown in red).
    Below please find the source code that I am using:
    package graphics;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.ScrollPane;
    import java.awt.event.AdjustmentEvent;
    public class CMyComponent extends ScrollPane {
         /** <p>Listener to force a component to repaint when a scroll bar changes its
          * position.</p>
         private final class ScrollBarAdjustmentListener implements java.awt.event.AdjustmentListener {
              /** <p>The component to force to repaint.</p> */
              private final Component m_Target;
              /** <p>Default constructor.</p>
               * @param Target The component to force to repaint.
              private ScrollBarAdjustmentListener(Component Target) { m_Target = Target; }
              /** <p>Forces to component to repaint upon adjustment of the scroll bar.</p>
               *  @see java.awt.event.AdjustmentListener#adjustmentValueChanged(java.awt.event.AdjustmentEvent)
              public void adjustmentValueChanged(AdjustmentEvent e) { m_Target.paint(m_Target.getGraphics()); }
         public CMyComponent() {
              // Ensure that the component repaints upon changing of the scroll bars
              ScrollBarAdjustmentListener sbal = new ScrollBarAdjustmentListener(this);
              getHAdjustable().addAdjustmentListener(sbal);
              getVAdjustable().addAdjustmentListener(sbal);
         public void paint(Graphics g) {
              setBackground(Color.BLUE);
              g.setColor(Color.RED);
              g.fillRect(getScrollPosition().x, getScrollPosition().y, getViewportSize().width, getViewportSize().height);
         public final static void main(String[] args) {
              java.awt.Frame f = new java.awt.Frame();
              f.add(new CMyComponent());
              f.pack();
              f.setVisible(true);
    }

    Dear all,
    I used the last days and tried several things. I think now I have a quite good working solution (just one bug remains) and it is very performant. To give others a chance to see what I have done I post the source code of the main class (a canvas drawing and implementing scrolling) here. As soon as the sourceforge project is accepted, I will publish the whole sources at there. Enjoy. And if you have some idea for my last bug in getElementAtPixel(Point), then please tell me.
    package internetrail.graphics.hexgrid;
    import java.awt.Canvas;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.Point;
    import java.awt.Polygon;
    import java.awt.event.ComponentEvent;
    import java.awt.event.ComponentListener;
    import java.awt.geom.Area;
    import java.awt.image.BufferedImage;
    import java.util.WeakHashMap;
    import java.util.Map;
    /** <p>Hex grid view.</p>
    * <p>Visualizes a {@link IHexGridModel}.</p>
    * @version 0.1, 03.06.2006
    * @author Bjoern Wuest, Germany
    public final class CHexGridView extends Canvas implements ComponentListener, IHexGridElementListener {
         /** <p>Serial version unique identifier.</p> */
         private static final long serialVersionUID = -965902826101261530L;
         /** <p>Instance-constant parameter for the width of a hex grid element.</p> */
         public final int CONST_Width;
         /** <p>Instance-constant parameter for 1/4 of the width of a hex grid element.</p> */
         public final int CONST_Width1fourth;
         /** <p>Instance-constant parameter for 3/4 of the width of a hex grid element.</p> */
         public final int CONST_Width3fourth;
         /** <p>Instance-constant parameter for 1.5 times of the width of a hex grid element.</p> */
         public final int CONST_Width1dot5;
         /** <p>Instance-constant parameter for 4 times of the width of a hex grid element.</p> */
         public final int CONST_Widthquad;
         /** <p>Instance-constant parameter for the height of a hex grid element.</p> */
         public final int CONST_Height;
         /** <p>Instance-constant parameter for 1/2 of the height of a hex grid element.</p> */
         public final int CONST_Heighthalf;
         /** <p>Instance-constant parameter for the double height of a hex grid element.</p> */
         public final int CONST_Heightdouble;
         /** <p>The steepness of a side of the hex grid element (calculated for the upper left arc).</p> */
         public final double CONST_Steepness;
         /** <p>The model of this hex grid </p> */
         private final IHexGridModel m_Model;
         /** <p>A cache for already created images of the hex map.</p> */
         private final Map<Point, Image> m_Cache = new WeakHashMap<Point, Image>();
         /** <p>The graphical area to draw the selection ring around a hex element.</p> */
         private final Area m_SelectionRing;
         /** <p>The image of the selection ring around a hex element.</p> */
         private final BufferedImage m_SelectionRingImage;
         /** <p>The current position of the hex grid in pixels (top left visible corner).</p> */
         private Point m_ScrollPosition = new Point(0, 0);
         /** <p>Flag to define if a grid is shown ({@code true}) or not ({@code false}).</p> */
         private boolean m_ShowGrid = true;
         /** <p>Flag to define if the selected hex grid element should be highlighted ({@code true}) or not ({@code false}).</p> */
         private boolean m_ShowSelected = true;
         /** <p>The offset of hex grid elements shown on the screen, measured in hex grid elements.</p> */
         private Point m_CurrentOffset = new Point(0, 0);
         /** <p>The offset of the image shown on the screen, measured in pixels.</p> */
         private Point m_PixelOffset = new Point(0, 0);
         /** <p>The index of the currently selected hex grid element.</p> */
         private Point m_CurrentSelected = new Point(0, 0);
         /** <p>The width of a buffered pre-calculated image in pixel.</p> */
         private int m_ImageWidth;
         /** <p>The height of a buffered pre-calculated image in pixel.</p> */
         private int m_ImageHeight;
         /** <p>The maximum number of columns of hex grid elements to be shown at once on the screen.</p> */
         private int m_MaxColumn;
         /** <p>The maximum number of rows of hex grid elements to be shown at once on the screen.</p> */
         private int m_MaxRow;
         /** <p>Create a new hex grid view.</p>
          * <p>The hex grid view is bound to a {@link IHexGridModel} and registers at
          * that model to listen for {@link IHexGridElement} updates.</p>
          * @param Model The model backing this view.
         public CHexGridView(IHexGridModel Model) {
              // Set the model
              m_Model = Model;
              CONST_Width = m_Model.getElementsWidth();
              CONST_Height = m_Model.getElementsHeight();
              CONST_Width1fourth = CONST_Width/4;
              CONST_Width3fourth = CONST_Width*3/4;
              CONST_Width1dot5 = CONST_Width*3/2;
              CONST_Heighthalf = CONST_Height/2;
              CONST_Widthquad = CONST_Width*4;
              CONST_Heightdouble = CONST_Height*2;
              CONST_Steepness = (double)CONST_Heighthalf / CONST_Width1fourth;
              m_ImageWidth = getSize().width+CONST_Widthquad;
              m_ImageHeight = getSize().height+CONST_Heightdouble;
              m_MaxColumn = m_ImageWidth / CONST_Width3fourth;
              m_MaxRow = m_ImageHeight / CONST_Height;
              // Register this canvas for various notifications
              m_Model.addElementListener(this);
              addComponentListener(this);
              // Create the selection ring to highlight hex grid elements
              m_SelectionRing = new Area(new Polygon(new int[]{-1, CONST_Width1fourth-1, CONST_Width3fourth+1, CONST_Width+1, CONST_Width3fourth+1, CONST_Width1fourth-1}, new int[]{CONST_Heighthalf, -1, -1, CONST_Heighthalf, CONST_Height+1, CONST_Height+1}, 6));
              m_SelectionRing.subtract(new Area(new Polygon(new int[]{2, CONST_Width1fourth+2, CONST_Width3fourth-2, CONST_Width-2, CONST_Width3fourth-2, CONST_Width1fourth+2}, new int[]{CONST_Heighthalf, 2, 2, CONST_Heighthalf, CONST_Height-2, CONST_Height-2}, 6)));
              m_SelectionRingImage = new BufferedImage(CONST_Width, CONST_Height, BufferedImage.TYPE_INT_ARGB);
              Graphics2D g = m_SelectionRingImage.createGraphics();
              g.setColor(Color.WHITE);
              g.fill(m_SelectionRing);
         @Override public synchronized void paint(Graphics g2) {
              // Caculate the offset of indexes to show
              int offsetX = 2 * (m_ScrollPosition.x / CONST_Width1dot5) - 2;
              int offsetY = (int)(Math.ceil(m_ScrollPosition.y / CONST_Height) - 1);
              m_CurrentOffset = new Point(offsetX, offsetY);
              // Check if the image is in the cache
              Image drawing = m_Cache.get(m_CurrentOffset);
              if (drawing == null) {
                   // The image is not cached, so draw it
                   drawing = new BufferedImage(m_ImageWidth, m_ImageHeight, BufferedImage.TYPE_INT_ARGB);
                   Graphics2D g = ((BufferedImage)drawing).createGraphics();
                   // Draw background
                   g.setColor(Color.BLACK);
                   g.fillRect(0, 0, m_ImageWidth, m_ImageHeight);
                   // Draw the hex grid
                   for (int column = 0; column <= m_MaxColumn; column += 2) {
                        for (int row = 0; row <= m_MaxRow; row++) {
                             // Draw even column
                             IHexGridElement element = m_Model.getElementAt(offsetX + column, offsetY + row);
                             if (element != null) { g.drawImage(element.getImage(m_ShowGrid), (int)(column*(CONST_Width3fourth-0.5)), CONST_Height*row, null); }
                             // Draw odd column
                             element = m_Model.getElementAt(offsetX + column+1, offsetY + row);
                             if (element!= null) { g.drawImage(element.getImage(m_ShowGrid), (int)(column*(CONST_Width3fourth-0.5)+CONST_Width3fourth), CONST_Heighthalf*(row*2+1), null); }
                   // Put the image into the cache
                   m_Cache.put(m_CurrentOffset, drawing);
              // Calculate the position of the image to show
              offsetX = CONST_Width1dot5 + (m_ScrollPosition.x % CONST_Width1dot5);
              offsetY = CONST_Height + (m_ScrollPosition.y % CONST_Height);
              m_PixelOffset = new Point(offsetX, offsetY);
              g2.drawImage(drawing, -offsetX, -offsetY, null);
              // If the selected element should he highlighted, then do so
              if (m_ShowSelected) {
                   // Check if the selected element is on screen
                   if (isElementOnScreen(m_CurrentSelected)) {
                        // Correct vertical offset for odd columns
                        if ((m_CurrentSelected.x % 2 == 1)) { offsetY -= CONST_Heighthalf; }
                        // Draw the selection circle
                        g2.drawImage(m_SelectionRingImage, (m_CurrentSelected.x - m_CurrentOffset.x) * CONST_Width3fourth - offsetX - ((m_CurrentSelected.x + 1) / 2), (m_CurrentSelected.y - m_CurrentOffset.y) * CONST_Height - offsetY, null);
         @Override public synchronized void update(Graphics g) { paint(g); }
         public synchronized void componentResized(ComponentEvent e) {
              // Upon resizing of the component, adjust several pre-calculated values
              m_ImageWidth = getSize().width+CONST_Widthquad;
              m_ImageHeight = getSize().height+CONST_Heightdouble;
              m_MaxColumn = m_ImageWidth / CONST_Width3fourth;
              m_MaxRow = m_ImageHeight / CONST_Height;
              // And flush the cache
              m_Cache.clear();
         public void componentMoved(ComponentEvent e) { /* do nothing */ }
         public void componentShown(ComponentEvent e) { /* do nothing */ }
         public void componentHidden(ComponentEvent e) { /* do nothing */ }
         public synchronized void elementUpdated(IHexGridElement Element) {
              // Clear cache where the element may be contained at
              for (Point p : m_Cache.keySet()) { if (isElementInScope(Element.getIndex(), p, new Point(p.x + m_MaxColumn, p.y + m_MaxRow))) { m_Cache.remove(p); } }
              // Update the currently shown image if the update element is shown, too
              if (isElementOnScreen(Element.getIndex())) { repaint(); }
         /** <p>Returns the model visualized by this grid view.</p>
          * @return The model visualized by this grid view.
         public IHexGridModel getModel() { return m_Model; }
         /** <p>Returns the current selected hex grid element.</p>
          * @return The current selected hex grid element.
         public IHexGridElement getSelected() { return m_Model.getElementAt(m_CurrentSelected.x, m_CurrentSelected.y); }
         /** <p>Sets the current selected hex grid element by its index.</p>
          * <p>If the selected hex grid element should be highlighted and is currently
          * shown on the screen, then this method will {@link #repaint() redraw} this
          * component automatically.</p>
          * @param Index The index of the hex grid element to become the selected one.
          * @throws IllegalArgumentException If the index refers to a non-existing hex
          * grid element.
         public synchronized void setSelected(Point Index) throws IllegalArgumentException {
              // Check that the index is valid
              if ((Index.x < 0) || (Index.y < 0) || (Index.x > m_Model.getXElements()) || (Index.y > m_Model.getYElements())) { throw new IllegalArgumentException("There is no hex grid element with such index."); }
              m_CurrentSelected = Index;
              // If the element is on screen and should be highlighted, then repaint
              if (m_ShowSelected && isElementOnScreen(m_CurrentSelected)) { repaint(); }
         /** <p>Moves the visible elements to the left by the number of pixels.</p>
          * <p>To move the visible elements to the left by one hex grid element, pass
          * {@link #CONST_Width3fourth} as the parameter. The component will
          * automatically {@link #repaint()}.</p>
          * @param Pixels The number of pixels to move to the left.
          * @return The number of pixels moved to the left. This is always between 0
          * and {@code abs(Pixels)}.
         public synchronized int moveLeft(int Pixels) {
              int delta = m_ScrollPosition.x - Math.max(0, m_ScrollPosition.x - Math.max(0, Pixels));
              if (delta != 0) {
                   m_ScrollPosition.x -= delta;
                   repaint();
              return delta;
         /** <p>Moves the visible elements up by the number of pixels.</p>
          * <p>To move the visible elements up by one hex grid element, pass {@link
          * #CONST_Height} as the parameter. The component will automatically {@link
          * #repaint()}.</p>
          * @param Pixels The number of pixels to move up.
          * @return The number of pixels moved up. This is always between 0 and {@code
          * abs(Pixels)}.
         public synchronized int moveUp(int Pixels) {
              int delta = m_ScrollPosition.y - Math.max(0, m_ScrollPosition.y - Math.max(0, Pixels));
              if (delta != 0) {
                   m_ScrollPosition.y -= delta;
                   repaint();
              return delta;
         /** <p>Moves the visible elements to the right by the number of pixels.</p>
          * <p>To move the visible elements to the right by one hex grid element, pass
          * {@link #CONST_Width3fourth} as the parameter. The component will
          * automatically {@link #repaint()}.</p>
          * @param Pixels The number of pixels to move to the right.
          * @return The number of pixels moved to the right. This is always between 0
          * and {@code abs(Pixels)}.
         public synchronized int moveRight(int Pixels) {
              int delta = Math.min(m_Model.getXElements() * CONST_Width3fourth + CONST_Width1fourth - getSize().width, m_ScrollPosition.x + Math.max(0, Pixels)) - m_ScrollPosition.x;
              if (delta != 0) {
                   m_ScrollPosition.x += delta;
                   repaint();
              return delta;
         /** <p>Moves the visible elements down by the number of pixels.</p>
          * <p>To move the visible elements down by one hex grid element, pass {@link
          * #CONST_Height} as the parameter. The component will automatically {@link
          * #repaint()}.</p>
          * @param Pixels The number of pixels to move down.
          * @return The number of pixels moved down. This is always between 0 and
          * {@code abs(Pixels)}.
         public synchronized int moveDown(int Pixels) {
              int delta = Math.min(m_Model.getYElements() * CONST_Height + CONST_Heighthalf - getSize().height, m_ScrollPosition.y + Math.max(0, Pixels)) - m_ScrollPosition.y;
              if (delta != 0) {
                   m_ScrollPosition.y += delta;
                   repaint();
              return delta;
         /** <p>Checks if the hex grid element of the given index is currently
          * displayed on the screen (even just one pixel).</p>
          * <p>The intention of this method is to check if a {@link #repaint()} is
          * necessary or not.</p>
          * @param ElementIndex The index of the element to check.
          * @return {@code true} if the hex grid element of the given index is
          * displayed on the screen, {@code false} if not.
         public synchronized boolean isElementOnScreen(Point ElementIndex) { return isElementInScope(ElementIndex, m_CurrentOffset, new Point(m_CurrentOffset.x + m_MaxColumn, m_CurrentOffset.y + m_MaxRow)); }
         /** <p>Checks if the hex grid element of the given index is within the given
          * indexes.</p>
          * <p>The intention of this method is to check if a {@link #repaint()} is
          * necessary or not.</p>
          * @param ElementIndex The index of the element to check.
          * @param ReferenceIndexLeftTop The left top index of the area to check.
          * @param ReferenceIndexRightBottom The right bottom index of the area to check.
          * @return {@code true} if the hex grid element of the given index is within
          * the given area, {@code false} if not.
         public synchronized boolean isElementInScope(Point ElementIndex, Point ReferenceIndexLeftTop, Point ReferenceIndexRightBottom) { if ((ElementIndex.x >= ReferenceIndexLeftTop.x) && (ElementIndex.x <= ReferenceIndexRightBottom.x) && (ElementIndex.y >= ReferenceIndexLeftTop.y) && (ElementIndex.y <= (ReferenceIndexRightBottom.y))) { return true; } else { return false; } }
         /** <p>Return the {@link IHexGridElement hex grid element} shown at the given
          * pixel on the screen.</p>
          * <p><b>Remark: There seems to be a bug in retrieving the proper element,
          * propably caused by rounding errors and unprecise pixel calculations.</p>
          * @param P The pixel on the screen.
          * @return The {@link IHexGridElement hex grid element} shown at the pixel.
         public synchronized IHexGridElement getElementAtPixel(Point P) {
              // @FIXME Here seems to be some bugs remaining
              int dummy = 0; // Variable for warning to indicate that there is something to do :)
              // Calculate the pixel on the image, not on the screen
              int px = P.x + m_PixelOffset.x;
              int py = P.y + m_PixelOffset.y;
              // Determine the x-index of the column (is maybe decreased by one)
              int x = px / CONST_Width3fourth + m_CurrentOffset.x;
              // If the column is odd, then shift the y-pixel by half element height
              if ((x % 2) == 1) { py -= CONST_Heighthalf; }
              // Determine the y-index of the row (is maybe decreased by one)
              int y = py / CONST_Height + m_CurrentOffset.y;
              // Normative coordinates to a single element
              px -= (x - m_CurrentOffset.x) * CONST_Width3fourth;
              py -= (y - m_CurrentOffset.y) * CONST_Height;
              // Check if the normative pixel is in the first quarter of a column
              if (px < CONST_Width1fourth) {
                   // Adjustments to the index may be necessary
                   if (py < CONST_Heighthalf) {
                        // We are in the upper half of a hex-element
                        double ty = CONST_Heighthalf - CONST_Steepness * px;
                        if (py < ty) { x--; }
                   } else {
                        // We are in the lower half of a hex-element
                        double ty = CONST_Heighthalf + CONST_Steepness * px;
                        if (py > ty) {
                             x--;
                             y++;
              return m_Model.getElementAt(x, y);
    }Ah, just to give you some idea: I use this component to visualize a hex grid map with more than 1 million grid elements. And it works, really fast, and requires less than 10 MByte of memory.

  • How to restrict the maximum size of a java.awt.ScrollPane

    Dear all,
    I would like to implement a scroll pane which is resizable, but not to a size exceeding the maximum size of the java.awt.Canvas that it contains.
    I've sort of managed to do this by writing a subclass of java.awt.ScrollPane which implements java.awt.event.ComponentListener and has a componentResized method that checks whether the ScrollPane's viewport width (height) exceeds the content's preferred size, and if so, resizes the pane appropriately (see code below).
    It seems to me, however, that there ought to be a simpler way to achieve this.
    One slightly weird thing is that when the downsizing of the pane happens, the content can once be moved to the left by sliding the horizontal scrollbar, but not by clicking on the arrows. This causes one column of gray pixels to disappear and the rightmost column of the content to appear; subsequent actions on the scrollbar does not have any further effect. Likewise, the vertical scrollbar can also be moved up once.
    Also, I would like a java.awt.Frame containing such a restrictedly resizable scrollpane, such that the Frame cannot be resized by the user such that its inside is larger than the maximum size of the scrollpane. The difficulty I encountered with that is that setSize on a Frame appears to set the size of the window including the decorations provided by the window manager (fvwm2, if that matters), and I haven't been able to find anything similar to getViewportSize, which would let me find out the size of the area inside the Frame which is available for the scrollpane which the frame contains.
    Thanks in advance for hints and advice.
    Here's the code of the componentResized method:
      public void componentResized(java.awt.event.ComponentEvent e)
        java.awt.Dimension contentSize = this.content.getPreferredSize();
        this.content.setSize(contentSize);
        java.awt.Dimension viewportSize = getViewportSize();
        System.err.println("MaxSizeScrollPane: contentSize = " + contentSize);
        System.err.println("MaxSizeScrollPane: viewportSize = " + viewportSize);
        int dx = Math.max(0, (int) (viewportSize.getWidth() - contentSize.getWidth()));
        int dy = Math.max(0, (int) (viewportSize.getHeight() - contentSize.getHeight()));
        System.err.println("MaxSizeScrollPane: dx = " + dx + ", dy = " + dy);
        if ((dx > 0) || (dy > 0))
          java.awt.Dimension currentSize = getSize();
          System.err.println("MaxSizeScrollPane: currentSize = " + currentSize);
          setSize(new java.awt.Dimension(((int) currentSize.getWidth()) - dx, ((int) currentSize.getHeight()) - dy));
        System.err.println();
      }Best regards, Jan

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    public class ScrollPaneTest
        GraphicCanvas canvas;
        CustomScrollPane scrollPane;
        private Panel getScrollPanel()
            canvas = new GraphicCanvas();
            scrollPane = new CustomScrollPane();
            scrollPane.add(canvas);
            // GridBagLayout allows scrollPane to remain at
            // its preferred size during resizing activity
            Panel panel = new Panel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            panel.add(scrollPane, gbc);
            return panel;
        private WindowListener closer = new WindowAdapter()
            public void windowClosing(WindowEvent e)
                System.exit(0);
        private Panel getUIPanel()
            int w = canvas.width;
            int h = canvas.height;
            int visible = 100;
            int minimum = 200;
            int maximum = 500;
            final Scrollbar
                width  = new Scrollbar(Scrollbar.HORIZONTAL, w,
                                       visible, minimum, maximum),
                height = new Scrollbar(Scrollbar.HORIZONTAL, h,
                                       visible, minimum, maximum);
            AdjustmentListener l = new AdjustmentListener()
                public void adjustmentValueChanged(AdjustmentEvent e)
                    Scrollbar scrollbar = (Scrollbar)e.getSource();
                    int value = scrollbar.getValue();
                    if(scrollbar == width)
                        canvas.setWidth(value);
                    if(scrollbar == height)
                        canvas.setHeight(value);
                    canvas.invalidate();
                    scrollPane.validate();
            width.addAdjustmentListener(l);
            height.addAdjustmentListener(l);
            Panel panel = new Panel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(2,2,2,2);
            gbc.weightx = 1.0;
            addComponents(new Label("width"),  width,  panel, gbc);
            addComponents(new Label("height"), height, panel, gbc);
            gbc.anchor = GridBagConstraints.CENTER;
            return panel;
        private void addComponents(Component c1, Component c2, Container c,
                                   GridBagConstraints gbc)
            gbc.anchor = GridBagConstraints.EAST;
            c.add(c1, gbc);
            gbc.anchor = GridBagConstraints.WEST;
            c.add(c2, gbc);
        public static void main(String[] args)
            ScrollPaneTest test = new ScrollPaneTest();
            Frame f = new Frame();
            f.addWindowListener(test.closer);
            f.add(test.getScrollPanel());
            f.add(test.getUIPanel(), "South");
            f.pack();
            f.setLocation(200,200);
            f.setVisible(true);
            f.addComponentListener(new FrameSizer(f));
    class GraphicCanvas extends Canvas
        int width, height;
        public GraphicCanvas()
            width = 300;
            height = 300;
        public void paint(Graphics g)
            super.paint(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            int dia = Math.min(width, height)*7/8;
            g2.setPaint(Color.blue);
            g2.draw(new Rectangle2D.Double(width/16, height/16, width*7/8, height*7/8));
            g2.setPaint(Color.green.darker());
            g2.draw(new Ellipse2D.Double(width/2 - dia/2, height/2 - dia/2, dia-1, dia-1));
            g2.setPaint(Color.red);
            g2.draw(new Line2D.Double(width/16, height*15/16-1, width*15/16-1, height/16));
        public Dimension getPreferredSize()
            return new Dimension(width, height);
        public Dimension getMaximumSize()
            return getPreferredSize();
        public void setWidth(int w)
            width = w;
            repaint();
        public void setHeight(int h)
            height = h;
            repaint();
    class CustomScrollPane extends ScrollPane
        Dimension minimumSize;
        public Dimension getPreferredSize()
            Component child = getComponent(0);
            if(child != null)
                Dimension d = child.getPreferredSize();
                if(minimumSize == null)
                    minimumSize = (Dimension)d.clone();
                Insets insets = getInsets();
                d.width  += insets.left + insets.right;
                d.height += insets.top + insets.bottom;
                return d;
            return null;
        public Dimension getMinimumSize()
            return minimumSize;
        public Dimension getMaximumSize()
            Component child = getComponent(0);
            if(child != null)
                return child.getMaximumSize();
            return null;
    class FrameSizer extends ComponentAdapter
        Frame f;
        public FrameSizer(Frame f)
            this.f = f;
        public void componentResized(ComponentEvent e)
            Dimension needed = getSizeForViewport();
            Dimension size = f.getSize();
            if(size.width > needed.width || size.height > needed.height)
                f.setSize(needed);
                f.pack();
         * returns the minimum required frame size that will allow
         * the scrollPane to be displayed at its preferred size
        private Dimension getSizeForViewport()
            ScrollPane scrollPane = getScrollPane(f);
            Insets insets = f.getInsets();
            int w = scrollPane.getWidth() + insets.left + insets.right;
            int h = getHeightOfChildren() + insets.top + insets.bottom;
            return new Dimension(w, h);
        private ScrollPane getScrollPane(Container cont)
            Component[] c = cont.getComponents();
            for(int j = 0; j < c.length; j++)
                if(c[j] instanceof ScrollPane)
                    return (ScrollPane)c[j];
                if(((Container)c[j]).getComponentCount() > 0)
                    return getScrollPane((Container)c[j]);
            return null;
        private int getHeightOfChildren()
            Component[] c = f.getComponents();
            int extraHeight = 0;
            for(int j = 0; j < c.length; j++)
                int height;
                if(((Container)c[j]).getComponent(0) instanceof ScrollPane)
                    height = ((Container)c[j]).getComponent(0).getHeight();
                else
                    height = c[j].getHeight();
                extraHeight += height;
            return extraHeight;
    }

  • Awt.geom shape as Icon?

    I want to use a geometric shape (specifically, a small circle) the icon for a JToggleButton. I can't use a static image as I need to be able to change the color of the icon. Is there any class that implements the Icon interface and has the methods of the awt.geom classes?
    Thanks

    Or like this?
    import java.awt.*;
    import java.awt.geom.AffineTransform;
    import java.awt.geom.Ellipse2D;
    import javax.swing.*;
    public class ShapeIcon implements Icon {
        private final Paint paint;
        private final Shape shape;
        public ShapeIcon(Paint paint, Shape shape) {
            this.paint = paint;
            this.shape = shape;
        @Override
        public int getIconHeight() {
            return shape.getBounds().height;
        @Override
        public int getIconWidth() {
            return shape.getBounds().width;
        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
            Graphics2D g2 = ((Graphics2D) g);
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setPaint(paint);
            g2.fill(AffineTransform.getTranslateInstance(x, y).createTransformedShape(shape));
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    JLabel label = new JLabel(new ShapeIcon(
                            Color.RED, new Ellipse2D.Double(0, 0, 32, 32)));
                    label.setBorder(BorderFactory.createLineBorder(Color.BLUE));
                    JOptionPane.showMessageDialog(null, label);
    }

  • OutOfMemory error in java.awt.image.DataBufferInt. init

    We have an applet application that performs Print Preview of the images in the canvas. The images are like a network of entities (it has pictures of the entities involve (let's say Person) and how it links to other entities). We are using IE to launch the applet.
    We set min heap space to 128MB, JVM max heap space to 256MB, java plugin max heap space to 256MB using the Control Panel > Java.
    When the canvas width is about 54860 and height is 1644 and perform Print Preview, it thows an OutOfMemoryError in java.awt.image.DataBufferInt.<int>, hence, the Print Preview page is not shown. The complete stack trace (and logs) is as follows:
    Width: 54860 H: 1644
    Max heap: 254 # using Runtime.getRuntime().maxMemory()
    javaplugin.maxHeapSize: 256M # using System.getProperties("javaplugin.maxHeapSize")
    n page x n page : 1x1
    Exception in thread "AWT-EventQueue-2" java.lang.OutOfMemoryError: Java heap space
         at java.awt.image.DataBufferInt.<init>(Unknown Source)
         at java.awt.image.Raster.createPackedRaster(Unknown Source)
         at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown Source)
         at java.awt.image.BufferedImage.<init>(Unknown Source)
         at com.azeus.gdi.chart.GDIChart.preparePreview(GDIChart.java:731)
         at com.azeus.gdi.chart.GDIChart.getPreview(GDIChart.java:893)
         at com.azeus.gdi.ui.GDIUserInterface.printPreviewOp(GDIUserInterface.java:1526)
         at com.azeus.gdi.ui.GDIUserInterface$21.actionPerformed(GDIUserInterface.java:1438)
         at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
         at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
         at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
         at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
         at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
         at java.awt.Component.processMouseEvent(Unknown Source)
         at javax.swing.JComponent.processMouseEvent(Unknown Source)
         at java.awt.Component.processEvent(Unknown Source)
         at java.awt.Container.processEvent(Unknown Source)
         at java.awt.Component.dispatchEventImpl(Unknown Source)
         at java.awt.Container.dispatchEventImpl(Unknown Source)
         at java.awt.Component.dispatchEvent(Unknown Source)
         at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
         at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
         at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
         at java.awt.Container.dispatchEventImpl(Unknown Source)
         at java.awt.Component.dispatchEvent(Unknown Source)
         at java.awt.EventQueue.dispatchEvent(Unknown Source)
         at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
         at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
         at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
         at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
         at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
         at java.awt.EventDispatchThread.run(Unknown Source)
    Drilling down the cause of the problem. The OutOfMemory occurred in the constructor of DataBufferInt when it tried to create an int array:
    public DataBufferInt(int size) {
    super(STABLE, TYPE_INT, size);
    data = new int[size]; # this part produce out of memory error when size = width X height
    bankdata = new int[1][];
    bankdata[0] = data;
    The OutOfMemory error occurred when size is width * height (54860 X 1644) which is 90,189,840 bytes (~86MB).
    I can replicate the OutOfMemory error when initiating an int array using a test class when it uses the default max heap space but if I increase the heap space to 256MB, it cannot be replicated in the test class.
    Using a smaller width and height with product not exceeding 64MB, the applet can perform Print Preview successfully.
    Given this, I think the java applet is not using the value assigned in javaplugin.maxHeapSize to set the max heap space, hence, it still uses the default max heap size and throws OutOfMemory in int array when size exceeds the default max heap space which is 64MB.
    For additional information, below is some of the java properties (when press S in java applet console):
    browser = sun.plugin
    browser.vendor = Sun Microsystems, Inc.
    browser.version = 1.1
    java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
    java.awt.printerjob = sun.awt.windows.WPrinterJob
    java.class.path = C:\PROGRA~1\Java\jre6\classes
    java.class.version = 50.0
    java.class.version.applet = true
    java.runtime.name = Java(TM) SE Runtime Environment
    java.runtime.version = 1.6.0_17-b04
    java.specification.version = 1.6
    java.vendor.applet = true
    java.version = 1.6.0_17
    java.version.applet = true
    javaplugin.maxHeapSpace = 256M
    javaplugin.nodotversion = 160_17
    javaplugin.version = 1.6.0_17
    javaplugin.vm.options = -Xms128M -Djavaplugin.maxHeapSpace=256M -Xmx256m -Xms128M
    javawebstart.version = javaws-1.6.0_17
    Kindly advise if this is a bug in JRE or wrong setting. If wrong setting, please advise on the proper way to set the heap space to prevent OutOfMemory in initializing int array.
    Thanks a lot.
    Edited by: rei_xanther on Jun 28, 2010 12:01 AM
    Edited by: rei_xanther on Jun 28, 2010 12:37 AM

    rei_xanther wrote:
    ..But the maximum value of the int data type is 2,147,483,647. That is the maximum positive integer value that can be stored in (the 4 bytes of) a signed int, but..
    ..The value that I passed in the int array size is only 90,189,840...its only connection with RAM is that each int requires 4 bytes of memory to hold it.
    new int[size] -- size is 90,189,840Sure. So the number of bytes required to hold those 90,189,840 ints is 360,759,360.
    I assumed that one element in the int array is 1 byte. ..Your assumption is wrong. How could it be possible to store 32 bits (4 bytes) in 8 bits (1 byte)? (a)
    a) Short of some clever compression algorithm applied to the data.

  • Java.awt.Dialog in Java 1.6 has a memory leak

    When a modal Dialog opens a modal sub-dialog, the Dialog stays in memory after both the sub-dialog and the Dialog itself is disposed.
    The field that contains the leaked object is Dialog.modalDialogs (static). The methods which causes the leak are Dialog.modalHide and Dialog.modalShow.
    Whenever a modal Dialog is opened, Dialog.modalShow is called, and adds itself to Dialog.modalDialogs.
    When it closes, Dialog.modalHide is called and removes one copy of itself from Dialog.modalDialogs. Then Dialog.modalShow is called on all previously blocked modal dialogs. When the sub-dialog is opened and closed, Dialog.modalDialogs contains two references to the main Dialog, and only one of them is removed when Dialog.modalHide for that Dialog is called.
    To detect the leak, just put a break point in Dialog.modalHide, after modalDialogs.remove(this);. When opening a Dialog and closing it without opening a sub-dialog, the Dialog.modalDialogs field should be empty. When a sub-dialog was opened and closed before the main Dialog is closed, the Dialog.modalDialogs field contains a reference to the disposed main Dialog.
    This leak does not exist in 1.5.0_10 (no Dialog.modalDialogs field). I have searched the bug database, but I have not found this bug there. Could anyone confirm this?
    A simple code to reproduce the leak:
    import java.awt.Dimension;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowEvent;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    public class Test {
       public static void main(String[] args) {
          final JFrame frame = new JFrame() {
             protected void processWindowEvent(WindowEvent e) {
                super.processWindowEvent(e);
                if (e.getID() == WindowEvent.WINDOW_CLOSING) {
                   System.exit(0);
          JButton button = new JButton("Dialog");
          button.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent aE) {
                JButton subButton = new JButton("SubDialog");
                subButton.addActionListener(new ActionListener() {
                   public void actionPerformed(ActionEvent aE) {
                      JOptionPane.showMessageDialog(frame, "SubDialog");
                JOptionPane.showMessageDialog(frame, subButton);
          frame.getContentPane().add(button);
          frame.pack();
          // Center the window
          Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
          Dimension frameSize = frame.getSize();
          if (frameSize.height > screenSize.height) {
             frameSize.height = screenSize.height;
          if (frameSize.width > screenSize.width) {
             frameSize.width = screenSize.width;
          frame.setLocation((screenSize.width - frameSize.width) / 2,
                (screenSize.height - frameSize.height) / 2);
          frame.setVisible(true);
    }

    Sorry, I just found the bug in the bugdatabase (with google of course,):
    [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6497929]

  • Quality of Cursors created with java.awt.Toolkit(createCutsomCursor)

    Hi -
    I encountered a small problem while creating my own cursors for my Java application , I used the java.awt.Toolkit Objects createCustomCursor method to use a .GIF image as a cursor ... it worked but the quality of that cursor is horrible, the outline is rough ... I tried the same with a transparent PNG file afterwards unfortunately the same result , does anyone know why the quality is that bad or may this just be a problem of the choosen color pool ?
    Help would be very appreciated since I have no clue how to use .cur files ... seems like a non supported format , in case someone knows how to import those it would help a lot if you would drop some lines of code.
    I am currently using Java 2 SDK 1.4.0_01 , newest version.
    Thanks for you time and thanks in advance for possible answers
    -- Harald Scheckenbacher

    I noticed this problem too. It looks like the routine is generating cursors which are scaled to to the maximum size of the system. On my win XP system,
    Dimension dim = toolkit.getBestCursorSize(256, 256);
    int maxColors = toolkit.getMaximumCursorColors();
    return 32,32 and 256 respectively
    If I provide a 16x16, all the pixels have been pixel doubled. If I specify a 32x32 image, then the cursor looks perfect. This looks like a bug for the java folks. Not sure why someone would ever want a cursor image to be pixel scaled.
              

  • AccessClassInPackage.sun.awt.geom

    My class imports sun.awt.geom.Crossings in order to implement a similar-to-java.awt.Polygon intersects method, upon float values. This takes place in an applet. The all known error message appears in the java console:
    java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.awt.geom)
    I should actually sign my applet just to import that package!? (lets say the policy file is not an option in my case)
    Why is that package different in such a way, than other packages? Is it not located together with all the other classes that compose the jre? (Also, is it documented somewhere?) May it be that the jre of the client that runs the applet would not necessarily provide this package or is it a standard in the J2SE jre?
    When an applet imports java.awt.Polygon (wihch imports sun.awt.geom.Crossings) no AccessControlException in thrown. I wonder.
    Thanks.
    mplexus2

    all the sun.* packages are offlimits to Applets since they contain code that could comprimise the system, and they do not contain any security checks. There may be an exception in one of the sun's get audio file.

  • If Statement in java.awt paint

    import java.applet.Applet;  //bring in the applet class
    import java.awt.*;             //bring in the graphics class
    import java.awt.event.*;      //bring in the event class
    import java.text.DecimalFormat;    //bring in the decimal format class
    import java.lang.Float;       //bring in the float class
    public class Bmi extends Applet implements ActionListener {   //begin program and start ActionListener
      Label weight, height;    //define Label variable
      TextField weighttext, heighttext;    //define TextField variables
      Button calculate;     //define button variables
      float index, wt, ht, max, min;    //define float variables
      DecimalFormat fmt2 = new DecimalFormat("#.00"); //set decimal format for reals
    public void init() {    //begin init()
      weight = new Label("Please enter your weight in Kg. (2 decimal places): ");   //define content of Label weight
      weighttext = new TextField(6);            //define size of TextField
      height = new Label("Please enter your height in Metres (2 decimal places): ");   //define content of Label height
      heighttext = new TextField(5);    //define size of TextField
      calculate = new Button("Calculate!!");       //define content of Button
      add(weight);      //add Label weight to the GUI
      add(weighttext);   //add TextField weighttext to the GUI
      add(height);      //add Label height to the GUI
      add(heighttext);     //add TextField heighttext to the GUI
      add(calculate);        //add button calculate to the GUI
      calculate.addActionListener(this);    //wait for button to be returned
      wt = 0;     //reset wt to 0
      index = 0;  //reset index to 0
      ht = 0;      //reset ht to 0
      max = 0;      //reset max to 0
      min = 0;    //reset min to 0
      public void actionPerformed( ActionEvent e ) {   //run upon return of button
      wt = Float.parseFloat(weighttext.getText());  //convert weighttext from String to Float
      ht = Float.parseFloat(heighttext.getText());    //covert heighttext from String to Float
      repaint();     //refresh paint area
      public float indexer()  //begin indexer method
        float ind;    //delare local variable ind
        ind = wt/(ht*ht);      //perform calculation
        return ind;    //make indexer() the value of variable ind
      }  // end of indexer method
      public float maxWeight()  //begin maxWeight method
        float maxwt;    //declare local variable maxwt
        final float UPPER = 25.0f;   //declare variable UPPER as a float with a decimal value of 25.0
        maxwt = UPPER*ht*ht;      //perform calculation
        return maxwt;          //make maxWeight() the value of variable maxwt
      }  // end of maxWeight method
      public float minWeight()   //begin minWeight method
        float minwt;    //declare local variable minwt
        final float LOWER= 20.0f;   //declare variable LOWER as a float with a decimal value of 20.0
        minwt = LOWER*ht*ht;    //perform calculation
        return minwt;      //make minWeight() the value of variable minwt
      }  // end of minWeight method
    public void paint(Graphics g)    //begin paint method, define g as Graphics
        index=indexer();   //covert method indexer() to variable index
        max=maxWeight();      //convert method maxWeight() to variable max
        min=minWeight();     //convert method minWeight() to variable min
        g.setFont(new Font("Verdana", Font.ITALIC, 15));    //define font, weight and size
        g.setColor(new Color(90,90,90));     //set new colour
        g.drawRect(5,100,300,75);      //define size of rectangle
        g.setColor(new Color(255,107,9));   //set new colour
        g.drawString("BMI is " + fmt2.format(index) + " for " + fmt2.format(wt) + "kg",20,120);   //create string in paint, define its on screen position
        g.drawString("Maximum bodyweight is " + fmt2.format(max) + "kg", 20,140);   //create string in paint, define its on screen position
        g.drawString("Minimum bodyweight is " + fmt2.format(min) + "kg", 20,160);     //create string in paint, define its on screen position
      }  // end of paint method
    }    // end of Bmi classI have written the above code to calculate someones BMI (Body Mass Index). Basically as you can see it recieves a weight and height from the user and calculates the rest. But whilst that good I would like to know how I can make it tell the user something to the effect of "Your overweight" or "Your underweight". The if statement runs like this:
    if (wt > max)This forum doesn't quite handle <> properly. The greater and less than symbols. So above you will see > this is the html character code for a greater than symbol so please read it as such.
    And then if wt is greater than max then it will say "Your overweight".
    But I can't figure out how to include it in the above program. Becuase it won't run in paint, atleast it won't the way I have done it previously. So can you think of any other ways?
    Help much appreciated,
    Simon

    Thanks very much that works well.
    Simon
    My code now looks like this: import java.applet.Applet;  //bring in the applet class
    import java.awt.*;             //bring in the graphics class
    import java.awt.event.*;      //bring in the event class
    import java.text.DecimalFormat;    //bring in the decimal format class
    import java.lang.Float;       //bring in the float class
    public class Bmi extends Applet implements ActionListener {   //begin program and start ActionListener
      Label weight, height;    //define Label variable
      TextField weighttext, heighttext;    //define TextField variables
      Button calculate;     //define button variables
      float index, wt, ht, max, min;    //define float variables
      DecimalFormat fmt2 = new DecimalFormat("#.00"); //set decimal format for reals
    public void init() {    //begin init()
      weight = new Label("Please enter your weight in Kg. (2 decimal places): ");   //define content of Label weight
      weighttext = new TextField(6);            //define size of TextField
      height = new Label("Please enter your height in Metres (2 decimal places): ");   //define content of Label height
      heighttext = new TextField(5);    //define size of TextField
      calculate = new Button("Calculate!!");       //define content of Button
      add(weight);      //add Label weight to the GUI
      add(weighttext);   //add TextField weighttext to the GUI
      add(height);      //add Label height to the GUI
      add(heighttext);     //add TextField heighttext to the GUI
      add(calculate);        //add button calculate to the GUI
      calculate.addActionListener(this);    //wait for button to be returned
      wt = 0;     //reset wt to 0
      index = 0;  //reset index to 0
      ht = 0;      //reset ht to 0
      max = 0;      //reset max to 0
      min = 0;    //reset min to 0
      public void actionPerformed( ActionEvent e ) {   //run upon return of button
      wt = Float.parseFloat(weighttext.getText());  //convert weighttext from String to Float
      ht = Float.parseFloat(heighttext.getText());    //covert heighttext from String to Float
      repaint();     //refresh paint area
      public float indexer()  //begin indexer method
        float ind;    //delare local variable ind
        ind = wt/(ht*ht);      //perform calculation
        return ind;    //make indexer() the value of variable ind
      }  // end of indexer method
      public float maxWeight()  //begin maxWeight method
        float maxwt;    //declare local variable maxwt
        final float UPPER = 25.0f;   //declare variable UPPER as a float with a decimal value of 25.0
        maxwt = UPPER*ht*ht;      //perform calculation
        return maxwt;          //make maxWeight() the value of variable maxwt
      }  // end of maxWeight method
      public float minWeight()   //begin minWeight method
        float minwt;    //declare local variable minwt
        final float LOWER= 20.0f;   //declare variable LOWER as a float with a decimal value of 20.0
        minwt = LOWER*ht*ht;    //perform calculation
        return minwt;      //make minWeight() the value of variable minwt
      }  // end of minWeight method
    public void you(Graphics g)
      String statement;
      if(wt > max) statement="You are very fat";
      else if(wt < min) statement="You are very thin";
      else statement="You are in the recommended weight range for your height";
      g.drawString(statement, 20,210);
    public void paint(Graphics g)    //begin paint method, define g as Graphics
        you(g);
        index=indexer();   //covert method indexer() to variable index
        max=maxWeight();      //convert method maxWeight() to variable max
        min=minWeight();     //convert method minWeight() to variable min
        g.setFont(new Font("Verdana", Font.ITALIC, 15));    //define font, weight and size
        g.setColor(new Color(90,90,90));     //set new colour
        g.drawRect(5,100,300,75);      //define size of rectangle
        g.setColor(new Color(255,107,9));   //set new colour
        g.drawString("BMI is " + fmt2.format(index) + " for " + fmt2.format(wt) + "kg",20,120);   //create string in paint, define its on screen position
        g.drawString("Maximum bodyweight is " + fmt2.format(max) + "kg", 20,140);   //create string in paint, define its on screen position
        g.drawString("Minimum bodyweight is " + fmt2.format(min) + "kg", 20,160);     //create string in paint, define its on screen position
      }  // end of paint method
    }    // end of BmiThanks again,
    Simon

  • Can I build a GUI application with SWING only without [import java.awt.*;]

    I have seen several threads (in forums), books and tutorials about SWING and I see that they all mix SWING with AWT (I mean they import both Swing and AWT in their code).
    The conclusion that comes out is:
    It is good to learn about SWING and forget AWT as it won't be supported later. I have decided to do so, and I never include <<import java.awt.*;>> in my code.
    But I see that you cannot do much without <<import java.awt.*;>>. For example this line which changes the background color:
    <<frame.getContentPane().setBackground(Color.red)>>
    works only with <<import java.awt.*;>>. I have seen that codes in this and other forums import awt to change the background. Why is that?
    After all, I wonder, what can I do;
    My question is, can I change the background (and of course do all other things listener, buttons etc) without using <<import java.awt.*;>>.
    I would like to avoid using <<import java.awt.*;>> and using awt since my program will not work later.
    In addition, I believe there is no point to learn awt, which later will not exist.
    I know, I must have misunderstood something. I would appreceate it very much, if anyone could give me even a short answer.
    Thank you in advance,
    JMelsi

    Since swing is a layer on top of awt, AWT will exist for as long as swing does.
    If sun does ever remove AWT they will have to replace it something else swing can layer on to and you will probably only have to replace your import statements.
    The main difference is the way there drawn to the screen.
    You can do custom drawing on swing components but you can't on AWT.
    If your using a desktop PC system it's probably best to use swing just in case you wish to do some custom drawing.
    awt uses less memory than swing and is faster but swing can be extended. awt comes only as standard.
    Say for example you wish to implement a JButton with a ProgressBar below the button text, this can be done with swing!

  • The method add() in java.awt.Container made me in confuse

    Here is my two java code file:
    //MyContainer.java
    package sam.gui;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import javax.swing.JApplet;
    import javax.swing.JFrame;
    public class MyContainer extends JApplet {
         private MyButton[] myButton = new MyButton[2];
         private static int counter = 0;
         public MyContainer() {
              myButton[0] = new MyButton(5, 5, 200, 30);
              myButton[1] = new MyButton(5, 40, 200, 30);
              for (int i = 0; i < myButton.length; i++) {
                   add(myButton);
         public void paint(Graphics g) {
              for (int i = 0; i < myButton.length; i++) {
                   System.out.println("MyButton : " + (i+1));
                   myButton[i].draw(g);
         public static void main(String[] args) {
              MyContainer container = new MyContainer();
              JFrame f = new JFrame();
              f.getContentPane().add(container);
              f.pack();
              f.setSize(new Dimension(300, 200));
              f.show();
    //MyButton.java
    package sam.gui;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    public class MyButton extends Component {
         private Color m_rectColor = new Color(128, 73, 0);
         public MyButton(int x, int y, int width, int height) {
              setBounds(x, y, width, height);     
         public void draw(Graphics g) {
              Graphics2D g2 = (Graphics2D)g;
              g.setColor(m_rectColor);
              g.fillRect(0, 0,
                        getBounds().width, getBounds().height);
              System.out.println("x = " + getBounds().x);
              System.out.println("y = " + getBounds().y);
              System.out.println("width = " + getBounds().width);
              System.out.println("height = " + getBounds().height);          
    I thinked the runned result should be below:
    MyButton : 1
    x = 5
    y = 5
    width = 200
    height = 30
    MyButton : 2
    x = 5
    y = 40
    width = 200
    height = 30But in fact, its result is here:
    MyButton : 1
    x = 5
    y = 5
    width = 200
    height = 30
    MyButton : 2
    x = 0
    y = 0
    width = 292
    height = 173I don't know why the result would like this? I have used add(...) method to add two component MyButton to the container MyContainer, But the bounds of the second component is not I want.
    So this problem made me go into confuse.

    You need to learn how layout managers work. The default layout manager of a JApplet and JFrame is BorderLayout .
    /Kaj

  • Using List Class in java.awt / java.util ?

    have a program that:
    import java.util.*;
    List list = new LinkedList();
    list = new ArrayList();
    ... read a file and add elements to array
    use a static setter
    StaticGettersSetters.setArray(list);
    next program:
    import java.awt.*;
    public static java.util.List queryArray =
    StaticGettersSetters.getArray();
    If I don't define queryArray with the package and class, the compiler
    gives an error that the List class in java.awt is invalid for queryArray.
    If I import the util package, import java.util.*; , the compiler
    gives an error that the list class is ambiguous.
    Question:
    If you using a class that exists in multiple packages, is the above declaration of queryArray the only way to declare it ?
    Just curious...
    Thanks for your help,
    YAM-SSM

    So what you have to do is explicitly tell the compiler which one you really want by spelling out the fully-resolved class name:
    import java.awt.*;
    import java.sql.*;
    import java.util.*;
    public class ClashTest
        public static void main(String [] args)
            java.util.Date today    = new java.util.Date();
            java.util.List argsList = Arrays.asList(args);
            System.out.println(today);
            System.out.println(argsList);
    }No problems here. - MOD

Maybe you are looking for

  • Does anyone know how to get photos from iCloud back on your iPhone?

    I was having issues with my iPhone 4 not charging anymore. I went to the apple store today and ended up having to buy a replacment phone. When I was going through the set-up, I tried to do an iCloud restore but wasn't able to as the new iPhone didn't

  • Any way to identify emails that were open when Mail crashed?

    Admittedly, I probably had too many emails sitting open (plus a bunch of open tabs in 3 different browsers). Mail crashes, and I Force Quit. When I reopen mail, a few emails do repoen, but the majority do not. Is there any way of identifying which em

  • Approver gets refreshed after the contract is released

    Hi All, I am facing a problem while creating GOA i have activated the one step approval workflow WS 14000088 and have the agent assignment based on standard roles. I can see the approver picked up correctly in approval preview but when i release the

  • JDBC Error: ORA-01000: maximum open cursors exceeded

    Post Author: prashant CA Forum: Information OnDemand I successfully created reports using CR4E on windows, deployed JSPS to Websphere running on windows and was able to view a large reports for a using JNDI connection resources to Oracle 10g. Every t

  • RAC Install on Virtual Machines

    Howdy.... I am trying to get first steps into RAC. I only got one Notebook to work with ... and since VMware works nice I figured ...I might be able to setup a two node cluster. I wonder if it is even possible? (I am thinking of Failovertimes and suc