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.

Similar Messages

  • 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;
    }

  • 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

  • Problems changing colour using Graphics class in java.awt

    Hi,
    The problem only happens when more than two images are on a panel. In this case, I have to strings that are drawn. The first drawn string is called "A" the second drawn string is called "B". However, when i change the colour of "B" to let's say Red, the panel erases the letter "B" and insteads changes "A" to red. How can I fix this so that when the user chooses the colour red it changes the colour of the latest drawn string and not the first one. please help!!!!
    import java.awt.*;
    public class StringPanel extends GBPanel
         private String shape = "clear", str;
         private int x, y;
         private Color color = Color.black;
         public void paintComponent(Graphics g)
              super.paintComponent(g);
              g.setColor (color);
              if(shape.equalsIgnoreCase("draw string"))
                   g.setColor(color);
                   g.drawString(str, x, y);
              else if (shape.equalsIgnoreCase("exit"))
                   System.exit(0);
         public void drawCurve(Color color)
         this.color = color;
         repaint();
         public void drawString(String shape, String str, int x, int y)
              this.shape = shape;
              this.str = str;
              this.x = x;
              this.y = y;
              repaint();
         public void drawString1(String shape, String str, int x, int y)
              Graphics g = getGraphics();
              g.setColor(color);
              if (shape.equalsIgnoreCase("draw string"))
                   g.setColor(color);
                   g.drawString(str, x, y);
              else
                   repaint();
    }

    well, as I said, I can't remember what the update method thing was for... I think it was related to not clearing the screen first.
    Anyway, if you maintain a list of objects that should be drawn and then in the paintComponent method, loop thru the list of objects and redraw them, it will work. Then you change the state of an object and call repaint. When you are going to change color, you need to, in effect, redraw the entire affected area. Now this can be done partially with clipping, but it's complicated to deal with that. So the simplest way is just redraw everything on repaint.

  • Cannot resolve symbol java.awt.graphics

    // DrawRectangleDemo.java
    import java.awt.*;
    import java.lang.Object;
    import java.applet.Applet;
    public class DrawRectangleDemo extends Applet
         public void paint (Graphics g)
              // Get the height and width of the applet's drawing surface.
              int width = getSize ().width;
              int height = getSize ().height;
              int rectWidth = (width-50)/3;
              int rectHeight = (height-70)/2;
              int x = 5;
              int y = 5;
              g.drawRect (x, y, rectWidth, rectHeight);
              g.drawString ("drawRect", x, rectHeight + 30);
              x += rectWidth + 20;
              g.fillRect (x, y, rectWidth, rectHeight);
              // Calculate a border area with each side equal tp 25% of
              // the rectangle's width.
              int border = (int) (rectWidth * 0.25);
              // Clear 50% of the filled rectangle.
              g.clearRect (x + border, y + border,
                             rectWidth - 2 * border, rectHeight - 2 * border);
              g.drawString ("fillRect/clearRect", x, rectHeight + 30);
              x += rectWidth + 20;
              g.drawRoundRect (x, y, rectWidth, rectHeight, 15, 15);
              g.drawString ("drawRoundRect", x, rectHeight + 30);
              x=5;
              y += rectHeight + 40;
              g.setColor (Color.yellow);
              for (int i = 0; i < 4; i++)
                   g.draw3DRect (x + i * 2, y + i * 2,
                                       rectWidth - i * 4, rectHeight - i * 4, false);
              g.setColor (Color.black);
              g.drawString ("draw3DRect", x, y, + rectHeight + 25);
              x += rectWidth + 20;
              g.setColor (Color.yellow);
              g.fill3DRect (x, y, rectWidth, rectHeight, true);
              g.setColor (Color.black);
              g.drawString ("fill3DRect", x, y, + rectHeight + 25);
    Help me with this codes. I typed correctly but there still errors.
    --------------------Configuration: JDK version 1.3.1 <Default>--------------------
    D:\Program Files\Xinox Software\JCreator LE\MyProjects\DrawRectangleDemo.java:56: cannot resolve symbol
    symbol : method drawString (java.lang.String,int,int,int)
    location: class java.awt.Graphics
              g.drawString ("draw3DRect", x, y, + rectHeight + 25);
    ^
    D:\Program Files\Xinox Software\JCreator LE\MyProjects\DrawRectangleDemo.java:64: cannot resolve symbol
    symbol : method drawString (java.lang.String,int,int,int)
    location: class java.awt.Graphics
              g.drawString ("fill3DRect", x, y, + rectHeight + 25);
    ^
    2 errors
    Process completed.
    -------------------------------------------------------------------------------------------------------------------------------

    cannot resolve symbol
    symbol : method drawString (java.lang.String,int,int,int)
    This is telling you that you are trying to invoke the drawString() method with 4 parameters: String, int, int, int
    If you look at the API the drawString() method need 3 parameters: String, int, int - so you have an extra int
    location: class java.awt.Graphics
    g.drawString ("draw3DRect", x, y, + rectHeight + 25);
    Now is you look at your code you will find that you have 3 ',' in you method call. (I don't think you want the ',' after the y.

  • Inability to draw simple graphics in Java properly (threads and JFrame)

    I am trying to use a thread to continually draw randomly positioned and randomly sized squares in the middle of a JFrame window. I have got 'something' working with the following code, however when run, the actual window doesn't come up properly. If I resize the window it does, and I get the result I wanted, but when the window is first opened it does not fully draw itself on screen. Can anybody help here? I am a bit of a novice when it comes to Java
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.*;
    public class TestDraw extends JFrame implements Runnable {
    //DECLARE VARIABLES
         private JLabel lblText;
         private JButton btnBegin;
         private JPanel contentPane;
         private int CoordX, CoordY,SizeX, SizeY, Colour;     // Co'ords for drawing the squares
         Random random = new Random();                              // Random numbers (for square dimensions and colours)
         int n_1 = 450, n_2 = 130, n_3 = 100, n_4 = 4;          // The different ranges of randoms I require
         Thread squares = new Thread(this);                         // Implements a new thread
    //END OF DECLARE VARIABLES
    // CALLS INITIAL PROCEDURE, SETS VISIBLE ETC
         public TestDraw() {
              super();
              initializeComponent();
              this.setVisible(true);
    // INITIALISATION PROCEDURE CALL
         private void initializeComponent() {
              lblText = new JLabel();
              btnBegin = new JButton();
              contentPane = (JPanel)this.getContentPane();
              // lblText
              lblText.setText("This should draw squares on screen...");
              // btnBegin
              btnBegin.setText("Start");
              btnBegin.addActionListener(new ActionListener() {
                   public void actionPerformed(ActionEvent e) {
                        btnBegin_actionPerformed(e);
              // contentPane
              contentPane.setLayout(null);
              addComponent(contentPane, lblText, 10,300,364,18);
              addComponent(contentPane, btnBegin, 144,10,101,28);
              // TestDraw
              this.setTitle("TestDraw Program for CM0246");
              this.setLocation(new Point(0, 0));
              this.setSize(new Dimension(390, 350));
    // POSITION COMPONENTS ON SCREEN
         private void addComponent(Container container,Component c,int x,int y,int width,int height)     {
              c.setBounds(x,y,width,height);
              container.add(c);
    // EVENT HANDLING PROCEDURES
         private void btnBegin_actionPerformed(ActionEvent e) {
              System.out.println("\nAction Event from btnBegin called...");
              squares.start(); //STARTS THE SQUARES DRAWING THREAD (Draws random squares on screen)
    // THE MAIN METHOD (STARTS THE PROGRAM)
         public static void main(String[] args) {
              TestDraw bobdole = new TestDraw();
    // THE SQUARE DRAWINGS THREAD (SHOULD DRAW RANDOM SIZED AND COLOURED SQUARES IN RANDOM PLACES)
         public void run() {
              System.out.println("Thread running if this prints");
                   while(true) {
                        int int_1 = random.nextInt(n_1);     // chooses random int for X co'ord
                        int int_2 = random.nextInt(n_2)+70;     // chooses random int for Y co'ord
                        int int_3 = random.nextInt(n_3)+10;     // chooses random int for X dimension
                        int int_4 = random.nextInt(n_3)+10;     // chooses random int for Y dimension
                        CoordX = int_1;
                        CoordY = int_2;
                        SizeX  = int_3;
                        SizeY  = int_4;
                        repaint();
                        try {
                             squares.sleep(500);
                        catch (InterruptedException e) {
                             System.out.println(e);
    // THE PAINT METHOD ATTATCHED TO THE SQUARES THREAD
         public void paint( Graphics g ) {
              System.out.print("Colour" + Colour);
              g.setColor(Color.blue);
              g.fillRect(CoordX, CoordY, SizeX, SizeY);
    // END OF PROGRAM

    I don't see any problem when I run the program but.. In general you shouldn't paint directly on a frame by overloading the paint method. You should rather create a custom component on which you draw.
    But if you do overload paint, make sure you call super.paint before doing anything else.
    More information in this tutorial: http://java.sun.com/docs/books/tutorial/uiswing/painting/index.html

  • How can i display multiple Pictures in a java.awt.Container best?

    hi,
    I just started with a new Project, it works just like a FileManager.
    On entering a directory all the files in it shall be displayed in a scrollable area. Displayed means here a Graphical representation of the file, in case of a picture a small preview version of it.
    I put together a javax.swing.JScrollPane with a java.awt.Container and viewport. The Container has a FlowLayout.
    Now for every image in a Directory I create a Component-class in witch I overwrote the public void paint(Graphics g) to display a scaled version of the image, this scaled version is created in the Constructor of my Component-class.
    this works fine for just a few images, but if i try to open a directory with a lot of pictures it takes a long time at the beginning and sometimes it just kills the application.
    so i changed in a way that only when a Component is in view of the visible rectangle of the scroll pane the scaled image will be created, and when the component gets out of view the image is set to null.
    now it is running without killing the application, but it takes way too long to scroll now, because the images are loaded all the time.
    so i figured i must be doing something wrong, so what is the best way to get small previews for up to a few hundred files and then display them in a scrollable area? (like in Windows Explorer if you activate the miniature preview)
    if anyone can give me some hints, that would be great
    thanks shirasuresh

    This might give you some ideas:
    import java.awt.*;
    import javax.swing.*;
    public abstract class LazyIcon implements Icon {
        private int width;
        private int height;
        private Image image;
        public LazyIcon(int width, int height) {
            this.width = width;
            this.height = height;
        protected abstract Image createImage();
        public int getIconHeight() {
            return width;
        public int getIconWidth() {
            return height;
        public void paintIcon(Component comp, Graphics g,int x, int y) {
            if (image == null)
                image = createImage();
            g.drawImage(image, x, y, comp);
    }You could also do this with a custom component class, but I like the JLabel + Icon combination.
    Any if you want to get fancy, you could load images in another thread, at low priority, so when the user is just sitting there, your code is preparing the panel for scrolling ;-)
    Message was edited by:
    BigDaddyLoveHandles

  • 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!

  • Problem in java.awt.print

    Hi here is my code .
    I am generating page dynamically and passing to printer.
    Printing Functionalities working file. But I am taking some data from database (Access). And in this code for example i have 4 records in Database and i am generating 4 pages (each page for resord).
    I am getting only 2 records. And for other two records i am getting blank page.
    Reason is My ResultSet object is moving to next record twice.
    I mean if i have 6 records i get only 3 pages.
    If i have 10 records i get only 5 pages and If i have 1 record i dont get any page.
    How shall i solve this problem.
    Thanx in advance.
    import java.awt.*;
    import java.awt.print.*;
    import java.sql.*;
    public class SubbuBook extends Thread implements Printable {
    Connection con;
         Statement stmt;
         static ResultSet rsValue;
         public void run() {
              dataConnection();
              PrinterJob job = PrinterJob.getPrinterJob();
              Book bk = new Book();
              job.setPageable(bk);
              if (job.printDialog()) {
         try {
              bk.append(new SubbuBook(),job.defaultPage(), 4);
              job.print();
              }catch (Exception e) {
              System.out.println("Exception "+e);
         System.exit(0);
    public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException {
         Font fntHeading = new Font("Helvetica",Font.BOLD,24);
    Font fntRow = new Font("Helvetica",Font.PLAIN,14);
         try{
         if(rsValue.next()) {
              g.setFont(fntHeading);
              g.setColor(Color.red);
              g.drawString("Main Report",200,100);
              g.setColor(Color.blue);
              g.drawLine(100,150,500,150);
              g.drawLine(100,150,100,500);
              g.drawLine(100,500,500,500);
              g.drawLine(500,100,500,500);
              g.drawLine(200,150,200,500);
              g.setFont(fntRow);
              g.setColor(Color.black);
              g.drawString("Program Id",120,200);
              g.drawString(rsValue.getString("prog_id"),250,200);
              g.drawString("Program Name",120,250);
              g.drawString(rsValue.getString("prog_name"),250,250);
              g.drawString("Artist Name",120,300);
              g.drawString(rsValue.getString("Artist"),250,300);
         }catch(Exception ae) {
         System.out.println("Exception inside Paint"+ae);
         return Printable.PAGE_EXISTS;
    private void dataConnection() {
         try{
         Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
         con=DriverManager.getConnection("jdbc:odbc:artist");
         stmt=con.createStatement();
         rsValue=stmt.executeQuery("select * from artist order by Prog_name");
         System.out.println("Connection is Proper");
         }catch(Exception e){
              System.out.println("Exception at Connection"+e);

    I am not sure this..
    Instead of if pls give while and check:
    try{
    while(rsValue.next()) {
    g.setFont(fntHeading);
    g.setColor(Color.red);
    g.drawString("Main Report",200,100);

  • Deprecation warning for getFontMetrics(java.awt.Font) in java.awt.Toolkit

    Hi all,
    When I use the following code
    JComponent c;
    FontMetrics metrics = getToolkit().getFontMetrics(c.getFont());
    I get this following warning during compilation:-
    warning: getFontMetrics(java.awt.Font) in java.awt.Toolkit has been deprecated
    JDK suggests to use getLineMetrics() of the Font class.
    But there's an issue with that: if I use getLineMetrics(), there is no API method that I can use to get the width of a string as opposed to FontMetrics which provides stringWidth(String str) method for that purpose. In fact all the methods in FontMetrics are not mapped into LineMetrics.
    Could anyone please help or provide me at least some pointers on how to tackle this issue so that I can get rid of the deprecated method along with the existing methods mapped to equivalent APIs? The bottomline is that I should be able to maintain the existing functinality of my application for those part of code that uses getToolkit().getFontMetrics().
    Thank you for your help in advance.
    -Sanjoy Das

    Use Graphics.getFontMetrics(font) instead.
    After creation your frame and calling frame.show();
    You can access it like that
    frame.show();
    frame.getGraphics().getFontMetrics(new Font("Arial",0,10));
    before showing graphics is null.
    Or just create a BufferedImage and ask it for graphics.
    BufferedImage img=new BufferedImage(...);
    img.getGraphics().getFontMetrics(font);
    regards
    Stas

  • How to move image in Java Awt.

    Hi ,
    I am developing a simple application using Java awt.
    I have created a application which displays a image. now i want it to move automatically using a timer or something.
    How can i do it. if i have to change the x and y position of the image in which function should i do it?
    Which is the function which is called for every frame?
    Thanks
    Glen.

    public void paint(Graphics g)?
    Are you making a game by any chance?

  • Rendering of an 8Bit-tiff with java.awt produces crap

    Hi Folks,
    i do a downsampling of tiff images. The source tiffs are colored 8 Bit greyscale with a 256 color-table. Now i have 2 possibilities to resample with java.awt:
    1. the target-tiff is of 24Bit true color:
    BufferedImage objDownsample = new BufferedImage(iTargetWidth, iTargetHeight, BufferedImage.TYPE_INT_RGB);The result is a perfect looking, but oversized tiff with 16 million colors each pixel.
    2. the target-tiff is of 8Bit like the source-tiff:
    BufferedImage objDownsample = new BufferedImage(iTargetWidth, iTargetHeight, BufferedImage.TYPE_BYTE_INDEXED,(IndexColorModel)image.getColorModel());The result is a small sized tiff image of 8Bit. Problem: it now has visible vertical stripes of two colors (which both composed result the source-color i assume).
    Does anybody know what's wrong here and how to retrieve the 8Bit color-image without stripes?
    Here comes the whole source:
        private BufferedImage resize(int newHeight, int newWidth, BufferedImage image) {
            int iTargetHeight = newHeight;
            int iTargetWidth = newWidth;
            //Create a BufferedImage that fits
            BufferedImage objDownsample = new BufferedImage(iTargetWidth, iTargetHeight, BufferedImage.TYPE_BYTE_INDEXED,(IndexColorModel)image.getColorModel());
            //A map with all necessary rendering hints to optimize the quality of the image
            Map<java.awt.RenderingHints.Key, java.lang.Object> obj_Map = new HashMap<java.awt.RenderingHints.Key, java.lang.Object>();       
            obj_Map.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            obj_Map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            obj_Map.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
          // Draw the scaled image
          Graphics2D graphics2D = objDownsample.createGraphics();
            graphics2D.addRenderingHints(obj_Map);
            graphics2D.drawImage(image, 0, 0, iTargetWidth, iTargetHeight, null);
            return objDownsample;
        }Thanks
    Albrecht

    As far as I can tell, this solution only allows compositing within the component that is currently being painted. What would be nice is if I could add a custom composite to say .. a JLabel, which paints based on the colors of the underlying pixel data (ie. from its parent container). In this way you could make a JLabel that always inverts the color of what's underneath.
    Here, painting to the screen using a composite allows me to get the pixels underneath as the destination raster, the pixels in the JLabel as the source raster, and what actually gets painted which is the destination output raster.
    If I paint to a BufferedImage instead, the composite's 'destination raster' is the new BufferedImage's default values which are all black. Thus compositing over this would not have the desired effects described above (inverting the underlying image for instance). The missing piece when rendering to the BufferedImage is first copying the underlying screen data into a BufferedImage before painting to it. How do I do that? Something tells me it's very difficult.

  • Graphics generated using awt.graphics not displaying when run through a jar

    I've created a small application that works fine when compiled and ran normally.
    When I create a jar and run it, the application works mostly fine too, the button (there's a button in it) shows up, but the graphics produced with java.awt.Graphics don't. What's really weird is that this problem only seems to occur for some people. I sent the jar to some friends and for some of them it worked fine, while others had the same problem I have.
    Can anyone tell me what's causing this and what I can do to fix it?

    I would investigate by finding out what JRE versions are running on each of the users machines and then compare to see if there is a correlation between certain versions and this Graphics problem.

  • Custom Cursor in Java

    I am working on an application in java , where I want to create a
    cursor of CrossHair type in which the horizontal and the vertical
    hairs/lines should run across the entire screen/panel , and not limited to
    32x32 pixel size. With the method Toolkit.createCustomCursor(Image ,
    Hotspot , String) one can create cursors with images of one's choice , BUT
    ONLY OF 32X32 PIXEL SIZE. How can I overcome this restriction ? Is there
    any other way to go about it ?
    I shall be obliged if could please help me solve this problem.
    Yours sincerely ,
    Karunesh Tripathi

    Your idea is worth appreciatoin and holds promise of providing a solution indirectly. I would elaborate my problem further. I want to show this big cursor over a JPanel , occupying a major part of the screen , which is contained in a JFrame alongwith the usual JMenuBar and JToolBar.
    In fact , presently , I am already drawing a cross hair across the panel by g2D.drawLine(int , int , int , int) method in paintComponent(Graphics g) of the JPanel. But it does not move as fast as a cursor , especially when the painting load on the panel increases , because the painting of the cross hair at new location can take place only after the method repaint() as well as the event handler returns.
    Therefore, the solution may have to be searched in the OS (Windows 98 , in this case) and the basic code of java.awt.Toolkit.createCustomCursor(Image , HotSpot , String).
    Your idea may, however , improve the situation significantly , provided the applet is made to float over the JPanel with a transparent background and without borders etc. Can this be done ? I shall be obliged , if you could extend your expertise further.

Maybe you are looking for

  • Additional field in CAT worklist

    Hi, I need to display and populate a custom field for which the screen field is CATS_ADDFI-FIELD1 (additional field1) in CAT worklist.Transaction code is <b>CAT2</b>.The worklist is a table control.How can i achieve this? Regards, Monica.

  • Burning discs through external DVD burner

    I've bought an external DVD burner as PE 10 did not recognise the inbuilt one in windows 8.1. It does not recognise the new burner either. How can I tell it where to burn the disc as the "burner location" box is not accessible. I've tried burning to

  • Video Players for the Flash Phobic | Flash 411 | Adobe TV

    You've got a video, and you just want to play it back on your blog or website. This episode is for you - featuring down and dirty techniques for publishing your video on the Flash platform. http://adobe.ly/wPY4CL

  • No photos in i-photo projects pane

    I've created a couple of calendars on i-photo 08, but now that I want to create a new one I can't seem to access any photos at all in the project pane. All attempts to resolve this have failed,and all updates are installed. Any advice very welcome!

  • Frm messages only in status line not as pop-up

    How can I tell forms to display the frm-messages like frm-40406 transaction completed... only in the status line without any pop-up window which I have to confirm?