Solved

Java scrolling with a Viewport

Posted on 2004-10-17
7
2,264 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
[X]
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
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

705 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