Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Swing Layout Problem

Status
Not open for further replies.

drkestrel

MIS
Sep 25, 2000
439
GB
I want to layout the following:
Code:
|-----------------------
|                     | |
|                     | |
|                     | |
|       image         | |
|                     | |
|                     | |
|                     | | <- scroll bar
|                     | |
|                     | |
|     --------        | |
|     |button|        | |
|     --------        | |
|------------------------

An image and a button on a same 'pane that is scrollable. (i.e. the button would not be viewable until it is scrolled)

I tried the following code, but there simply is not scroll bars!!
Code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.applet.*;
import java.net.URL;


public class TestScrollFrame
{
    public static void main (String[] cool)
    {
        JFrame myFrame = new CoolFrame();
        myFrame.show();
    }
}

class CoolFrame extends JFrame
{

    public CoolFrame()
    {
        setTitle(&quot;Frame Test&quot;);
        Toolkit tk= Toolkit.getDefaultToolkit();
        Dimension d= tk.getScreenSize();
        setSize(d.width,d.height);
        setLocation(0,0);
        addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
        Container contentPane = getContentPane();
        Component viewedComponent = new MyBorderPanel();
        JScrollPane sp = new JScrollPane(viewedComponent,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        contentPane.add(sp);
    }


}

class MyFlowPanel extends JPanel
{
    private Image myImage;
    MediaTracker tracker;

    public MyFlowPanel(Image myImage)
    {
        this.myImage= myImage;
        tracker = new MediaTracker(this);
        tracker.addImage(myImage,0);
        try
        {
            tracker.waitForID(0);
        }  //try
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }  //catch
        setLayout(new FlowLayout(FlowLayout.LEFT));
    } //Constructor

    public void paintComponent(Graphics g)
    {
        g.drawImage(myImage,5,5,null);
    }

} //class MyFlowPanel


class MyBorderPanel extends JPanel
{
    public MyBorderPanel()
    {
        Toolkit tk= Toolkit.getDefaultToolkit();
        try
        {
            Image theImg = Toolkit.getDefaultToolkit().getImage(&quot;myImg.jpg&quot;);
            MyFlowPanel imgPanel = new MyFlowPanel(theImg);
            add(imgPanel,&quot;Center&quot;);
            JPanel soundPanel = new JPanel(new FlowLayout());
            JButton soundButton = new JButton (&quot;A Button&quot;);
            soundButton.addActionListener(new ButtonListener());
            soundPanel.add(soundButton);
            add(soundPanel,&quot;South&quot;);
        } //try
        catch (Exception e)
        {
            e.printStackTrace();
        } //catch

    } //Constructor

} //MyBorderPanel

class ButtonListener implements ActionListener
{
    public void actionPerformed(ActionEvent evt)
    {
        //do something

    } //actionPerformed
} //ButtonListener

When the frame is resized, the picture is 'croped', and everthing else is resized!
 
You have to use the setMinimumSize() and setPreferredSize() functions of the JPanel you want to have displayed by the JScrollPane. I did not adapt your code (sorry), but I wrote one myself (was faster, I think ;-) - and it's everything but perfect, a throwaway prototype, what do you say...):

Code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.*;

public class MyTestScrollFrame extends JFrame
{
	public static void main(String[] args)
	{
		new MyTestScrollFrame().setVisible(true);
	}

	public MyTestScrollFrame()
	{
		super(&quot;Test&quot;);
		this.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		this.setSize(300, 500);
		this.setLocation(100, 100);
		this.getContentPane().setLayout(new BorderLayout());
		JScrollPane scroller = new JScrollPane(new ImagePanel(),
																					 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
																					 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		this.getContentPane().add(scroller);
	}
}

class ImagePanel extends JPanel
{
	private BufferedImage image;

	public ImagePanel()
	{
		initImage();
		initSize();
	}

	private void initImage()
	{
		this.image = new BufferedImage(100, 1000, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = (Graphics2D)this.image.getGraphics();
		g.setColor(Color.white);
		g.fillRect(0, 0, 100, 1000);
		g.setColor(Color.black);
		g.drawOval(0, 0, 100, 1000);
	}

	private void initSize()
	{
		this.setMinimumSize(new Dimension(100, 1000));
		this.setPreferredSize(new Dimension(100, 1000));
	}

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

Hope this helps...
allow thyself to be the spark that lights the fire
haslo@haslo.ch - www.haslo.ch​
 
I could get the following working
Code:
|-----------------------
|                     | |
|                     | |
|                     | |
|       image         | |
|                     | |
|                     | |
|                     | | <- scroll bar
|                     | |
|_______________________|
|     --------          |
|     |button|          |
|     --------          | 
|------------------------
(i.e. just the image that is scrolling and not the whole screen)

However,
Problem 1- To the right of the scrolling image- I see something grey, and upon scrolling half-way, I see lots of horizontal black line (JPanel.setBackground() or drawImage with Background Colour passed in does not work!)
Problem 2- I could NOT get the whole image AND button scrolling

Nevertheless, the code I used to get just the image scrolling is-
Code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.*;
public class TestScrollFrame2
{
    private Dimension d;
    public static void main (String[] cool)
    {
        JFrame myFrame = new MainFrame();
        myFrame.show();
    }


}

class MainFrame extends JFrame
{
    private Dimension d;

    public MainFrame()
    {
        //Check out screen resolution
        Toolkit tk= Toolkit.getDefaultToolkit();
        d= tk.getScreenSize();
        //Maximise the Frame
        setSize(d);
        setLocation(0,0);

        setTitle(&quot;Test Frame&quot;);


        //How to handle close window (clicking the cross)
        addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
        Container contentPane = getContentPane();

        //The main Panel
        Component viewedComponent = new MyBorderPanel(d);
        contentPane.add(viewedComponent);

}

class MyImgPanel extends JPanel
{
    //The Image to show
    private Image myImage;
    MediaTracker tracker;


    //Constructor- takes in image to be displayed
    public MyImgPanel(Image myImage)
    {
        this.myImage= myImage;
        tracker = new MediaTracker(this);
        tracker.addImage(myImage,0);
        try
        {
            tracker.waitForID(0);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        setLayout(new BorderLayout(1,1));
        setMinimumSize(new Dimension (myImage.getWidth(this),myImage.getHeight(this)));
        setPreferredSize(new Dimension (myImage.getWidth(this),myImage.getHeight(this)));
                
        //DOES NOT WORK- even set it to Color.green, there is not green background
        setBackground(Color.lightGray);

    }

    //Draw the image on the upper left hand side- coordinate 1,1)
    public void paintComponent(Graphics g)
    {
        g.setColor(Color.white);
        g.drawImage(myImage,1,1,Color.white,null);
    }

}


class MyBorderPanel extends JPanel
{
    private Dimension d;

    public MyBorderPanel(Dimension d)
    {
        this.d= d;

        //Set the minimum and preferred size to be that of the screen resolution
        setMinimumSize(d);
        setPreferredSize(d);
        String imgLoc;
        //BorderLayout with horizontal and vertical gaps of 2
        setLayout(new BorderLayout(2,2));
        
        try{
            JPanel emptyPanel = new JPanel();
            emptyPanel.setBackground(Color.lightGray);
            //Create a new ImgPanel displaying the Image

            Image theImg = Toolkit.getDefaultToolkit().getImage(&quot;MyPic.jpg&quot;);
            Dimension imgDimension = new Dimension (theImg.getWidth(this),theImg.getHeight(this)+20);
            this.setMinimumSize(imgDimension);
            this.setPreferredSize(imgDimension);


            Component imgPanel = new MyImgPanel(theImg);
            JScrollPane imgSP = new JScrollPane(imgPanel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            add(imgSP,&quot;Center&quot;);
            add(emptyPanel,&quot;West&quot;);
            add(emptyPanel,&quot;East&quot;);

            //Bottom Panel showing a button
            JPanel soundPanel = new JPanel(new FlowLayout());
            JButton soundButton = new JButton (&quot;Listen to Music&quot;);
            soundButton.addActionListener(new ButtonListener());
            soundPanel.add(soundButton);
            add(soundPanel,&quot;South&quot;);

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

}

class ButtonListener implements ActionListener
{
    public void actionPerformed(ActionEvent evt)
    {
        try
        {

            //Do Something
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

I tried to get the whole frame(including the button) scrolling with the following code, but no luck!!
Code:
public class TestScrollFrame3
{
    private Dimension d;
    public static void main (String[] cool)
    {
        JFrame myFrame = new MainFrame();
        myFrame.show();
    }


}

class MainFrame extends JFrame
{
    private Dimension d;

    public MainFrame()
    {
        //Check out screen resolution
        Toolkit tk= Toolkit.getDefaultToolkit();
        d= tk.getScreenSize();
        //Maximise the Frame
        setSize(d.width,d.height);
        setLocation(0,0);

        setTitle(&quot;Test Frame&quot;);


        //How to handle close window (clicking the cross)
        addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
        Container contentPane = getContentPane();

        //The main Panel
        Component viewedComponent = new MyBorderPanel(d);
        //Make the main Panel scrollable
        JScrollPane sp = new JScrollPane(viewedComponent,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        contentPane.add(sp);
    }  //MainFrame
}

class MyImgPanel extends JPanel
{
    //The Image to show
    private Image myImage;
    MediaTracker tracker;


    //Constructor- takes in image to be displayed
    public MyImgPanel(Image myImage)
    {
        this.myImage= myImage;
        tracker = new MediaTracker(this);
        tracker.addImage(myImage,0);
        try
        {
            tracker.waitForID(0);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        setLayout(new BorderLayout(1,1));
        setMinimumSize(new Dimension (myImage.getWidth(this),myImage.getHeight(this)));
        setPreferredSize(new Dimension (myImage.getWidth(this),myImage.getHeight(this)));

    }


    //Draw the image on the upper left hand side- coordinate 1,1)
    public void paintComponent(Graphics g)
    {
        g.drawImage(myImage,1,1,Color.white,null);
    }

}


class MyBorderPanel extends JPanel
{
    private Dimension d;

    public MyBorderPanel(Dimension d)
    {
        this.d= d;

        //Set the minimum and preferred size to be that of the screen resolution
        setMinimumSize(d);
        setPreferredSize(d);
        String imgLoc;
        //BorderLayout with horizontal and vertical gaps of 2
        setLayout(new BorderLayout(2,2));
        //Different image for different screen resolution
     
        try{
            //Create a new ImgPanel displaying the Image
            Image theImg = Toolkit.getDefaultToolkit().getImage(&quot;MyPic.jpg&quot;);
            Dimension imgDimension = new Dimension (theImg.getWidth(this),theImg.getHeight(this)+20);
            this.setMinimumSize(imgDimension);
            this.setPreferredSize(imgDimension);

            Component imgPanel = new MyImgPanel(theImg);
            //JScrollPane imgSP = new JScrollPane(imgPanel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            add(imgPanel,&quot;Center&quot;);

            //Bottom Panel showing a button
            JPanel soundPanel = new JPanel(new FlowLayout());
            JButton soundButton = new JButton (&quot;Listen to music&quot;);
            soundButton.addActionListener(new ButtonListener());
            soundPanel.add(soundButton);
            add(soundPanel,&quot;South&quot;);

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

}


class ButtonListener implements ActionListener
{
    public void actionPerformed(ActionEvent evt)
    {
        try
        {

            //Do Something
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Any suggestions??
 
The grey and horizontal lines stuff is because you overwrite the paintComponent Method of the JPanel - if you don't paint anything, the JPanel does not know what to display and takes just what passes its way. You could make the following in the paintComponent() method:

Code:
public void paintComponent(Graphics g)
{
 g.setColor(Color.white); // or whatever background color you want
 g.fillRect(0, 0, this.getWidth(), this.getHeight()); // or something similar, like getSize().width, didn't check it out
 g.drawImage(...); // as above
}

You could then try to create a JPanel that contains the image's JPanel and the button, set the inner JPane's size and then set the outer JPanel's size according to the inner one plus the button height - you see what I mean? Then create the JScrollPane with the outer JPanel - gets a little complicated, but a Computer can handle that :)...

If you don't succeed just post again, I'll have a look at it this evening... (local time: 15:00)

Hope this helps...
allow thyself to be the spark that lights the fire
haslo@haslo.ch - www.haslo.ch​
 
Haslo,
Thanks, I got the Gray/Horizontal line problem sorted, but still could not get the whole Frame scrolling (i.e. if the image is very tall, then I should have to scroll down to the bottom before I could see a button).
Any suggestions?
 
Try to put the JScrollPane &quot;around&quot; the MyBorderPanel and add the MyImgPanel and the SoundPanel to the MyBorderPanel. Set the size of the MyBorderPanel then. Does this work?
allow thyself to be the spark that lights the fire
haslo@haslo.ch - www.haslo.ch​
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top