Below is a simple swing app in which i was experimenting certain custom techniques.The code is as follows :-
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ThemeComponents extends JFrame{
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable(){public void run(){new ThemeComponents();}});
}
public ThemeComponents()
{
super("HACK 1:Creating Image Themed Components ");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
CustomPanel p1=new CustomPanel();
p1.add(new CustomLabel());
add(p1);
pack();
setVisible(true);
}
}
class CustomPanel extends JPanel
{
BufferedImage img;
CustomPanel()
{
try
{
img=ImageIO.read(new File("src/background.jpg"));
} catch(IOException e){
System.out.println("Error in loading background image "+e);
}
}
public void paintComponent(Graphics g)
{
g.drawImage(img,0,0,getWidth(),getHeight(),null);
}
public Dimension getPreferredSize()
{
return new Dimension(img.getWidth(),img.getHeight());
}
}
class CustomLabel extends JLabel
{
ImageIcon img;
CustomLabel ()
{
img=new ImageIcon("src/tornado.gif");
setSize(img.getIconWidth(),getHeight());
setIcon((Icon) img);
//setOpaque(false);
//setIconTextGap(0);
setLocation(10,10);
}
}
Now I have following questions :-
1)When i set the layout to null setLayout(null) in my main class ThemeComponents then why the frame size shrinks to null with only title bar ?I expected it to take the size of CustomPanel as i have used pack() for the frame.(using layouts such as flowlayout , borderlayout however produces correct output)
2)Is using getPreferredSize() better for setting the size of component instead of setPreferredSize().Actually i don’t find any difference between them.
If you use
null-layout, preferred size will return (0,0) and hence you will only see the title bar.pack()validates yourJFrameand then sets the size of theJFrameto the preferred size of the content pane (which is 0,0) and add the required space for the title bar, menus, etc…Most likely you should avoid calling
setPreferredSize()and rather overridegetPreferredSize(). CallingsetPreferredSize()leaves the possibility to others to modify that value. In such situation it probably means that the preferred size is not an intrinsic part of your component and therefore you should not need to callsetPreferredSize(). While overridinggetPreferredSize()gives you full control and results in the preferred size being an intrinsic part of your component.You should also call
super.paintComponent(g);in your CustomPanel.In your
CustomLabel, it does not make any sense to callsetLocation(the parent layout will change that anyway)In your
CustomLabel, this does not make any sense either:setSize(img.getIconWidth(),getHeight());since the parent layout will change those values anyway (and btw,getHeight()returns 0 in this case)