Problems with adding JPanel into JLayer

409 views Asked by At

I am currently working on a Java Swing application. I want to use a JLayer to decorate a JPanel but get stuck.

Now I am going to add a JTextArea into a JPanel and then add the JPanel into a JLayer, and finally into a JScrollPane. A JPanel is a must because I want to add extra component beside the JTextArea (The JTextArea will be added to BorderLayout.CENTER and the custom component, BorderLayout.LINE_START). The problem is that JPanel does not expand automatically but shrinks to (0, 0) size.

I have thought of some workarounds but they aren't quite suitable.

(1) Add a JScrollPane into to the JLayer and add the JLayer into the top-level container directly. However the JLayer also covers the JScrollPane while I only want it to cover the JTextArea.

(2) Avoid using a JPanel and look for other ways to add a custom component beside the JTextArea, but I couldn't think of any simple way to achieve it.

Here is the code:

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;

public class Test
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                //add JLayer
                JTextArea textArea = new JTextArea("JTextArea blah blah blah");
                JPanel panel = new JPanel(new BorderLayout());
                panel.setBackground(Color.RED);
                panel.add(textArea, BorderLayout.CENTER);
                JLayer<JPanel> layer = new JLayer<JPanel>(panel, new LayerUI<JPanel>());
                frame.add(new JScrollPane(layer), BorderLayout.CENTER);
                //setup frame and show
                frame.setSize(250,250);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

result:

enter image description here

My workaround (1):

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;

public class Test
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                //add JLayer
                JTextArea textArea = new JTextArea("JTextArea blah blah blah");
                JPanel panel = new JPanel(new BorderLayout());
                panel.setBackground(Color.RED);
                panel.add(textArea, BorderLayout.CENTER);
                JLayer<JScrollPane> layer = new JLayer<JScrollPane>(new JScrollPane(panel), new LayerUI<JScrollPane>());
                frame.add(layer, BorderLayout.CENTER);
                //setup frame and show
                frame.setSize(250,250);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

This seems to work but the JLayer painting will cover the JScrollPane's scroll bar which is not preferred.

(Example of covering the JScrollPane: subclass LayerUI:)

new LayerUI<JScrollPane>()
{
      @Override
      public void paint(Graphics g, JComponent c)
      {
            super.paint(g,c);
            g.setColor(new Color(255,0,0,50));
            g.fillRect(0,0,c.getWidth(),c.getHeight());
      }
}

on scrolling (JScrollPane covered by JLayer):

enter image description here

So how to achieve a correct result? Thanks for solutions in advance.

0

There are 0 answers