ScrollPane Canvas

HI guys !
I am making a chat window like in a instant messenger.
I am extending a scrollpane and adding a canvas and painting strings and emoticons to this ...
The size of the canvas is always equivalent to the size of its parent i.e the scrollpane.But wht i want is as soon as the typed messages painted on the canvas ,go beyond the height of the canvas ,the scrollbars should appear like in normal messengers and the canvas height should increase.Whenever the scrollpane's size changes ,the canvas size changes.To get the scrollbars manually i have to use the setsize.If i use the setsize method then it is called twice one by the scrollpane and one by my code- and it goes in some infinite loop.Anybody knows how to deal with this problem.. I tried to override the setsize method but eventually i had to use the setsize mehtod to change the size of the canvas which results in the same behaviour.
Any help will be appreciated.
Thnx,
Viral.

1. First option is to use a TextArea instead of a canvas, this will set the scrollbars automaticaly.
2. If you realy need a canvas, set it size outside of paint methode, the loop you describe is probably because you set the size in the paint method.
Noah

Similar Messages

  • ScrollPane Canvas repaint

    hello everybody,
    I am adding a Canvas to a ScrollPane and adding different Strings to this Canvas using drawString method.
    But the problem is that when i scroll up or sidewards then the contens are repainted and i can see the contents of the Canvas. How to do this.
    Pls help me out.
    I am putting down my code below.
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import java.applet.*;
    public class MyTest extends Applet
    MyScroll sc;
    MyNewComponent newComponent;
    public void init()
    sc = new MyScroll();
    newComponent = new MyNewComponent();
    newComponent.setBounds(0,0,100,100);
    newComponent.addElements();
    sc.add(newComponent);
              sc.updateComponent(newComponent);
    add(sc);
              sc.validate();
    class MyNewComponent extends Canvas
    Vector lines,fonts,colors;
    int x=0,y=10;
    Enumeration linesEnu,colorEnu;
    public void MyComponent()
    public void addElements()
    lines = new Vector();
              fonts = new Vector();
    colors = new Vector();
    lines.addElement(" Jogi ");
    lines.addElement(" Prabha ");
    lines.addElement(" Kothi ");
    lines.addElement(" Naresh ");
              lines.addElement(" Murthy");
              lines.addElement(" vishal ");
    linesEnu = lines.elements();
                   colorEnu = colors.elements();
    public void paint(Graphics g)
    Font f = new Font("SansSerif",Font.BOLD,10);
    while(linesEnu.hasMoreElements())
    g.setColor(Color.black);
    g.setFont(f);
    g.drawString(""+linesEnu.nextElement(),x,y );
    y=y+10;
    public void update(Graphics g)
              paint(g);
    class MyScroll extends ScrollPane
         public void MyScroll()
         public void paint(Graphics g)
         public void update(Graphics g)
         public void updateComponent(MyNewComponent o)
              o.repaint();
    Thanks in advance

    In addition to the previous reply:
    You use an enumeration to go through the strings, which you create outside the paint method. As an enumeration only allows you to go through its contents once, the first call to paint after adding a string will work ok, whereas all subsequent calls will find an empty enumeration, i.e. one, where hasMoreElements returns false immediately.
    So, move your inesEnu = lines.elements() command to the paint-method, too.
    Bye, Marc.

  • Problems with ScrollPane's

    I have a ScrollPane
    // Canvas
    Canvas m_MapCanvas = new Canvas();
    // ScrollPane
    ScrollPane scrollPane1 = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
    // add mouse listener's
    addMouseMotionListener(this);
    addMouseListener(this);
    // Canvas init
    m_MapCanvas.setBounds(0,0,512,512);
    // Init
    scrollPane1.setBounds(new Rectangle(MapPos.x, MapPos.y, 800, 600));
    scrollPane1.getVAdjustable().setUnitIncrement( 32 );
    scrollPane1.add(m_MapCanvas);
    scrollPane1.addMouseListener(this);
    scrollPane1.addMouseMotionListener(this);
    // Add
    contentPane.add(scrollPane1);Case 1:
    I load an image file into a BufferedImage. After the file is loaded I set the size if the Canvas to the size of the BufferedImage, and draw this on m_MapCanvas. The m_Canvas still remains the same size in scrollPane1.
    I set the size like this:
    m_MapCanvas.setSize(l_iWidth, l_iHeight);Case 2:
    I cant read the mouse position when the mouse is above the scrollPane
    I get the mouse envent like this:
    public void mouseMoved(MouseEvent e)
        mouseXpos = e.getX();
        mouseYpos = e.getY();
    }

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.net.*;
    import javax.imageio.ImageIO;
    public class ScrollPaneTest
        ScrollableCanvas scrollableCanvas;
        public ScrollPaneTest()
            scrollableCanvas = new ScrollableCanvas(getImages());
            ScrollPane scrollPane = new ScrollPane();
            scrollPane.add(scrollableCanvas);
            Frame f = new Frame();
            f.addWindowListener(new WindowAdapter()
                public void windowClosing(WindowEvent e)
                    System.exit(0);
            f.add(getImageController(), "North");
            f.add(scrollPane);
            f.add(getSizeController(), "South");
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
        private BufferedImage[] getImages()
            String[] fileNames = {
                "barnowl.jpg", "timberwolf.jpg", "owls.jpg", "coyote.jpg"
            BufferedImage[] images = new BufferedImage[fileNames.length];
            for(int j = 0; j < images.length; j++)
                try
                    URL url = getClass().getResource("images/" + fileNames[j]);
                    images[j] = ImageIO.read(url);
                catch(MalformedURLException mue)
                    System.err.println("url" + mue.getMessage());
                catch(IOException ioe)
                    System.err.println("read: " + ioe.getMessage());
            return images;
        private Panel getImageController()
            Button next = new Button("next image");
            next.addActionListener(new ActionListener()
                public void actionPerformed(ActionEvent e)
                    scrollableCanvas.moveAhead();
            Panel panel = new Panel();
            panel.add(next);
            return panel;
        private Panel getSizeController()
            final Button
                less = new Button("smaller canvas"),
                more = new Button("bigger canvas");
            ActionListener l = new ActionListener()
                int direction;
                public void actionPerformed(ActionEvent e)
                    Button button = (Button)e.getSource();
                    if(button == less)
                        direction = -1;
                    if(button == more)
                        direction = 1;
                    scrollableCanvas.changeSize(direction);
            less.addActionListener(l);
            more.addActionListener(l);
            Panel panel = new Panel();
            panel.add(less);
            panel.add(more);
            return panel;
        public static void main(String[] args)
            new ScrollPaneTest();
    class ScrollableCanvas extends Canvas
        BufferedImage[] images;
        int index;
        Dimension size;
        public ScrollableCanvas(BufferedImage[] images)
            this.images = images;
            index = 0;
            size = new Dimension(images[index].getWidth(), images[index].getHeight());
        public void paint(Graphics g)
            super.paint(g);
            int w = getWidth();
            int h = getHeight();
            int imageWidth = images[index].getWidth();
            int imageHeight = images[index].getHeight();
            int x = (w - imageWidth)/2;
            int y = (h - imageHeight)/2;
            g.drawImage(images[index], x, y, this);
        public Dimension getPreferredSize()
            return size;
        public void moveAhead()
            index = (index + 1) % images.length;
            size.width  = images[index].getWidth();
            size.height = images[index].getHeight();
            invalidate();             // mark this (Canvas) invalid
            getParent().validate();   // ask scrollPane to validate its child
            repaint();
        public void changeSize(int direction)
            size.width  = size.width  + (int)(direction * 0.1 * size.width);
            size.height = size.height + (int)(direction * 0.1 * size.height);
            invalidate();
            getParent().validate();
    }

  • How do I create an infinite drawing canvas in a ScrollPane?

    I wanted to figure this out on my own, but it is time to ask for help. I've tried too many different things. The closest I've come to the behaviour I want is with this code:
    final BorderPane root = new BorderPane();
    final Pane canvasWrapper = new Pane();
    canvasWrapper.setPrefSize(800, 500);
    canvasWrapper.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    canvasWrapper.setStyle("-fx-background-color: lightgray; -fx-border-color: green; -fx-border-width: 2px;");
    final Group canvas = new Group();
    canvasWrapper.getChildren().add(canvas);
    final ScrollPane scroll = new ScrollPane();
    scroll.setContent(canvasWrapper);
    root.setCenter(scroll);
    // event code for adding circles and lines to the canvas
    I want the ScrollPane to be filled with the Pane, so it can catch events for drawing. When the stage is resized, the ScrollPane is resized too. This the result of the BorderPane. What I want is to expand the window and have canvasWrapper expand to fill the entire ScrollPane viewport. When the stage is made smaller the ScrollPane shrinks, but I want the canvasWrapper to retain its size. The idea is the drawing canvas can only grow. When it gets too large for the current stage/ScrollPane size, the scrollpane can be used to navigate around the canvas.
    I tried using
    scroll.setFitToHeight(true);
    scroll.setFitToWidth(true);
    but this causes the Pane to be made smaller when the viewport is made smaller.

    I figured it out!
    Use
    scroll.setFitToHeight(true);
    scroll.setFitToWidth(true);
    to resize the Pane as the view port changes.
    Save the canvas' size as the Pane's size.
    canvas.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
                @Override
                public void changed(ObservableValue<? extends Bounds> ov, Bounds t, Bounds t1) {
                    canvasWrapper.setMinSize(t1.getMaxX(), t1.getMaxY());
    This forces the Pane to always be as large as the group is.
    Missed a piece of code - jrguenther

  • Flicker Problems with a dynamic Canvas and scrollpane

    Hello all,
    I'm having some trouble with flickering in a dynamically sizing canvas. Basically I have a new component similar to a text area implemented as a canvas. I put this canvas into a scrollpane and it is updated when a new message comes in. problem occurs both when a new msg comes in and when the scrollbar is used. I get heavy flickering in the component area and no where else. I've tried double buffering, I've looked through some of the old topic threads here and tried a few suggestions but it still occurs. I traced the paint/update calls with printlns into the console and found that only the paint gets called and not the update. I'm thinking that the changing height of the canvas is automatically calling the paint method directly. Any and all help (that works) will be rewarded with duke dollars. I really need help on this one. Below is a cut away of the code:
    CANVAS COMPONENT
    public class IconBox extends Canvas {
    //other methods to handle text processing
    public void append(String text)
    //places text into a vector and calls repaint to add it to
    //the canvas and updates the height of the canvas
    public void update (Graphics g)
    paint(g);
    public void paint(Graphics g)
    // I basically refresh the canvas with new text updates
    // here with g,drawtexts and add a few images with
    // drawimage
    APPLET
    public class ConfDraw extends Applet implements ComponentListener
    newTextarea lC;
    ScrollPane appletScroller
    public void init()
    lC = new IconBox(427);
    lC.addComponentListener(this);
    appletScroller = new ScrollPane(1);
    appletScroller.add(lC,0);
    appletScroller.setSize( 445, 380 );
    public void componentResized(ComponentEvent e) {
    appletScroller.doLayout();
    public void componentHidden(ComponentEvent e) {
    public void componentMoved(ComponentEvent e) {
    public void componentShown(ComponentEvent e) {
    // other methods that send text to IC
    public void update(Graphics g)
    //tried with and without this over ride at this level
    paint(g);
    }

    Create offscreen image & graphics
    eg.
    Image offscreenImg = createImage(w, this.size().height);
    Graphics offscreenG = offscreenImg.getGraphics();paint all ur contents on off screen grpahics.
    eg.
    offscreenG.drawString("Hello", 10, 10);finally paint the off-screen image to the Graphics
    g.drawImage(offscreenImg,0,0,this);This will avoid flickering as whole of the image is replaced at once. Also override update.

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

  • Problem with ScrollPane and JFrame Size

    Hi,
    The code is workin but after change the size of frame it works CORRECTLY.Please help me why this frame is small an scrollpane doesn't show at the beginning.
    Here is the code:
    import java.awt.*;
    public class canvasExp extends Canvas
         private static final long serialVersionUID = 1L;
         ImageLoader map=new ImageLoader();
        Image img = map.GetImg();
        int h, w;               // the height and width of this canvas
         public void update(Graphics g)
            paint(g);
        public void paint(Graphics g)
                if(img != null)
                     h = getSize().height;
                     System.out.println("h:"+h);
                      w = getSize().width;
                      System.out.println("w:"+w);
                      g.drawRect(0,0, w-1, h-1);     // Draw border
                  //  System.out.println("Size= "+this.getSize());
                     g.drawImage(img, 0,0,this.getWidth(),this.getHeight(), this);
                    int width = img.getWidth(this);
                    //System.out.println("W: "+width);
                    int height = img.getHeight(this);
                    //System.out.println("H: "+height);
                    if(width != -1 && width != getWidth())
                        setSize(width, getHeight());
                    if(height != -1 && height != getHeight())
                        setSize(getWidth(), height);
    }I create frame here...
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.JFrame;
    public class frame extends JFrame implements MouseMotionListener,MouseListener
         private static final long serialVersionUID = 1L;
        private ScrollPane scrollPane;
        private int dragStartX;
        private int dragStartY;
        private int lastX;
        private int lastY;
        int cordX;
        int cordY;
        canvasExp canvas;
        public frame()
            super("test");
            canvas = new canvasExp();
            canvas.addMouseListener(this);
            canvas.addMouseMotionListener(this);
            scrollPane = new ScrollPane();
            scrollPane.setEnabled(true);
            scrollPane.add(canvas);
            add(scrollPane);
            setSize(300,300);
            pack();
            setVisible(true);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        public void mousePressed(MouseEvent e)
            dragStartX = e.getX();
            dragStartY = e.getY();
            lastX = getX();
            lastY = getY();
        public void mouseReleased(MouseEvent mouseevent)
        public void mouseClicked(MouseEvent e)
            cordX = e.getX();
            cordY = e.getY();
            System.out.println((new StringBuilder()).append(cordX).append(",").append(cordY).toString());
        public void mouseEntered(MouseEvent mouseevent)
        public void mouseExited(MouseEvent mouseevent)
        public void mouseMoved(MouseEvent mouseevent)
        public void mouseDragged(MouseEvent e)
            if(e.getX() != lastX || e.getY() != lastY)
                Point p = scrollPane.getScrollPosition();
                p.translate(dragStartX - e.getX(), dragStartY - e.getY());
                scrollPane.setScrollPosition(p);
    }...and call here
    public class main {
         public main(){}
         public static void main (String args[])
             frame f = new frame();
    }There is something I couldn't see here.By the way ImageLoader is workin I get the image.
    Thank you for your help,please answer me....

    I'm not going to even attempt to resolve the problem posted. There are other problems with your code that should take priority.
    -- class names by convention start with a capital letter.
    -- don't use the name of a common class from the standard API for your custom class, not even with a difference of case. It'll come back to bite you.
    -- don't mix awt and Swing components in the same GUI. Change your class that extends Canvas to extend JPanel instead, and override paintComponent(...) instead of paint(...).
    -- launch your GUI on the EDT by wrapping it in a SwingUtilities.invokeLater or EventQueue.invokeLater.
    -- calling setSize(...) followed by pack() is meaningless. Use one or the other.
    -- That's not the correct way to display a component in a scroll pane.
    Ah, well, and the problem is that when you call pack(), it retrieves the preferredSize of the components in the JFrame, and you haven't set a preferredSize for the scroll pane.
    Please, for your own good, take a break from whatever it is you're working on and go through The Java&#8482; Tutorials: [Creating a GUI with JFC/Swing|http://java.sun.com/docs/books/tutorial/uiswing/TOC.html]
    db

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

  • Event handling in scrollpane and graphics programming concept

    I am still unclear about what to do to refresh a canvas inside a scrollpane?
    what should i do with "repaint()" method of scrollpane??
    clearly i have to update the drawing on the graphics g of the canvas, according to the viewport of the scrollpane so that a min. area is painted only.
    will the "repaint()" method of canvas automatically get called when scrollbar is scrolled?? i tested but seems not.
    do i have to consume adjustmentevent?? seems it's not a low level event
    i saw in the console that the "update()" of the canvas sometimes get called twice when i scroll the scrollbar.
    the problem i am having is : i got different effect when i clicked on different part of the scrollbar
    clicked on the "bubble" will scroll the canvas, but once stopped the canvas that becomes visible(blank be4) is not updated
    only clicking on the area next to the "bubble" will lead to a "great leap" and the screen get updated
    i dont know how to override the adjustmentvaluechanged() actually

    i clearrect() and drawline(), filloval() in the update() of canvas and call update() inside the paint() of the canvas, i dont know if i should make it this way
    should i call repaint() of the scrollpane or repaint() of the canvas inside the adjustmentvaluechanged() of the scrollpane??

  • How to move the canvas in the screen

    Hi,
    I am a j2ME game developer. I wanna create a canvas which contains something that can't be displayed all at a time. the user has to scroll across to view the canvas. I am not aware of the issues of this kind. Help me out in this regard.
    Cheers
    joe

    You could add a scrollPane to the component holding the image however, as you may or may not know, a scrollPane can only be added to Container type components so you can't add a scrollPane to a Canvas. You could add it to its parent Frame however.

  • ScrollPane zoom in/out

    Hello, this is my first post.
    I'd like to add zoom in/out function to my ScrollPane, and make shortcut (CTRL+MOUSE SCROLL UP/DOWN) for it. ( like Inkscape )
    I made the following code ( Canvas ) to achieve this, but have some problems.
    *1. How can I prevent ScrollBar's thumb to move when pressing CTRL?*
    When ScrollBar is visible and ScrollBar's thumb (or scroller, knob) has room to move, CTRL+MOUSE SCROLL UP/DOWN doesn't work because the thumb moves instead of zooming in/out.
    When the thumb moves up/down to bar's end, then zoom in/out finally works fine.
    *2. ScrollEvent handler is sometimes not called in ScrollPane*
    When ScrollBarPolicy is not ScrollBarPolicy.ALWAYS and Scrollbar is not visible, SOMETIMES CTRL+SCROLL UP/DOWN operation dosen't work.
    (ScrollEvent handler is not called. For other panes, ScrollEvent works fine. Please check MouseScrollEventTest below)
    Thank you in advance.
    Canvas
    public class Canvas extends Application {
         DoubleProperty zoom = new SimpleDoubleProperty(1.0);
         final double MAX_ZOOM = 3.0;
         final double MIN_ZOOM = 0.1;
         @Override
         public void start(Stage stage) throws Exception {
              Rectangle rectangle = RectangleBuilder.create()
                   .width(1000).height(1000)
                   .fill( LinearGradientBuilder.create()
                        .stops(new Stop(0, Color.BLUE), new Stop(1, Color.RED))
                        .build()
                   ).build();
              ScrollPane scrollPane = ScrollPaneBuilder.create()
                   .content(
                        GroupBuilder.create()
                             .children(rectangle)
                             .build())
    //               .hbarPolicy(ScrollBarPolicy.ALWAYS)
    //               .vbarPolicy(ScrollBarPolicy.ALWAYS)
                   .build();
              rectangle.scaleXProperty().bind(zoom);
              rectangle.scaleYProperty().bind(zoom);
              scrollPane.setOnScroll(new EventHandler<ScrollEvent>(){
                   public void handle(ScrollEvent event) {
                        if( !event.isControlDown() ) return ;
                        double zoomValue;
                        if ( event.getDeltaY() > 0 ) {
                             zoomValue = zoom.get() + 0.1;
                        } else {
                             zoomValue = zoom.get() - 0.1;
                        if( zoomValue > MAX_ZOOM || zoomValue < MIN_ZOOM ) return ;
                        zoom.set(zoomValue);
              Scene scene = SceneBuilder.create()
                        .width(500).height(500)
                        .root(scrollPane)
                        .build();
              stage.setScene(scene);
              stage.show();
         public static void main(String[] args) {
              launch(args);
    Mouse Scroll Event Test
    public class MouseScrollEventTest extends Application {
         BorderPane bPane;
         ScrollPane sPane;
         public void start(Stage stage) throws Exception {
              EventHandler<ScrollEvent> handler = new EventHandler<ScrollEvent>() {
                   public void handle(ScrollEvent event) {
                        System.out.println(event);
              bPane = new BorderPane();
              bPane.setPrefSize(100, 100);
              sPane = new ScrollPane();
              sPane.setPrefSize(100, 100);
    //          sPane.setContent( new Rectangle(50,50) );
    //             This works fine.
              bPane.setOnScroll(handler);
    //             Sometimes, this is not called.
              sPane.setOnScroll(handler);
              HBox root = new HBox();
              root.getChildren().addAll(bPane, sPane);
              Scene scene = new Scene(root);
    //          scene.setOnScroll(handler);
              stage.setScene(scene);
              stage.show();
         public static void main(String[] args) {
              launch(args);
    }--- My Environment
    Windows Vista
    JavaFX 2.0 SDK
    Edited by: 932474 on 2012/05/07 4:31
    Edited by: 932474 on 2012/05/07 4:47

    Thank you for the good example.
    But actually, I just give up using ScrollPane and created a ZoomCanvas which can zoom in/out and pan.
    The code is here.
    Any comments or improvement would be appreciated.
    ZoomCanvas
    public class ZoomCanvas extends StackPane {
         private ZoomController zoomController;
         private Group contentWrapper;
         private double translateXWhenMousePressed, translateYWhenMousePressed;
         private double xWhenMousePressed , yWhenMousePressed;
         private static class ZoomController {
              private int deltaCount = 0;
              private final double DEFAULT_ZOOM = 1.0;
              private boolean useAnimation = true;
              private DoubleProperty zoomMax   = new SimpleDoubleProperty(10.0);
              private DoubleProperty zoomMin   = new SimpleDoubleProperty(0.1);
              private DoubleProperty zoomDelta = new SimpleDoubleProperty(1.2);
              private DoubleProperty zoom      = new SimpleDoubleProperty( DEFAULT_ZOOM );
              public ZoomController() {
              public void zoomIn() {
                   double zoomValue = DEFAULT_ZOOM * Math.pow(zoomDelta.get(), deltaCount+1);
                   if( zoomValue > zoomMax.get() ) {
                        setZoom(zoomMax.get());
                        return;
                   deltaCount++;
                   setZoom( zoomValue );
              public void zoomOut() {
                   double zoomValue = DEFAULT_ZOOM * Math.pow(zoomDelta.get(), deltaCount-1);
                   if( zoomValue < zoomMin.get() ) {
                        setZoom(zoomMin.get());
                        return;
                   deltaCount--;
                   setZoom( zoomValue );
              public void setZoom( double zoomValue ) {
                   if( useAnimation ) {
                        Timeline zoomTimeline = new Timeline();
                        zoomTimeline.getKeyFrames().add(
                             new KeyFrame(Duration.millis(300), new KeyValue(zoom, zoomValue))
                        zoomTimeline.play();
                   } else {
                        zoom.set(zoomValue);
         public ZoomCanvas(Node content) {
              super();
              Rectangle clip = new Rectangle();
              clip.widthProperty().bind(widthProperty());
              clip.heightProperty().bind(heightProperty());
              // to adjust layoutBounds when drawingPane's scale changes
              contentWrapper = new Group(content);          
              StackPane.setAlignment(contentWrapper, Pos.CENTER);
              getChildren().add(contentWrapper);
              zoomController = new ZoomController();
              content.scaleXProperty().bind(zoomController.zoom);
              content.scaleYProperty().bind(zoomController.zoom);
              content.translateXProperty();
              hookEvents();
              setClip(clip);
         private void hookEvents() {
              setOnScroll(new EventHandler<ScrollEvent>() {
                   public void handle(ScrollEvent event) {
                        if( event.getDeltaY() > 0 ) {
                             zoomController.zoomIn();
                        } else {
                             zoomController.zoomOut();
              setOnMousePressed(new EventHandler<MouseEvent>(){
                   public void handle(MouseEvent event) {
                        if( !event.isMiddleButtonDown() ) return ;
                        translateXWhenMousePressed = contentWrapper.getTranslateX();
                        translateYWhenMousePressed = contentWrapper.getTranslateY();
                        xWhenMousePressed = event.getX();
                        yWhenMousePressed = event.getY();
                        setCursor(Cursor.MOVE);
                        event.consume();
              setOnMouseReleased(new EventHandler<MouseEvent>(){
                   public void handle(MouseEvent event) {
                        setCursor(Cursor.DEFAULT);
              setOnMouseDragged(new EventHandler<MouseEvent>(){
                   public void handle(MouseEvent event) {
                        if(!event.isMiddleButtonDown())
                             return;
                        contentWrapper.setTranslateX( translateXWhenMousePressed +  event.getX() - xWhenMousePressed );
                        contentWrapper.setTranslateY( translateYWhenMousePressed +  event.getY() - yWhenMousePressed );
                        event.consume();
    ZoomCanvasTest
    public class ZoomCanvasTest extends Application {
         public void start(Stage primaryStage) throws Exception {
              Rectangle rect = new Rectangle(0,0,100,100);
              rect.setStyle("-fx-fill: blue;");
              Circle circle = new Circle(100,100,50);
              circle.setStyle("-fx-fill: red;");
              Pane canvasContent = new Pane();
              canvasContent.setStyle(
                        "-fx-background-color: papayawhip;" +
                        "-fx-border-color: black;");
              canvasContent.getChildren().add(circle);
              canvasContent.getChildren().add(rect);
              ZoomCanvas canvas = new ZoomCanvas(canvasContent);
              canvas.setStyle(
                   "-fx-background-color: mistyrose;" +
                   "-fx-border-color: black;"
              ToolBar toolBar = new ToolBar();
              toolBar.setOrientation(Orientation.VERTICAL);
              toolBar.getItems().add( new Button("sample") );
              BorderPane root = new BorderPane();
              root.setCenter(canvas);
              root.setRight(toolBar);
    //          root.getChildren().addAll(canvas, toolBar);
              Scene scene = new Scene(root);
              primaryStage.setScene(scene);
              primaryStage.show();
         public static void main(String[] args) {
              launch(args);
    }Edited by: 932474 on 2012/05/08 10:17
    Edited by: 932474 on 2012/05/08 10:40
    Edited by: 932474 on 2012/05/08 10:56

  • Adding scrollbars to canvas!!

    hi everybody,
    a have a simple ??
    i'm working on a chat application. my message displaying area is a canvas.i have added scroll-bars to it using scroll-pane
    "sp = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);"
    now what i want is the scrollbars should adjust automatically to
    display the last message and also i should be able to adjust them
    manually so that i can view the previous messages.
    i have tried setScrollposition() it works well also but then i'm not
    able to adjust scrollbars manually.
    this interface is in AWT.
    please tell me a solution.its a bit urgent.
    thankx and regards
    asheet

    Because your canvas is growing.(I think)
    The new size of the canvas causes it to be layd out again. And laying out a component usually causes flickering (depending on the plattform). I guess the workaround would be to use a canvas just as big as the shown part of it. Add a scrollbar by its side (not a scrollpane) and use the scrollposition to choose what part of the text that should be painted. That way you can use doublebuffering, and avoid the problem completly. (No resizing of components means nothing is layd out again)
    Ragnvald Barth
    Software engineer

  • ScrollPane problem

    All,
    i am trying to create my own TextArea, as i need to output lines of text with different colors on each line (a TextArea can only have one color for the text?).
    i have created the following program but whenever i click on the scrollbar to scroll down all of the text disappears.
    Where am i going wrong? please help
    regards
    package scrollbar;
    import java.awt.*;
    import java.awt.event.*;
    import java.applet.*;
    public class ScrollBar extends Applet
      public Canvas canvas = new Canvas();
      public ScrollPane pane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
      public void init()
        this.setLayout(null);
        canvas.setBackground(Color.white);
        pane.add(canvas);
        pane.setSize(300, 200);
        pane.setLocation(10,10);
        this.add(pane);
      public void paint(Graphics g)
        System.out.println("paint");
        Graphics gr = canvas.getGraphics();
        int posX = 10;
        int posY = 10;
        for (int i = 0; i < 20; i++)
          gr.drawString("TEST FONT ", posX, posY);
          posY += 20;

    this is because u draw strings over the ScrollPane and not in it, and every time you scroll it, it calls the repaint method and paint over your strings.
    my suggestion is to put a label in the scrollpane and write your strings on the label or it could be easier to set html text in the label like this:l.setText("<html><body>....")good luck
    mamtz

  • ScrollPane Problem (please help!!!!)

    I've got a class PanneauImages (extends JPanel) and it contains (zone_photo) a canvas on which i draw images(several images ( a set of images) on one canvas, that's y i need a ScrollPane).
    In the application, we have a button to change the set of images, like to go from set 1 to set 2 etc...
    we may need the scroller to show for the first set for example, but not the second. so it's supposed to show for the 1st set, disapear for the 2nd and come back for set 3 for example.
    I have a method repaint in the canvas class....
    my problem is, that the scroller jsut doesn't move when i change the set of images. and the weird thing is that this happens only when I run the application on Windows. On LINUX i don't have any problems...
    here's the full code of the two classes...
    PS : the button that chages the set is contained in another class that contains the class PanneauImage...
    first, Panneau Images...
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import java.io.*;
    import javax.swing.*;
    import dbtables.*;
    * Classe : PanneauImages
    * Description : Cette classe represente un panneau contenant l'ensemble des images
    * elles meme contenues dans une zone
    * Societe : Medias France
    * @version 1.0
    class PanneauImages extends JPanel
         * La page resultat contenat cette page
         ResultPanel parent;
         * La zone contenant les images encadrees
         Imag zone_photo;
         * Dimensions
         int width, height;
         * La barre de defilement contenant les images
         ScrollPane sp;
         //===========================================================================================
         * Constructeur par defaut.
         * @param     res Le parent
         * @param     chain La dexieme partie de l'adresse
         * @return     Sans objet.
         public PanneauImages(ResultPanel res, int w, int h)
              parent = res;
              width = w;
              height = h;
              setLayout(new BorderLayout());
              sp = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
              zone_photo = new Imag(this, sp, width, height);     
              sp.add(zone_photo);
              Adjustable vadjust = sp.getVAdjustable();
              Adjustable hadjust = sp.getHAdjustable();
              add(sp, "Center");
         * redessiner les photos
         * @param     Sans objet.
         * @return     Sans
         public void redessiner()
              //zone_photo.changeHeight();
              zone_photo.effacer();
         zone_photo.repaint();
         * Trouver la meilleure taille pour le composant
         * @param     Sans objet.
         * @return     La taille optimale
         public Dimension getPreferredSize()
              return new Dimension(width, height);
         * Trouver la meilleure marge pour le composant
         * @param     Sans objet.
         * @return     La marge optimale
         public Insets getInsets()
              return new Insets(5,5,5,5);
    and Imag
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import java.io.*;
    import javax.swing.*;
    import dbtables.*;
    * Classe : Imag
    * Description : Cette classe represente plusieurs image dans des cadres
    * Societe : Medias France
    * @version 1.0
    class Imag extends Canvas
         * Le scrollPane contenant cette classe
         ScrollPane scroll;
         * La classe contenant ces images
         PanneauImages parent;
         * Variables
         int id,nb_images=0, indice=0, ancien_hauteur=0;
         int width, height;
         * Hauteur et largeur du cadre
         int hauteur, largeur;
         * tableau contenant les adresses des images
         java.awt.Image[] img;
         * les Coordonnees des images
         int x,y, xx, yy;
         * lee nombre d'images par ligne
         int nbImLigne;
         //===========================================================================================
         * Constructeur par defaut.
         * @param     par Le parent
         * @param     s Le scroller
         * @param     w la largeur du conteneur d'origine
         * @param     h La hauteur du conteneur d'origine
         * @return     Sans objet.
         public Imag(PanneauImages par,ScrollPane s, int w, int h)
              parent = par;
              width=w;
              height = h;
              indice=0;
              scroll = s;
              //le listener pour le zoom sur les images
              addMouseListener(new MouseAdapter()
                   public void mouseClicked(MouseEvent evt)
                   //Coordonnee x du click souris
                   int x;
                   //Coordonnee y du click souris
                   int y;
                   //Le numero de ligne ou l'on a clique
                   int resy;
                   //Le numero de colonne ou l'on a clique
                   int resx;
                   //Le numero de l'image selectionnee
                   int num_image;
                   //recuperer les coordonnee du click
                   y = evt.getY();
                   x = evt.getX();
                   //trouver la ligne et la colonne
                   resy = y / 210;
                   resx = x / 182;
                   //verifier si le click est effectivement sur une image
                   int i1 = 10+210*resy;
                   int i2 = 172+210*resy;
                   if((i1 < y) && (i2 > y))
                        //rien faire
                   else
                        resy = -1;
                   int i3 = 10+182*resx;
                   int i4 = 172+182*resx;
                   if((i3 < x ) && (i4 > x ))
                        //rien faire
                   else
                        resx = -1;
                   //si click bon
                   if((resx > -1) && (resy > -1))
                        num_image = (resy *nbImLigne)+resx;
                        if (num_image < nb_images)
                             //creation et ouverture d'une fenetre image
                             Frame f = new Frame("Zoom");
                             ImageZoom imgzoom = new ImageZoom(f, img[num_image]);
         * Dessiner les images
         * @param     r Le contexte graphique utilise pour le dessin.
         * @return     Sans objet.
         public void paint(Graphics g)
              //pollen courant
              int nbre = parent.parent.numPollen;
              //nombre d'images pour ce pollen
              nb_images = ((ReqPropPollen)parent.parent.vectResult.elementAt(nbre)).images.size();
              if (nb_images > 0)
              img = new java.awt.Image[nb_images];
              Photo p;
              //recuperer les images a dessiner
              for(int i = 0; i < nb_images; i++)
                   String s = ((dbtables.Image)((ReqPropPollen)parent.parent.vectResult.elementAt(nbre)).images.elementAt(i)).getChem_ima();
                   p = new Photo(this,s);
                   img[i] = p.img;
              int j;
              x=10;
              y=10;
              j=0;
              xx=0;
              yy=0;
              //variables utilisees pour distribuer les images dans la fenetre
              int xmax = parent.parent.parent.parent.getSize().width-70;
              //nbre d'images max par ligne
              nbImLigne = xmax/182;
              //cas ou on ne peut afficher qu'une colone d'images
              if (nbImLigne==0)
                   j = -1;
              //pour toutes les images, les dessiner
              for (int i=0; i<nb_images; i++)
                   largeur = img.getWidth(this);
                   hauteur = img[i].getHeight(this);
                   taille();
                   //tant qu'on peut dessiner une autre image sur la meme ligne...
                   if (j<nbImLigne)
                        g.drawRect(x-1,y-1,162,162); // trace un rectangle noir autour de la photo
                        g.drawImage(img[i],x+xx,y+yy,largeur, hauteur,this); // affiche la photo
                        x=x+182; //*(j+1);
                        j++;
                   else
                        j = 0;
                        x = 10;
                        y = y+210;
                        g.drawRect(x-1,y-1,162,162); // trace un rectangle noir autour de la photo
                        g.drawImage(img[i],x+xx,y+yy,largeur, hauteur,this); // affiche la photo
                        j++;
                        x=x+182;
              width = 0; //permet de ne pas afficher une barre horizontale
              int i1;
              int i2;
              if (nbImLigne==0)
                   i1 = nb_images;
                   i2 = nb_images - i1;
              else
                   i1 = nb_images/nbImLigne;
                   i2 = nb_images - (i1*nbImLigne);
              int i3;
              if(i2 > 0)
                   i3 = i1+1;
              else
                   i3 = i1;
              height = 210*i3;
              if (nbImLigne==0)
                   width = 182;
              else
                   width = 182*nbImLigne;
              //modifier la taille du Canvas
              setBounds(getX(), getY(), width, height);
              System.out.println("la largeur du canvas est de "+ getWidth());
              System.out.println("la hauteur du canvas est de "+ getHeight());
              else
                   System.out.println("pas d'images pour ce pollen");
         * Calculer les variables pour le placement des images
         * @param     Sans objet.
         * @return     Sans objet.
         public void taille()
              int haut_tmp = hauteur*160/largeur;
              if (haut_tmp >= 160)
                   largeur = largeur*160/hauteur;
                   hauteur=160;
                   xx = (160-largeur)/2;
                   yy = 0;
              else
                   largeur = 160;
                   hauteur = haut_tmp;
                   yy = (160-hauteur)/2;
                   xx = 0;
         * Mise a jour du Canvas sans effacer le fond a chaque fois
         * @param     p Le contexte graphique
         * @return     Sans objet.
         public void update(Graphics g)
         paint(g);
         * Effacer le fond du Canvas
         * @param     p Le contexte graphique
         * @return     Sans objet.
    public void effacer()
         Graphics g = getGraphics();
         g.clearRect(getX(), getY(), getWidth(), height);
         g.dispose();
         * Trouver la taille minimale pour le composant
         * @param     Sans objet.
         * @return     La taille minimale
         public Dimension getMinimumSize()
              return new Dimension(width, height);
         * Trouver la meilleure taille pour le composant
         * @param     Sans objet.
         * @return     La taille optimale
         public Dimension getPreferredSize()
              return new Dimension(width, height);
         * Trouver la meilleure marge pour le composant
         * @param     Sans objet.
         * @return     La marge
         public Insets getInsets()
              return new Insets(0,0,0,0);

    OMG! it's worse! now I have the scroller (both horizontal and vertical!)all the time!!! It's as if it doesn't even see the JComponent!
    I tried changing the method paint to paintComponent but it doesn't change anything :o(
    anyway, this is really weird, i don't understant why it's ok with LINUX and not with windows :o(
    thanx for trying anyway :o) :o) :o)

  • ScrollPane Flow Layout

    Hi Guys,
    I am at my wits end as to how I can solve this. I really can't find a solution, I hope you can help.
    I have a gui layout thus:
    JTabbedPane -> JScrollPane -> JPanel -> JPanel (instead of awt.canvas)
    I have multiple java2d 'graphs' that I wish to layout on this scrollpane left to right which then wrap. If the screen is full, vertical scrollbars are triggered. So I think flow layout is the closest to this as I really must maintain the original component size. Grid layout etc resize the graphs making it look wrong.
    The problem is that with flow layout, it scrolls infinitely horizontally. The only way I can get to to stop scrolling harizontally is by calling setPreferedSize(). When I do this however it seems to disable the scroll bars.
    I have tried all combinations of layout managers to try and give me the same effect - to no avail. I have tried setting the scrollpane display policies and again this has no effect.
    So I suppose I can see two possibilites:
    1- find some way of getting the scrollpane to wrap without setPreferredSize()
    2- find a way of getting the scroll bars working, with setPreferredSize()
    My code, looks like this:
    scrollPaneContents_ = new JPanel();
    scrollPaneContents_.setPreferredSize(new Dimension(scrollPane_.getWidth(),scrollPane_.getHeight()));
    scrollPaneContents_.setLayout(new FlowLayout(FlowLayout.CENTER));
    scrollPane_ = new JScrollPane(scrollPaneContents_);
    //scrollPane_ = new JScrollPane(scrollPaneContents_/*,
    //scrollPane_.VERTICAL_SCROLLBAR_AS_NEEDED,scrollPane_.HORIZONTAL_SCROLLBAR_NEVER*/);
    //layout.setConstraints(scrollPane_, layoutConstraints);
    // I want it to scroll to the width less and continue downwards forever
    scrollPaneContents_.setVisible(true);
    tabView_.add("Tab Name",scrollPane_);
    tabView_.refresh();
    view_.refresh();
    scrollPaneContents_.add(graphView_);
    As you can see I have commented some out to try every combination :)
    Any suggestions?
    TIA

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import javax.swing.*;
    public class GridBagAddition
        public static void main(String[] args)
            DisplayPanel displayPanel = new DisplayPanel();
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().add(new JScrollPane(displayPanel));
            f.getContentPane().add(displayPanel.getButtonPanel(), "South");
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
    class DisplayPanel extends JPanel
        JButton addButton;
        GridBagConstraints gbc;
        int[] gridwidths = {
            GridBagConstraints.RELATIVE, GridBagConstraints.REMAINDER
        int graphCount = 0;
        public DisplayPanel()
            addButton = new JButton("add graph");
            setLayout(new GridBagLayout());
            gbc = new GridBagConstraints();
            gbc.weightx = 1.0;
            gbc.weighty = 1.0;
            gbc.insets = new Insets(10,5,10,5);
        public JPanel getButtonPanel()
            addButton.addActionListener(new ActionListener()
                public void actionPerformed(ActionEvent e)
                    gbc.gridwidth = gridwidths[graphCount++ % gridwidths.length];
                    add(new GraphPanel(), gbc);
                    revalidate();
            JPanel panel = new JPanel();
            panel.add(addButton);
            return panel;
    class GraphPanel extends JPanel
        final int PAD = 20;
        public GraphPanel()
            setPreferredSize(new Dimension(200,175));
        public void paintComponent(Graphics g)
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            int width = getWidth();
            int height = getHeight();
            int x0 = PAD;
            int x1 = width - PAD;
            int y0 = height - PAD;
            int y1 = PAD;
            g2.draw(new Line2D.Double(x0, y0, x0, y1));
            g2.draw(new Line2D.Double(x0, y0, x1, y0));
           

Maybe you are looking for

  • One account with several user devices

    My wife and I both have iPhones. I recently discovered the icloud features, but unfortunately don't have much use for it. My wife has not used the feature yet either, but now I got her an iPad for Christmas and I feel that she will find it useful for

  • ITunes deletes all the music off of my iPod. Why?

    iTunes is being a huge piece of crap. I want it to sync my songs onto my iPod Touch 4G. Instead, it decides to delete all 5500+ songs off of my iPod... twice. Once, I managed to put the songs back on, this takes over an hour and a half, then it delet

  • Regarding scheduling of BO reports.

    Hello BO expets, I am new to BOXI and have a very basic Q to ask. We are currently using Infoburst for scheduling our BO reports. which is not a BO product and is a third party tool. What i want to know is does BO has it own built-in scheduler ? and

  • Error in  standard  PO approval

    Hi everyone,    While doing the PO  release strategy in workflow , i am facing an error i.e,' Resolution of rule AC20000027 for task TS20000166: no agent found' .  can anyone help me fixing  this issue. Thanks, Archana.

  • Deauthorize? Keeping iTunes active on more than one computer?

    I'm sure the answer to this is somewhere here, my apologies, have only so much time to peruse the KB and am having no luck. I've been working overtime$. I have a new iPod and a new MacBookPro. I want to move all my songs from my old desktop G4 to my