Zar
Zar

Reputation: 6882

Adding a JPanel with fixed size above a JLayer

Following Oracle's Myopia guide, I have a simple JPanel which is added to a JFrame as a JLayer. Simple enough, this blurs the JPanel's components. However, I'm trying to add a second JPanel above this JPanel (meaning that it won't get blurred).

Simple JPanel along with Main-method:

public class ContentPanel extends JPanel {

    public ContentPanel() {
        setLayout(new BorderLayout());
        add(new JLabel("Hello world, this is blurry!"), BorderLayout.NORTH);
        add(new JLabel("Hello world, this is blurry!"), BorderLayout.CENTER);
        add(new JButton("Blurry button"), BorderLayout.SOUTH);
    }

    public static void main(String[] args) {

        JFrame f = new JFrame("Foo");
        f.setSize(300, 200);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);

        LayerUI<JComponent> layerUI = new BlurLayerUI();
        JPanel panel = new ContentPanel();
        JLayer<JComponent> jlayer = new JLayer<JComponent>(panel, layerUI);

        f.add(jlayer);
        f.setVisible(true);
    }

}

BlurLayerUI which blurs its "children":

class BlurLayerUI extends LayerUI<JComponent> {
    private BufferedImage mOffscreenImage;
    private BufferedImageOp mOperation;

    public BlurLayerUI() {
        float ninth = 1.0f / 9.0f;
        float[] blurKernel = { ninth, ninth, ninth, ninth, ninth, ninth, ninth,
                ninth, ninth };
        mOperation = new ConvolveOp(new Kernel(3, 3, blurKernel),
                ConvolveOp.EDGE_NO_OP, null);

    }

    @Override
    public void paint(Graphics g, JComponent c) {
        int w = c.getWidth();
        int h = c.getHeight();

        if (w == 0 || h == 0) {
            return;
        }

        // Only create the offscreen image if the one we have
        // is the wrong size.
        if (mOffscreenImage == null || mOffscreenImage.getWidth() != w
                || mOffscreenImage.getHeight() != h) {
            mOffscreenImage = new BufferedImage(w, h,
                    BufferedImage.TYPE_INT_RGB);
        }

        Graphics2D ig2 = mOffscreenImage.createGraphics();
        ig2.setClip(g.getClip());
        super.paint(ig2, c);
        ig2.dispose();

        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(mOffscreenImage, mOperation, 0, 0);
    }
}

This will produce the following:

enter image description here

I've tried to simply add the second JPanel to the JFrame after the first, this only results in that the second panel takes up all the space. Using various layout-managers and set-Maximum/Preferred-size() methods won't do any good. Nor will making the second panels background transparent.

How can I add add a JPanel with fixed size above a JLayer, thus allowing part of the first panel to appear (still blurry)?

Upvotes: 2

Views: 733

Answers (1)

Eric Hydrick
Eric Hydrick

Reputation: 3527

Going by your comment that you want to blur data while you have a loading image, I would recommend a dialog. You can put your unblurred panel on the dialog, turn off it's frame and title bar with setUndecorated(true), and set it's default close behavior to DO_NOTHING_ON_CLOSE to prevent the user from closing the dialog before the application is loaded. This would sit on top of your blurred panels, but since it's not part of the BlurLayerUI, it wouldn't be blurred.

Upvotes: 1

Related Questions