Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 6 of 6

Thread: BorderLayouts and graphics panels and such.

  1. #1
    Member
    Join Date
    May 2013
    Posts
    96
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default BorderLayouts and graphics panels and such.

    So I have something of an integration problem, I guess. In my current Java course, we have an assignment involving Graphics and Graphics2D. What we have to do is draw 4 "fans" in a frame, oriented such that there's one at each of the main compass points. Each fan is a series of 5 equal sized blades, represented by arcs, and enclosed in a circle. Also, the fan blades have to spin. In addition, we have to put in the center a star that sort of jumps around its little section. That is, it disappears and then reappears 90 degrees away. So it's all animated.

    Anyway, the good news for you guys and gals is that I have all those individual pieces already done. I have two classes--one named FanBlades for the fans, and one named SpinningStar for the star. I can run one instance of either of these objects and it looks great. But if I try to put them together in one frame, I can't get it to look right. There's something I'm missing about BorderLayout. And it's aggravating because I've used BorderLayout on my GUI windows before.

    So here's the AnimationFrame class, which attempts to tie them together. At present, it just shows two of the fans.

    public class AnimationFrame 
    {
    	//Total frame width and height.
    	protected static final int FRAME_WIDTH = 600;
    	protected static final int FRAME_HEIGHT = 600;
     
    	public static void main(String[] args) 
    	{
     
    		JFrame mainFrame = new JFrame();
     
    		mainFrame.setSize(FRAME_HEIGHT,FRAME_WIDTH);
    		mainFrame.setTitle("Spinning thingies!");
    		mainFrame.setVisible(true);
    		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		mainFrame.add(new FanBlades(),BorderLayout.NORTH);
    		mainFrame.add(new FanBlades(),BorderLayout.SOUTH);
     
    	}

    That code shows nothing but a blank gray screen. HOWEVER, if I set the layout to GridLayout, I can see both fans. But that's not the layout I want.

    I thought this would be the easy part of the project, but now it's like the solution is dangling just beyond my grasp.

    Here is the code for the FanBlades class.

     
    public class FanBlades extends JPanel
    {
     
    	private final int PANEL_WIDTH = AnimationFrame.FRAME_WIDTH / 4;
    	private final int PANEL_HEIGHT = AnimationFrame.FRAME_HEIGHT / 4;
     
    	//Starting position of the container box for the fan blades.
    	private int start_x;
    	private int start_y;
     
    	//Angle of the arc.
    	private int arcAngle;
     
    	//Starting angle for the blades.
    	private int startAngle;
     
    	//Width and length of the arcs.
    	private int arcWidth;
    	private int arcLength;	
     
    	//Integer count of the animation state, basically 1 of 8 drawings that loop.
    	private int animationState = 0;
     
    	//Speed in milliseconds of the animation.
    	private int animationSpeed = 100;
    	//Timer to control the fan animation.
    	private Timer animationTimer = new Timer(animationSpeed,new TimerListener());
     
    	//Color palette for the fan blades.
    	private Color[] palette = new Color[5];
     
    	FanBlades()
    	{
    		//Build the color palette.
    		for(int i = 0; i < 5; i++)
    			palette[i] = buildPalette();
     
    		this.setSize(PANEL_WIDTH, PANEL_HEIGHT);
    		this.setLayout(new FlowLayout(FlowLayout.LEFT));
     
    		animationTimer.start();		
    	}
    	protected void paintComponent(Graphics g)
    	{
     
     
    		int colorIndex = 0;
     
    		super.paintComponent(g);
     
    		//Start the fan's enclosing panel 10% off from the side.
    		//Round off to nearest whole number.
    		start_x = (int)(PANEL_WIDTH * 0.1);
    		start_y = (int)(PANEL_WIDTH * 0.1);
     
    		//Each fan blade is an arc of 1/10th of a circle, 36 degrees.
    		arcAngle = 36;
     
    		//Starting angle for the blades.
    		startAngle = animationState * 10;
     
     
    		//Width and length of the arcs.
    		arcWidth = 110;
    		arcLength = 110;	
     
    		//Draw the fan blades.
    		while(startAngle < 360)
    		{
    			g.setColor(palette[colorIndex]);
    			g.fillArc(start_x, start_y, arcWidth, arcLength, startAngle, arcAngle);
    			startAngle += (2 * arcAngle);
    			colorIndex++;
    		}	
    			g.drawOval(start_x, start_y, arcWidth, arcLength);
     
    	}
    	private Color buildPalette()
    	{
    		Random rand = new Random();
    		int redBalance = rand.nextInt(255);
    		int greenBalance = rand.nextInt(255);
    		int blueBalance = rand.nextInt(255);
     
    		return new Color(redBalance,greenBalance,blueBalance);
    	}
    	class TimerListener implements ActionListener
    	{
    		public void actionPerformed(ActionEvent e)
    		{
    			if(animationState < 7)
    				animationState++;
    			else
    				animationState = 0;
    			repaint();
    		}
     
    }

    And the SpinningStar class.

    public class SpinningStar extends JPanel
    {
     
    	//Delay for the timer.
    	private int animationDelay = 500;
     
    	//Timer to control the animation.
    	private Timer animationTimer = new Timer(animationDelay,new TimerListener());
     
    	//Variable to indicate the position of the star, in radians.
    	private double starPosition = 0;
     
     
    	private final int CLOCKWISE = 1;
    	private final int COUNTERCLOCKWISE = -1;
     
    	//Direction of the rotation.  
    	private int rotationDirection;
     
    	SpinningStar()
    	{
    		//Set the rotation direction.
    		rotationDirection = COUNTERCLOCKWISE;
     
    		//Start the timer.
    		animationTimer.start();
    	}
    	// draw general paths
    	public void paintComponent( Graphics g )
    	{
    	   super.paintComponent( g ); // call superclass's paintComponent
    	   Random random = new Random(); // get random number generator
     
    	   //Points on the star represented by two integer arrays.	   
    	   int[] xPoints = { 55, 67, 109, 73, 83, 55, 27, 37, 1, 43 };
    	   int[] yPoints = { 0, 36, 36, 54, 96, 72, 96, 54, 36, 36 };
     
    	   //The coordinates of approximate center of the star.
    	   int centerX;
    	   int centerY;
     
    	   //Sums of the x and y coordinates of the star points.  Used to calculate the center.
    	   int xSum = 0;
    	   int ySum = 0;
     
    	   Graphics2D g2d = ( Graphics2D ) g;
    	   GeneralPath star = new GeneralPath(); // create GeneralPath object
     
    	   //Two points on opposite ends of the star are 
    	   //(1,36) and (109,36) also known as
    	   //(xPoints[8],yPoints[8]) and (xPoints[2],yPoints[2])
    	   //Use these to get an approximate diameter of the surrounding circle.
    	   double diameter = getDiameter(xPoints[8],xPoints[2],yPoints[8],yPoints[2]);
     
    	   //Use these same points to get the midpoint of the circle.
    	   //double midpoint = ( (double)xPoints[8] + xPoints[2]) / 2 ;
     
    	   //Find the approximate center of the star.
    	   for(int i = 0; i < xPoints.length; i++)
    	   {
    		   xSum = xSum + xPoints[i];
    		   ySum = ySum + yPoints[i];
    	   }
     
    	   //Divide sums by number of points to get the approximate center.  Drop the decimal point.
    	   centerX = xSum / xPoints.length;
    	   centerY = ySum / yPoints.length;
     
     
    	   // set the initial coordinate of the General Path
    	   star.moveTo( xPoints[ 0 ], yPoints[ 0 ] );
     
    	   // create the star--this does not draw the star
    	   for ( int count = 1; count < xPoints.length; count++ )
    	   		star.lineTo( xPoints[ count ], yPoints[ count ] );
     
     
     
     
     
    	   star.closePath(); // close the shape
     
    	   g2d.translate( 150, 150 ); // translate the origin to (150, 150)
     
     
    	   Shape myCircle = new Ellipse2D.Double(centerX-(diameter/2), centerY-(diameter/2), diameter, diameter);
     
     
     
    	   //Rotate the position of the star.
    	   g2d.rotate( starPosition );
     
    	   // set random drawing color
    	   g2d.setColor( new Color( random.nextInt( 256 ),
    	   random.nextInt( 256 ), random.nextInt( 256 ) ) );
     
    	   //Draw one star at the indicated position
    	   g2d.fill( star ); 
    	   g2d.draw(myCircle);
     
    	   //Rotate the position for the next star by Pi/2 radians, or 90 degrees.
    	   //Multiply by the value of the rotationDirection variable to decide direction.
    	   starPosition += (Math.PI / 2) * rotationDirection;
     
     
     
    	} // end method paintComponent
     
    	private double getDiameter(int x1, int x2, int y1, int y2)
    	{
    		//Use the distance formula to calculate the distance between two 
    		//points on opposite ends of the star.
    		//First get (x2-x1)^2 and (y2-y1)^2.
    		double xDist = Math.pow((x2 - x1), 2);
    		double yDist = Math.pow((y2 - y1), 2);
     
    		//Get the total diameter.
    		double diameter = Math.sqrt((xDist + yDist));
     
    		//Return just the radius.  Cast to integer to approximate.
    		return diameter;
    	}
     
     
     
    	public static void main(String[] args) 
    	{
     
    		JFrame starFrame = new JFrame("Spinny star!");
     
    		starFrame.setVisible(true);
    		starFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		starFrame.add(new SpinningStar());
    		starFrame.setSize(300,300);
     
     
     
     
     
    	}
     
    	class TimerListener implements ActionListener
    	{
    		public void actionPerformed(ActionEvent e) 
    		{
    			repaint();
     
    		}
     
    	}
    }


  2. #2
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,324
    My Mood
    Hungover
    Thanks
    142
    Thanked 624 Times in 535 Posts

    Default Re: BorderLayouts and graphics panels and such.

    Set the background of the top FanBlades to red and the bottom FanBlades to green so you understand where everything is. BorderLayout saves most of the room for the CENTER component. Try setting the min/max/preferred size of your FanBlades.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  3. The Following User Says Thank You to KevinWorkman For This Useful Post:

    mstabosz (September 8th, 2013)

  4. #3
    Member
    Join Date
    May 2013
    Posts
    96
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: BorderLayouts and graphics panels and such.

    Quote Originally Posted by KevinWorkman View Post
    Set the background of the top FanBlades to red and the bottom FanBlades to green so you understand where everything is. BorderLayout saves most of the room for the CENTER component. Try setting the min/max/preferred size of your FanBlades.
    Fantastic. I added the following code to the constructor of my FanBlades class:

    Dimension preferredSize = new Dimension(PANEL_WIDTH, PANEL_HEIGHT);
     
    this.setPreferredSize(preferredSize);

    And it looks like it's working better. The fans are all jutting right up against the edges of their respective panels, which is not what I want. I want them centered. But that's probably part of how I implemented the FanBlades class and I think I can figure that one out on my own. I'll post back if I get stumped on that.

    Thanks a bunch Kevin. Helpful as always.

  5. #4
    Member
    Join Date
    May 2013
    Posts
    96
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: BorderLayouts and graphics panels and such.

    So I've now put a fan in each of the 4 directions, plus the star in the middle. The code below makes the frame. As you can see, I basically used up all 5 segments available to BorderLayout. There are 5 panels on the frame.

    The assignment is complete. However, I can never resist tinkering with my code and adding flourishes. I thought it would be cool to add a control panel of sorts to toggle a few features, such as spinning directions of the fans and star, speed of the fans, and maybe speed of the star. My question is this.... is it possible to add an additional panel to the below JFrame, or have I basically packed my frame like a theater that's filled up all its seats? Part of me is saying that this proposition makes perfect sense, another is saying "Java can't possibly be that rigid that it allows only a maximum of 5 panels in a BorderLayout frame.

    I was considering cramming all the drawings into one panel, the control panel into the second, then putting the whole thing into the frame GridLayout. But then I tried to cram the pictures into a panel and it got all screwy. Probably because of how I specified all the preferred sizes of the panels and the starting areas of all the fans.

                     JFrame mainFrame = new JFrame();
    		JPanel[] fanPanel = new FanBlades[4];	
     
    		//Set attributes of the main frame.
    		mainFrame.setSize(FRAME_HEIGHT,FRAME_WIDTH);
    		mainFrame.setTitle("Spinning thingies!");
    		mainFrame.setVisible(true);
    		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		mainFrame.setResizable(false);
    		mainFrame.setBackground(Color.WHITE);
    		mainFrame.setLocationRelativeTo(null);
     
    		//Set up the 4 fans.
    		for(int i = 0; i < 4; i++)
    			fanPanel[i] = new FanBlades(i);
     
    		//Position the fans.
    		mainFrame.add(fanPanel[0],BorderLayout.NORTH);
    		mainFrame.add(fanPanel[1],BorderLayout.EAST);
    		mainFrame.add(fanPanel[2],BorderLayout.SOUTH);
    		mainFrame.add(fanPanel[3],BorderLayout.WEST);
     
    		//Place the star.
    		mainFrame.add(new SpinningStar(),BorderLayout.CENTER);

  6. #5
    Super Moderator jps's Avatar
    Join Date
    Jul 2012
    Posts
    2,642
    My Mood
    Daring
    Thanks
    90
    Thanked 263 Times in 232 Posts

    Default Re: BorderLayouts and graphics panels and such.

    You can use different layouts that provide more options than the given 5 (north, south, west, east, center).
    You can also place another container in one of the positions, and give that container a layout with multiple components.
    For example, visualize this:
    mainFrame.add(new JPanel(new BorderLayout()), BorderLayout.SOUTH);
    Now the southern area has the north, south, west, east, and center. (or you can use what ever other layout you choose)

  7. The Following User Says Thank You to jps For This Useful Post:

    mstabosz (September 12th, 2013)

  8. #6
    Member
    Join Date
    May 2013
    Posts
    96
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: BorderLayouts and graphics panels and such.

    Thanks JPS. I tried for a while, but it just sorta felt like trying to toss the control panel into the same frame as the animations just sorta screwed everything up aesthetically, so I went with another frame, which was fun, looked better, and helped me learn about window listeners.

Similar Threads

  1. Help w/ hw , help with panels layouts in frame.
    By Lenjaku in forum What's Wrong With My Code?
    Replies: 4
    Last Post: March 30th, 2013, 03:12 PM
  2. adding or removing panels to panels
    By luisp88 in forum AWT / Java Swing
    Replies: 3
    Last Post: November 1st, 2011, 04:37 PM
  3. Java Not Removing Panels?
    By Pantheon8 in forum What's Wrong With My Code?
    Replies: 3
    Last Post: August 17th, 2011, 07:54 PM
  4. JTabbedPane with two Panels in the same tab?
    By cadarn in forum AWT / Java Swing
    Replies: 1
    Last Post: August 3rd, 2011, 10:48 AM
  5. Help with Layouts and Panels
    By Zookey in forum What's Wrong With My Code?
    Replies: 0
    Last Post: January 29th, 2011, 05:48 PM