Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Java scrolling with a Viewport

Posted on 2004-10-17
7
2,258 Views
Last Modified: 2008-01-09
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;
                  }
            }

}




0
Comment
Question by:darkpegasus5
  • 4
  • 3
7 Comments
 
LVL 6

Expert Comment

by:expertmb
ID: 12336343
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
 
LVL 1

Author Comment

by:darkpegasus5
ID: 12339628
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
 
LVL 6

Expert Comment

by:expertmb
ID: 12345806
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
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

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

 
LVL 1

Author Comment

by:darkpegasus5
ID: 12353339
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
 
LVL 6

Accepted Solution

by:
expertmb earned 500 total points
ID: 12356484
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
 
LVL 1

Author Comment

by:darkpegasus5
ID: 12364498
That did it! Thanks for your help and patience
0
 
LVL 6

Expert Comment

by:expertmb
ID: 12366358
:-)
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
This video teaches viewers about errors in exception handling.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question