Asked  7 Months ago    Answers:  5   Viewed   21 times

I have a subclass of JLabel that forms a component of my GUI. I have implemented the ability to drag and drop the component from one container to another, but without any visual effects. I want to have this JLabel follow the cursor during the drag of the item from one container to another. I figured that I could just create a glass pane and draw it on there. However, even after I add the component to the glass pane, set the component visible, and set the glass pane visible, and set the glass pane as opaque, I still so not see the component. I know the component works because I can add it to the content pane and have it show up.

How do I add a component to the glass pane?


Finally figured how to get the simple example working. Thanks, @akf. I was able to adapt this solution to my original problem, allowing me to remove ~60 lines of Java2D code that manually rendered a representation of the JLabel.

package test;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class MainFrame extends JFrame {

    /**
     * @param args
     */
    public static void main(String[] args) {
        MainFrame mf = new MainFrame();
        mf.setSize(400, 400);
        mf.setLocationRelativeTo(null);
        mf.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        mf.setGlassPane(new JPanel());

        JLabel l = new JLabel();
        l.setText("Hello");
        l.setBorder(new LineBorder(Color.BLACK, 1));
        l.setBounds(10, 10, 50, 20);
        l.setBackground(Color.RED);
        l.setOpaque(true);
        l.setPreferredSize(l.getSize());

        //mf.add(l);
        ((JPanel)mf.getGlassPane()).add(l);
        mf.getGlassPane().setVisible(true);

        mf.setVisible(true);
    }
}

 Answers

78

Besides the pointers to the LayerPane examples already provided, the issue with your original code centers around the setting of the preferred size of your label. You set it before the JLabel has been sized, so your:

l.setPreferredSize(l.getSize());

is ineffectual. If, on the other hand, you make that call after you make your call to setBounds, you will see your desired results. With that in mind, reorder this:

l.setPreferredSize(l.getSize());
l.setBounds(10, 10, 50, 20);

to look like this:

l.setBounds(10, 10, 50, 20);
l.setPreferredSize(l.getSize());
Tuesday, June 1, 2021
 
Freddie
answered 7 Months ago
19

There are a couple of problems here.

The first obvious thing is that you appear to be using mutable statics. This is a really bad idea and indicates (and causes!) confusion. In this particular case, one of the problems caused is that the flasher static is shared.

Flash flash = new Flash();                      //set up timer
tmr = new javax.swing.Timer(1000, new Flash());
tmr.addActionListener(flash);

We are adding two Flash actions. Ordinarily this would be bad, but just produce an undetectable "bug". The colour would be set twice.

Bring these two things together, and we have two actions without a break that perform the same toggle. Two toggles. The state does not change (although there are repaint, property change events, etc.).

So, don't use mutable statics, and keep the code clean.

Friday, June 4, 2021
 
Nate
answered 6 Months ago
80

It is currently not possible to trigger contextual voice commands without the "ok glass" cue: the main reasons are to prevent false positive and narrow down the window when the microphone is listening for commands.

Saturday, August 7, 2021
 
MassiveAttack
answered 4 Months ago
84

How to Create Translucent and Shaped Windows

Friday, October 1, 2021
 
Kaiser Advisor
answered 2 Months ago
100

Well. I figure out how to do it.

Although I spend more than 5 hours to understand all things behind, but the solution is very simple.

Just overwrite 'public boolean contains(int x, int y)' method of glass panel.

public static void main(String[] args)
{
    final JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setSize(800, 600);

    final JSplitPane panel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JPanel(), new JPanel());

    frame.getContentPane().add(panel, BorderLayout.CENTER);

    final JPanel glassPane = new JPanel(){
        @Override
        public boolean contains(int x, int y)
        {
            Component[] components = getComponents();
            for(int i = 0; i < components.length; i++)
            {
                Component component = components[i];
                Point containerPoint = SwingUtilities.convertPoint(
                    this,
                    x, y,
                    component);
                if(component.contains(containerPoint))
                {
                    return true;
                }
            }
            return false;
        }
    };
    glassPane.setOpaque(false);
    JButton button = new JButton("haha");
    button.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            System.out.println("haha");
        }
    });
    glassPane.add(button);
    glassPane.setBorder(BorderFactory.createLineBorder(Color.red));
    frame.setGlassPane(glassPane);

    //try to comment out this line to see the difference.
    glassPane.setVisible(true);

    frame.setVisible(true);
}
Tuesday, November 9, 2021
 
Jubair
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share