Reputation: 175
I'm trying to get clarification as to how borders work, specifically the insets, and in searching through the Java docs and numerous websites I can't seem to find a clear explanation. Looking at this code:
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class ShadowWindow {
public static void main(String[] args) {
new ShadowWindow();
}
public ShadowWindow() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new ShadowPane());
JPanel panel = new JPanel(new GridBagLayout());
panel.add(new JLabel("Look ma, no hands"));
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ShadowPane extends JPanel {
public ShadowPane() {
setLayout(new BorderLayout());
setOpaque(false);
setBackground(Color.BLACK);
setBorder(new EmptyBorder(0, 0, 10, 10));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fillRect(10, 10, getWidth(), getHeight());
g2d.dispose();
}
}
}
The way I interpret it this is what is happening:
So my question in how is the shadowPane going past the range of the JFrame? Does the border go 10 pixels outside the JFrame or does it exist inside the JFrame. From everything I've found it should be inside, but that doesn't make sense based on how this code generates a shadow behind the frame. can anybody walk me through this? Thanks.
Upvotes: 3
Views: 83
Reputation: 347194
So my question in how is the shadowPane going past the range of the JFrame?
It's not. pack
determines the preferred layout size of the content and makes the window big enough to accommodate it, because the frame is undercoated AND it's background is transparent, it "appears" as if the shadow hangs past the frame, it's an illusion.
The empty border is making sure that content added to the ShadowPane
is "forced" into a small space.
Lets change the code slightly...
JFrame frame = new JFrame("Testing");
JPanel content = new JPanel(new BorderLayout());
content.setBackground(Color.RED);
//frame.setUndecorated(true);
//frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(content);
//frame.setContentPane(new ShadowPane());
JPanel panel = new JPanel(new GridBagLayout());
panel.add(new JLabel("Look ma, no hands"));
ShadowPane shadowPane = new ShadowPane();
shadowPane.add(panel);
frame.add(shadowPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
What this does, is creates a new background panel, filled with the color red. It also adds the window decoration back in.
As you can see, the shadow pane and the label are are all rendered within the confines of the window.
If we once again remove the window decoration...
You can see that it's still the same...
So what's going on?
getPreferredSize
is providing the core information about how the component would like to be size (in this case 200x200
)
The EmptyBorder
is defining a usable space within the ShadowPane
which defines an area within which content can be displayed, it's leaving 10 pixels to the right and bottom of the component, in which components can't be displayed. This is take care of automatically by the layout manager. This means that the ShadowPane
can actually paint here itself, but components added to it will never be displayed here, hence the shadow board.
Basically, it's smoke and mirrors and used to generate the illusion of a drop shadow behind the content added to the frame (or the ShadowPane
in this case)
Upvotes: 5