I have developed a small swing application in which there is a square rotating in the upper half and there is a button in the lower half which can stop/run the square to rotate.
I have used the GridLayout to place the rotating square and the button.
(Another alternative is to use 2 JPanels ,one is with rotating square and second contains the button.Using this button appears of proper size.)
Here is the code :-
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Rotation {
JButton jbtn=new JButton("Stop");
component jpn2=new component(); //created a JPanel named jpn2 and got a reference to its timer object.
Timer timer=jpn2.timer;
Rotation()
{
JFrame jfrm=new JFrame("Rotating a square about a center");
jfrm.setSize(400,400);
jfrm.setLayout(new GridLayout(2,1));
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//JPanel jpnl=new JPanel();
//jpnl.add(jbtn);
jbtn.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("Stop"))
{
timer.stop();
jbtn.setText("Spin");
}
if(e.getActionCommand().equals("Spin"))
{
timer.start();
jbtn.setText("Stop");
}
}});
jfrm.add(jpn2);
jfrm.add(jbtn);
//jfrm.add(new JButton("Click"));
jfrm.setVisible(true);
//jfrm.setOpacity(0.8f);
}
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException
{
//JFrame.setDefaultLookAndFeelDecorated(true);
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
SwingUtilities.invokeLater(new Runnable(){public void run(){new Rotation();}});
}
}
class component extends JPanel implements ActionListener
{
Timer timer;
int theta=0;
component()
{
timer=new Timer(10,this);
timer.start();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
g2.rotate(theta,100,100);
g2.fillRect(50, 50, 100,100);
}
public void actionPerformed(ActionEvent e)
{
//Changing a global variable and then drawing the rectangle again and hence indirectly the square rotates.
theta=theta+10;
if(theta==360)
theta=0;
repaint();
}
}
Here is the output:-

But my confusion is when i decided to use FlowLayout instead of GridLayout i’m getting only the button and no rotating square.
By,as far as i have read,FlowLayout places components in a row and if space is less than it uses multiple rows.
Can anyone resolve this small stupid problem of mine which currently i am not able to resolve.
As others have said (+1 to mKorbel and HFOE)
The problem is you use
setSize(..)rather callpack()before settingJFrameto visible.You will also have to override
getPrefferedSize(..)inJPanelclass which will return the size of your square multiplied by 2 (or else when it rotates it wont fit).On a side note dont throw any excpetion in
main(..)never a good thing.see below for the code (uses
FlowLayoutbut also works withGridLayout):Using
new FlowLayout():Using
new GridLayout(2,1):