Java scrolling with a Viewport

I'm trying to get the code below to work. Basically, I want to add a bunch of JLabelOverlayedText objects to a JPanel that I can scroll through.

The JLabelOverlayedText is just a JLabel that has an image background with the text overlayed on top of it.

The CardsInHandPanel object is a JPanel that has a background image, two JButtons to scroll with, and the JPanel with a set viewport.

The code is not working as is, and I'm not exactly sure why, please submit a complete working answer, thanks...

/************************************************************************************/
import javax.swing.*;

public class NoScrollBarsExample{
      public static void main(String[] args){
            JFrame f = new JFrame();
            f.setSize(300,300);
            f.getContentPane().add(new CardsInHandPanel());
            f.show();
      }
}
/************************************************************************************/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import orb.gaming.interfaces.JLabelOverlayedText;
import orb.gaming.utility.GraphicUtilities;

public class CardsInHandPanel extends JPanel implements ActionListener{
      private Image image; // background image
      private JViewport vp = new JViewport();
      JPanel scrollpanel = new JPanel();
      private JButton up;
      private JButton down;
      public CardsInHandPanel()
      {
            image = GraphicUtilities.loadImage("C://card_window_t.png");
            setMinimumSize(new Dimension(image.getWidth(null) + 25,image.getHeight(null)));
            setOpaque(false);
            
            // create scroll buttons
            up = createButton("C://up_arrow.png", "Scroll Up");
            up.setBounds(image.getWidth(null) + 25 - up.getIcon().getIconWidth(), 30, 20,20);
            down = createButton("C://down_arrow.png","Scroll Down");
            down.setBounds(image.getWidth(null) + 25 - up.getIcon().getIconWidth(), image.getHeight(null) - 20 - 25, 20,20);
            
            scrollpanel.setLayout(null);
            scrollpanel.setOpaque(false);
            vp.setOpaque(false);
            setLayout(null);
            int y = -36; // offset by six for the first element
            for (int i = 0; i < 7; i++)
            {
                  JLabelOverlayedText newCard = new JLabelOverlayedText(new ImageIcon("C://blank_button.png"), "Card Name" + i, 12);
                  newCard.setBounds(2,y+=36,165,36);
                  scrollpanel.add(newCard);
            }
            vp.setView(scrollpanel);
            vp.setBounds(2,30,165,(36 * 5));
            add(vp);
            add(up);
            add(down);
      }

      /**
       * @return
       */
      public Image getImage() {
            return image;
      }

      /**
       * @param image
       */
      public void setImage(Image image) {
            this.image = image;
      }
      
      public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.drawImage(image,0,0,null);      
      }
      
      /**
                  Creates a Swing JButton. The image used for the button is
                  located at "../images/menu/" + name + ".png". The image is
                  modified to create a "default" look (translucent) and a
                  "pressed" look (moved down and to the right).
                  <p>The button doesn't use Swing's look-and-feel and
                  instead just uses the image.
            */
            public JButton createButton(String filename, String toolTip) {

                  ImageIcon image = new ImageIcon(filename);
                  JButton button = new JButton();
                  ImageIcon iconRollover = new ImageIcon(filename);
                  button.addActionListener(this);
                  
                  button.setOpaque(false);
                  button.setRolloverEnabled(true);
                  button.setBorder(null);
                  button.setIgnoreRepaint(true);
                  button.setFocusable(false);
                  button.setToolTipText(toolTip);
                  button.setBorder(null);
                  button.setContentAreaFilled(false);
                  Cursor cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
                  button.setCursor(cursor);
                  button.setIcon(image);

                  return button;
            }
            
      public void actionPerformed(ActionEvent e)
      {
                  Object source = e.getSource();
                  Point p = vp.getViewPosition();
                  if (source == down)
                        p.translate(0,10);
                  else
                        if ((p.x != 0) && (p.y != 0)) // don't scroll higher than what is visible
                              p.translate(0,-36);
                  
             JButton b = (JButton)source;      
                  vp.setViewPosition(p);
      }
}
/**********************************************************************************/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class JLabelOverlayedText extends JLabel implements MouseListener{
      private String myText;
      private boolean transparentImage = true;
      
      public JLabelOverlayedText(ImageIcon i){
            super(i);
            addMouseListener(this);
      }
      
      public JLabelOverlayedText(ImageIcon i, String text)
      {
            this(i);
            myText = text;
      }
      
      public JLabelOverlayedText(ImageIcon i, String text, int fontSize)
      {
            this(i, text);
            setFont(new Font("Serif", 1, fontSize));
      }
      
      public void paintComponent(Graphics g)
      {
            super.paintComponent(g);
            ImageIcon imageicon = (ImageIcon)this.getIcon();
            Image image = imageicon.getImage();
            
            FontMetrics fm = this.getFontMetrics(getFont());
            Point p = new Point();
            p.setLocation((getWidth() - fm.getStringBounds(myText, g).getWidth())/2 , (getHeight()/2)+5);
            g.setFont(getFont());
            g.setColor(Color.WHITE);
                        
            Graphics2D g2 = (Graphics2D)g;
            if (image != null)
            {
                  Composite alpha;
                  if (transparentImage)
                        alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
                  else
                        alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
                  g2.setComposite(alpha);
                  g2.drawImage(image, 0, 0, null);
                  g2.drawString(myText, p.x, p.y);
            }
      }
      
      public void mouseClicked(MouseEvent e) {}
      public void mouseEntered(MouseEvent e) {
            transparentImage = false;
      }
      public void mouseExited(MouseEvent e)      {
                  transparentImage = true;
            }
            public void mousePressed(MouseEvent e)      {}
            public void mouseReleased(MouseEvent e)      {}
      
            public void actionPerformed(ActionEvent e) {}
      
            public void mouseDragged(MouseEvent e) {}
            public void mouseMoved(MouseEvent e) {
                  synchronized(this) {
                  if (contains(e.getPoint()))
                        transparentImage = true;
                  else
                        transparentImage = false;
                  }
            }

}




LVL 1
darkpegasus5Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
expertmbConnect With a Mentor Commented:
i had an image of size 32 x 32, so i used for the size calculation. you can change 36 for your size calculation.
this soln won't  resize, earlier it had the GridLayout. now it is having null layout.

/*
 * Created on Oct 19, 2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author burli
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
/************************************************************************************/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/************************************************************************************/


class CardsInHandPanel extends JPanel implements ActionListener{
    private Image image; // background image
    private JViewport vp = new JViewport();
    JPanel scrollpanel = new JPanel();
    JScrollPane scrollpane = new JScrollPane(scrollpanel);
    private JButton up;
    private JButton down;
    public CardsInHandPanel()
    {
         image =  Toolkit.getDefaultToolkit().getImage("d:/rnd/group-logo.gif");
//GraphicUtilities.loadImage("C://card_window_t.png");
         setMinimumSize(new Dimension(image.getWidth(null) + 25,image.getHeight(null)));
         setOpaque(false);

         // create scroll buttons
         up = new JButton("Scroll Up", new ImageIcon("D:\\RND\\up.gif"));//createButton("D:\\up.gif", "Scroll Up");
         up.addActionListener(this);
         //up.setBounds(image.getWidth(null) + 25 - up.getIcon().getIconWidth(), 30, 20,20);
         up.setBounds(2, 200,45, 20);
         down = new JButton("Scroll Down", new ImageIcon("D:\\RND\\downtriangle.gif"));//createButton("d:\\downtriangle.gif","Scroll Down");
         down.addActionListener(this);
         //down.setBounds(image.getWidth(null) + 25 - up.getIcon().getIconWidth(), image.getHeight(null) - 20 - 25, 20,20);
         down.setBounds(2, 240,45, 20);
         scrollpanel.setLayout(new BoxLayout(scrollpanel, BoxLayout.Y_AXIS) );
         scrollpanel.setOpaque(false);
         vp.setOpaque(false);
         //setLayout(new GridLayout(3,1));
         setLayout(null);
         int y = -32; // offset by six for the first element
         for (int i = 0; i < 10; i++)
         {
              JLabelOverlayedText newCard = new JLabelOverlayedText(new ImageIcon("D:\\rnd\\ant_logo_small.gif"), "Card Name" + i, 12);
              newCard.setBounds(2,y+=32,165,32);
              scrollpanel.add(newCard);
         }
         vp.setView(scrollpanel);
         vp.setBounds(2,30,165,(32 * 5));
         add(vp);
         add(up);
         add(down);
    }

     /**
      * @return
      */
     public Image getImage() {
          return image;
     }

     /**
      * @param image
      */
     public void setImage(Image image) {
          this.image = image;
     }

     public void paintComponent(Graphics g){
          super.paintComponent(g);
          g.drawImage(image,0,0,null);
     }

     /**
               Creates a Swing JButton. The image used for the button is
               located at "../images/menu/" + name + ".png". The image is
               modified to create a "default" look (translucent) and a
               "pressed" look (moved down and to the right).
               <p>The button doesn't use Swing's look-and-feel and
               instead just uses the image.
          */
          public JButton createButton(String filename, String toolTip) {

               ImageIcon image = new ImageIcon(filename);
               JButton button = new JButton();
               ImageIcon iconRollover = new ImageIcon(filename);
               button.addActionListener(this);

               button.setOpaque(false);
               button.setRolloverEnabled(true);
               button.setBorder(null);
               button.setIgnoreRepaint(true);
               button.setFocusable(false);
               button.setToolTipText(toolTip);
               button.setBorder(null);
               button.setContentAreaFilled(false);
               Cursor cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
               button.setCursor(cursor);
               button.setIcon(image);

               return button;
          }

     public void actionPerformed(ActionEvent e)
     {
               Object source = e.getSource();
               Point p = vp.getViewPosition();
                  System.out.println("x: " + p.x);
                  System.out.println("y: " + p.y);

               if (source == down)
                    p.translate(0,32);
               else if(source == up){
                           if(p.y > 0)
                                 p.translate(0,-32);
                        }
               else if (p.y > 0){ // don't scroll higher than what is visible
                    p.translate(0,-32);
               }

           JButton b = (JButton)source;
               vp.setViewPosition(p);
     }
     public static void main(String[] args){
        JFrame f = new JFrame();
        f.setSize(300,300);
        f.getContentPane().add(new CardsInHandPanel());
        f.setVisible(true);
   }
}
/**********************************************************************************/


class JLabelOverlayedText extends JLabel implements MouseListener{
     private String myText;
     private boolean transparentImage = true;

     public JLabelOverlayedText(ImageIcon i){
          super(i);
          addMouseListener(this);
     }

     public JLabelOverlayedText(ImageIcon i, String text)
     {
          this(i);
          myText = text;
     }

     public JLabelOverlayedText(ImageIcon i, String text, int fontSize)
     {
          this(i, text);
          setFont(new Font("Serif", 1, fontSize));
     }

     public void paintComponent(Graphics g)
     {
          super.paintComponent(g);
          ImageIcon imageicon = (ImageIcon)this.getIcon();
          Image image = imageicon.getImage();

          FontMetrics fm = this.getFontMetrics(getFont());
          Point p = new Point();
          p.setLocation((getWidth() - fm.getStringBounds(myText, g).getWidth())/2 , (getHeight()/2)+5);
          g.setFont(getFont());
          g.setColor(Color.WHITE);

          Graphics2D g2 = (Graphics2D)g;
          if (image != null)
          {
               Composite alpha;
               if (transparentImage)
                    alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
               else
                    alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
               g2.setComposite(alpha);
               g2.drawImage(image, 0, 0, null);
               g2.drawString(myText, p.x, p.y);
          }
     }

     public void mouseClicked(MouseEvent e) {}
     public void mouseEntered(MouseEvent e) {
          transparentImage = false;
     }
     public void mouseExited(MouseEvent e)     {
               transparentImage = true;
          }
          public void mousePressed(MouseEvent e)     {}
          public void mouseReleased(MouseEvent e)     {}

          public void actionPerformed(ActionEvent e) {}

          public void mouseDragged(MouseEvent e) {}
          public void mouseMoved(MouseEvent e) {
               synchronized(this) {
               if (contains(e.getPoint()))
                    transparentImage = true;
               else
                    transparentImage = false;
               }
          }

}
0
 
expertmbCommented:
class CardsInHandPanel extends JPanel implements ActionListener{
     private Image image; // background image
     //private JViewport vp = new JViewport();
     JPanel scrollpanel = new JPanel();
     JScrollPane scrollpane = new JScrollPane(scrollpanel);
     private JButton up;
     private JButton down;
     public CardsInHandPanel()
     {
          image =  Toolkit.getDefaultToolkit().getImage("d:/rnd/group-logo.gif");
//GraphicUtilities.loadImage("C://card_window_t.png");
          setMinimumSize(new Dimension(image.getWidth(null) + 25,image.getHeight(null)));
          setOpaque(false);

          // create scroll buttons
          up = createButton("D:\\up.gif", "Scroll Up");
          up.setBounds(image.getWidth(null) + 25 - up.getIcon().getIconWidth(), 30, 20,20);
          down = createButton("d:\\downtriangle.gif","Scroll Down");
          down.setBounds(image.getWidth(null) + 25 - up.getIcon().getIconWidth(), image.getHeight(null) - 20 - 25, 20,20);

          scrollpanel.setLayout(new BoxLayout(scrollpanel, BoxLayout.Y_AXIS) );
          scrollpanel.setOpaque(false);
          //vp.setOpaque(false);
          scrollpane.setOpaque(false);
          scrollpane.getViewport().setOpaque(false);
          setLayout(null);
          int y = -36; // offset by six for the first element
          for (int i = 0; i < 10; i++)
          {
               JLabelOverlayedText newCard = new JLabelOverlayedText(new ImageIcon("D:\\rnd\\ant_logo_small.gif"), "Card Name" + i, 12);
               newCard.setBounds(2,y+=36,165,36);
               scrollpanel.add(newCard);
          }
          System.out.println("scrollpanel: " + scrollpanel.getComponentCount());
          //vp.setView(scrollpanel);
          /*vp.setView(scrollpane);
          vp.setBounds(2,30,165,(36 * 5));*/
          scrollpane.getViewport().setView(scrollpanel);
          //scrollpane.getViewport().setBounds(2,30,165,(36 * 5));
          scrollpane.setBounds(2,30,165,(36 * 5));
                  add(scrollpane);
          //add(vp);
          add(up);
          add(down);
     }
0
 
darkpegasus5Author Commented:
This solution uses a scrollpane which is what I was trying to avoid since I never want to see scrollbars and setting both scroll policies to never is not a valid option.
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
expertmbCommented:
solution without scrollpane

import javax.swing.*;
import javax.swing.border.EtchedBorder;

import java.awt.*;
import java.awt.event.*;

/************************************************************************************/


class CardsInHandPanel extends JPanel implements ActionListener{
    private Image image; // background image
    private JViewport vp = new JViewport();
    JPanel scrollpanel = new JPanel();
    JScrollPane scrollpane = new JScrollPane(scrollpanel);
    private JButton up;
    private JButton down;
    public CardsInHandPanel()
    {
         image =  Toolkit.getDefaultToolkit().getImage("d:/rnd/group-logo.gif");
//GraphicUtilities.loadImage("C://card_window_t.png");
         setMinimumSize(new Dimension(image.getWidth(null) + 25,image.getHeight(null)));
         setOpaque(false);

         // create scroll buttons
         up = new JButton("Scroll Up", new ImageIcon("D:\\RND\\up.gif"));//createButton("D:\\up.gif", "Scroll Up");
         up.addActionListener(this);
         //up.setBounds(image.getWidth(null) + 25 - up.getIcon().getIconWidth(), 30, 20,20);
         down = new JButton("Scroll Down", new ImageIcon("D:\\RND\\downtriangle.gif"));//createButton("d:\\downtriangle.gif","Scroll Down");
         down.addActionListener(this);
         //down.setBounds(image.getWidth(null) + 25 - up.getIcon().getIconWidth(), image.getHeight(null) - 20 - 25, 20,20);

         scrollpanel.setLayout(new BoxLayout(scrollpanel, BoxLayout.Y_AXIS) );
         scrollpanel.setOpaque(false);
         vp.setOpaque(false);
         setLayout(new GridLayout(3,1));
         int y = -36; // offset by six for the first element
         for (int i = 0; i < 10; i++)
         {
              JLabelOverlayedText newCard = new JLabelOverlayedText(new ImageIcon("D:\\rnd\\ant_logo_small.gif"), "Card Name" + i, 12);
              newCard.setBounds(2,y+=36,165,36);
              scrollpanel.add(newCard);
         }
         System.out.println("scrollpanel: " + scrollpanel.getComponentCount());
         vp.setView(scrollpanel);
         vp.setBounds(2,30,165,(36 * 5));
         add(vp);
         add(up);
         add(down);
    }

     /**
      * @return
      */
     public Image getImage() {
          return image;
     }

     /**
      * @param image
      */
     public void setImage(Image image) {
          this.image = image;
     }

     public void paintComponent(Graphics g){
          super.paintComponent(g);
          g.drawImage(image,0,0,null);
     }

     /**
               Creates a Swing JButton. The image used for the button is
               located at "../images/menu/" + name + ".png". The image is
               modified to create a "default" look (translucent) and a
               "pressed" look (moved down and to the right).
               <p>The button doesn't use Swing's look-and-feel and
               instead just uses the image.
          */
          public JButton createButton(String filename, String toolTip) {

               ImageIcon image = new ImageIcon(filename);
               JButton button = new JButton();
               ImageIcon iconRollover = new ImageIcon(filename);
               button.addActionListener(this);

               button.setOpaque(false);
               button.setRolloverEnabled(true);
               button.setBorder(null);
               button.setIgnoreRepaint(true);
               button.setFocusable(false);
               button.setToolTipText(toolTip);
               button.setBorder(null);
               button.setContentAreaFilled(false);
               Cursor cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
               button.setCursor(cursor);
               button.setIcon(image);

               return button;
          }

     public void actionPerformed(ActionEvent e)
     {
               Object source = e.getSource();
               Point p = vp.getViewPosition();
                  System.out.println("x: " + p.x);
                  System.out.println("y: " + p.y);

               if (source == down)
                    p.translate(0,10);
               else if(source == up){
                           if(p.y > 0)
                                 p.translate(0,-10);
                        }
               else if (p.y > 0){ // don't scroll higher than what is visible
                    p.translate(0,-10);
               }

           JButton b = (JButton)source;
               vp.setViewPosition(p);
     }
     public static void main(String[] args){
        JFrame f = new JFrame();
        f.setSize(300,300);
        f.getContentPane().add(new CardsInHandPanel());
        f.setVisible(true);
   }
}
/**********************************************************************************/


class JLabelOverlayedText extends JLabel implements MouseListener{
     private String myText;
     private boolean transparentImage = true;

     public JLabelOverlayedText(ImageIcon i){
          super(i);
          addMouseListener(this);
     }

     public JLabelOverlayedText(ImageIcon i, String text)
     {
          this(i);
          myText = text;
     }

     public JLabelOverlayedText(ImageIcon i, String text, int fontSize)
     {
          this(i, text);
          setFont(new Font("Serif", 1, fontSize));
     }

     public void paintComponent(Graphics g)
     {
          super.paintComponent(g);
          ImageIcon imageicon = (ImageIcon)this.getIcon();
          Image image = imageicon.getImage();

          FontMetrics fm = this.getFontMetrics(getFont());
          Point p = new Point();
          p.setLocation((getWidth() - fm.getStringBounds(myText, g).getWidth())/2 , (getHeight()/2)+5);
          g.setFont(getFont());
          g.setColor(Color.WHITE);

          Graphics2D g2 = (Graphics2D)g;
          if (image != null)
          {
               Composite alpha;
               if (transparentImage)
                    alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
               else
                    alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
               g2.setComposite(alpha);
               g2.drawImage(image, 0, 0, null);
               g2.drawString(myText, p.x, p.y);
          }
     }

     public void mouseClicked(MouseEvent e) {}
     public void mouseEntered(MouseEvent e) {
          transparentImage = false;
     }
     public void mouseExited(MouseEvent e)     {
               transparentImage = true;
          }
          public void mousePressed(MouseEvent e)     {}
          public void mouseReleased(MouseEvent e)     {}

          public void actionPerformed(ActionEvent e) {}

          public void mouseDragged(MouseEvent e) {}
          public void mouseMoved(MouseEvent e) {
               synchronized(this) {
               if (contains(e.getPoint()))
                    transparentImage = true;
               else
                    transparentImage = false;
               }
          }

}
0
 
darkpegasus5Author Commented:
I've tried this, but the panel with the jlabels on it still resizes beyond the (5 * 36) height specification. All labels are shown that fit the area instead of "clipping" only what is in view for the current 5 items (each item is 36 in height)
0
 
darkpegasus5Author Commented:
That did it! Thanks for your help and patience
0
 
expertmbCommented:
:-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.