Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / March 2005

Tip: Looking for answers? Try searching our database.

Floating Label Component in JScrollPane

Thread view: 
reinhard.engels@gmail.com - 15 Mar 2005 16:48 GMT
I have an app that displays stacked rectangular glyphs representing
data in a jscrollpane. It works fine.

Problem: I'd like to add labels to the rows of data glyphs. I'd like
these labels to float as you scroll horizontally, sort of like column
headers in excel, except the other direction. This doesn't work, as
I've coded it. When I scroll, there is some kind of repaint issue and
visual artifacts from the labels trace across the screen.

What I'm doing is calling setBounds on the floating label component in
the data panel paintComponent. I'm assuming this is wrong, but I don't
know what else to do. See code below for a short but full "working"
applet that displays the problem. If it looks hideous in your newreader
here are urls for the code and the applet:

code url:

http://www.everydaysystems.com/testjava/float_in_scroll/FloatInScrollTest.java.txt

applet url:

http://www.everydaysystems.com/testjava/float_in_scroll/FloatInScrollTest.html

I'm hoping this is an embarrassingly simple problem.

Thanks (and embarrassed) in advance,

Reinhard

*******************************************************

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;

public class FloatInScrollTest extends JApplet {

   public void init() {
       setSize(500, 100);
       JPanel dataPanel = new DataPanel();
       JScrollPane scrollPane = new JScrollPane(dataPanel);
       scrollPane

.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
       scrollPane

.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
       scrollPane.setPreferredSize(new Dimension(500, 100));
       getContentPane().add(scrollPane);
   }

   class FloatingLabelGlyph extends JComponent {
       public FloatingLabelGlyph(String label, Color color) {
           this.color = color;
           this.label = label;
           setVisible(true);
       }

       public void paintComponent(Graphics g) {
           g.setColor(color);
           g.drawString(label, 0, g.getFont().getSize());
       }

       Color color;
       String label;
   }

   class DataGlyph extends JComponent {
       public DataGlyph(Color color, int x, int y, int width) {
           this.color = color;
           setBounds(x, y, width, height);
           setVisible(true);
       }

       public void paintComponent(Graphics g) {
           g.setColor(color);
           g.fillRect(0, 0, getWidth(), getHeight());
       }

       private int height = 10;
       private Color color;
   }

   class DataPanel extends JPanel {
       public DataPanel() {
           super();
           setLayout(null);
           setSize(new Dimension(1000, 1000));
           setPreferredSize(new Dimension(1000, 1000));
           floatingLabels = new FloatingLabelGlyph[labels.length];
           for (int i = 0; i < labels.length; i++) {
               add(floatingLabels[i] = new
FloatingLabelGlyph(labels[i],
                       colors[i]));
           }
           add(new DataGlyph(colors[0], 150, rowYs[0], 50));
           add(new DataGlyph(colors[0], 170, rowYs[1], 75));
           add(new DataGlyph(colors[0], 220, rowYs[0], 100));
           add(new DataGlyph(colors[1], 160, rowYs[2], 55));
           add(new DataGlyph(colors[1], 960, rowYs[2], 35));
           add(new DataGlyph(colors[1], 220, rowYs[2], 25));
           add(new DataGlyph(colors[1], 200, rowYs[3], 33));
           add(new DataGlyph(colors[2], 600, rowYs[4], 100));
           add(new DataGlyph(colors[2], 900, rowYs[4], 88));
           setVisible(true);
       }

       public void paintComponent(Graphics g) {
           // TODO: update label positions. This is the broken part.
           g.clearRect(0,0,getWidth(),getHeight());
           for (int i = 0; i < floatingLabels.length; i++) {
               g.clearRect(floatingLabels[i].getX(),
floatingLabels[i].getY(),
                       floatingLabels[i].getWidth(), floatingLabels[i]
                               .getHeight());
               floatingLabels[i].setBounds((int) ((JViewport)
getParent())
                       .getViewPosition().getX(), labelYs[i], 80, 15);
           }
           super.paintComponent(g);
       }

       private String[] labels = new String[] { "Red Data", "Green
Data",
               "Blue Data" };
       private Color[] colors = new Color[] { Color.RED, Color.GREEN,
               Color.BLUE };
       private FloatingLabelGlyph[] floatingLabels;
       private int[] rowYs = new int[] { 10, 25, 40, 55, 70 };
       private int[] labelYs = new int[] { 10, 40, 70 };
   }

}

*******************************************************
John McGrath - 17 Mar 2005 06:03 GMT
> What I'm doing is calling setBounds on the floating label component in
> the data panel paintComponent. I'm assuming this is wrong, but I don't
> know what else to do.

One thing I noticed is that the paintComponent() methods do not all call
super.paintComponent(), which they generally should.  However, I don't
think that is the cause of your problems.

Moving components in the paintComponent() method is definitely not a good
idea.  I think a much better approach would be to place the "floating"
glyphs on a stationary, transparent panel that is placed above the
JScrollPane.

Signature

Regards,

John McGrath

reinhard.engels@gmail.com - 17 Mar 2005 15:26 GMT
> One thing I noticed is that the paintComponent() methods do not all call
> super.paintComponent(), which they generally should.  However, I don't
> think that is the cause of your problems.

Thank you, John. I tried adding super.paintComponent(g) methods but, as
you predicted, no luck.

> Moving components in the paintComponent() method is definitely not a good
> idea.  I think a much better approach would be to place the "floating"
> glyphs on a stationary, transparent panel that is placed above the
> JScrollPane.

The problem with putting the labels on a stationary panel is that I
*do* want them to scroll vertically (so they stay above the vertically
scrolling data glyphs they are labeling) but not horizontally (or
they'd disappear as you scrolled to view rightward data glyphs).
Naively, I'd think the floating label repositioning should be called by
a listener triggered whenever a scroll event took place, but from my
poking around, it doesn't seem there is such a listener.

Thanks again! Brute force or the kindness of strangers will eventually
yield a solution and I'll be sure to post it here.

Reinhard
reinhard.engels@gmail.com - 17 Mar 2005 15:56 GMT
Got it!

scrollPane.getHorizontalScrollBar().addAdjustmentListener(new
FloatingLabelAdjustmentListener(dataPanel));

Full revised code below. The scroll is still a little flickery, but no
more artifacts tracing all over the screen. Hope this is of use to
someone somewhere sometime...

Reinhard

**************************************************************

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;

public class FloatInScrollTest extends JApplet {

   public void init() {
       setSize(500, 100);
       DataPanel dataPanel = new DataPanel();
       JScrollPane scrollPane = new JScrollPane(dataPanel);
       scrollPane

.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
       scrollPane

.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
       scrollPane.setPreferredSize(new Dimension(500, 100));
       scrollPane.getHorizontalScrollBar().addAdjustmentListener(new
FloatingLabelAdjustmentListener(dataPanel));
       getContentPane().add(scrollPane);
   }

   class FloatingLabelGlyph extends JComponent {
       public FloatingLabelGlyph(String label, Color color, int y) {
           this.color = color;
           this.label = label;
           this.y = y;
           setVisible(true);
       }

       public void paintComponent(Graphics g) {
           g.setColor(color);
           g.drawString(label, 0, g.getFont().getSize());
           super.paintComponent(g);
       }

           public int getY(){
              return y;
           }
       int y;
       Color color;
       String label;
   }

   class DataGlyph extends JComponent {
       public DataGlyph(Color color, int x, int y, int width) {
           this.color = color;
           setBounds(x, y, width, height);
           setVisible(true);
       }

       public void paintComponent(Graphics g) {
           g.setColor(color);
           g.fillRect(0, 0, getWidth(), getHeight());
           super.paintComponent(g);
       }

       private int height = 10;
       private Color color;
   }

   class FloatingLabelAdjustmentListener implements AdjustmentListener
{
       public FloatingLabelAdjustmentListener(DataPanel dataPanel){
           super();
           this.dataPanel = dataPanel;
       }
       public void adjustmentValueChanged(AdjustmentEvent e){
           FloatingLabelGlyph[] floatingLabels =
dataPanel.getFloatingLabels();
           for (int i = 0; i < floatingLabels.length; i++) {
               floatingLabels[i].setBounds((int) ((JViewport)
dataPanel.getParent())
                       .getViewPosition().getX(),
floatingLabels[i].getY(), 80, 15);
           }
       }
       private DataPanel dataPanel;
   }

   class DataPanel extends JPanel {
       public DataPanel() {
           super();
           setLayout(null);
           setSize(new Dimension(1000, 1000));
           setPreferredSize(new Dimension(1000, 1000));
           floatingLabels = new FloatingLabelGlyph[labels.length];
           for (int i = 0; i < labels.length; i++) {
               add(floatingLabels[i] = new
FloatingLabelGlyph(labels[i],
                       colors[i],labelYs[i]));
           }
           add(new DataGlyph(colors[0], 150, rowYs[0], 50));
           add(new DataGlyph(colors[0], 170, rowYs[1], 75));
           add(new DataGlyph(colors[0], 220, rowYs[0], 100));
           add(new DataGlyph(colors[1], 160, rowYs[2], 55));
           add(new DataGlyph(colors[1], 960, rowYs[2], 35));
           add(new DataGlyph(colors[1], 220, rowYs[2], 25));
           add(new DataGlyph(colors[1], 200, rowYs[3], 33));
           add(new DataGlyph(colors[2], 600, rowYs[4], 100));
           add(new DataGlyph(colors[2], 900, rowYs[4], 88));
           setVisible(true);
       }

       public FloatingLabelGlyph[] getFloatingLabels(){
           return floatingLabels;
       }

       private String[] labels = new String[] { "Red Data", "Green
Data",
               "Blue Data" };
       private Color[] colors = new Color[] { Color.RED, Color.GREEN,
               Color.BLUE };
       private FloatingLabelGlyph[] floatingLabels;
       private int[] rowYs = new int[] { 10, 25, 40, 55, 70 };
       private int[] labelYs = new int[] { 10, 40, 70 };
   }

}

********************************************************************


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.