Solved

Java scrolling with a Viewport

Posted on 2004-10-17
7
2,250 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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…

759 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now