Placing Component on Glass Pane

Placing component on Glass Pane

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());

How to set postion to a glass pane in a JFrame and JPanel

Ok. I'll try to give an answer even if you didn't post the whole relevant code.

I suppose "g" is the component you want to use like a GlassPane.
You don't have to add other Components to the glass pane itself, but instead construct your component hierarchy like you usually do without glasspane. Then add the glass pane to the frame with setGlassPane() method of JFrame.

Here's a nice tutorial.

Component for glass pane console-style text display

JLabel would be the easiest. Otherwise you will have to override paintComponent to do anything fancy like animating the text movement.

placing a transparent JPanel on top of another JPanel not working

Indeed, it would be useful to tell the reason why you want panels one over another.

Starting with your code, and changing it a lot, I got it to work, but it might not do what you expect...

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

public class Test extends JFrame
{
public Test()
{
super();

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 200);

onInit();

setVisible(true);
}
private void onInit()
{
JLayeredPane lp = getLayeredPane();

JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JTextArea(), BorderLayout.CENTER);
panel.add(new JButton("Submit"), BorderLayout.SOUTH);
panel.setSize(300, 150); // Size is needed here, as there is no layout in lp

JPanel glass = new JPanel();
glass.setOpaque(false); // Set to true to see it
glass.setBackground(Color.GREEN);
glass.setSize(300, 150);
glass.setLocation(10, 10);

lp.add(panel, Integer.valueOf(1));
lp.add(glass, Integer.valueOf(2));
}

public static void main(String args[])
{
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new Test();
}
});
}
}

If totally transparent, well, it is like it isn't here! When opaque, it just covers some of the GUI, but doesn't prevent mouse clicks, for example.

How to convert JGraph to a glass pane?

I think you're over complicating things.

The glass pane will be the top most component (when visible), painting over the top of everything else. If you simply want to "overlay" one component over another you there are much simpler solutions...

The simplest idea I can think off would be to use a JLayeredPane, setting it up to use a GridBagLayout so you don't need to worry about positioning the child components. This will give you quick and easy methods for changing the order of components.

Another solution would be to simply add the overlay component directly on top of the underlay component.

Sample Image

import java.awt.BasicStroke;
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.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Overlay {

public static void main(String[] args) {
new Overlay();
}

public Overlay() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

ImagePane imagePane = new ImagePane();
imagePane.setLayout(new BorderLayout());
imagePane.add(new OverlayPane());

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(imagePane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class OverlayPane extends JPanel {

public OverlayPane() {
setOpaque(false);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.setStroke(new BasicStroke(4));
int radius = 40;
g2d.drawOval(326 - radius / 2, 351 - radius / 2, radius, radius);
g2d.drawOval(416 - radius / 2, 351 - radius / 2, radius, radius);

int size = 20;

g2d.drawLine(374, 400, 374 - size, 400 + size);
g2d.drawLine(374, 400, 374 + size, 400 + size);

g2d.dispose();
}

}

public class ImagePane extends JPanel {

private BufferedImage buffer;

public ImagePane() {
try {
buffer = ImageIO.read(new File("/path/to/your/image"));
} catch (IOException ex) {
ex.printStackTrace();
}
}

@Override
public Dimension getPreferredSize() {
return buffer == null ? new Dimension(200, 200) : new Dimension(buffer.getWidth(), buffer.getHeight());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(buffer, 0, 0, this);
g2d.dispose();
}
}

}

Place components to the right of tabs in a JTabbedPane

I guess this is what you want:

GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.NORTHEAST;
panel.setPreferredSize(new Dimension(panel.getPreferredSize().width,
(int) tabBounds.getHeight()));
glassPane.add(panel, gbc);

How to force repaint of a glass pane?

As I think invalidate() only flags your component to check sizes and layout. You should call repaint() to repaint your pane.

Also I am wondering why you use propertyChangeListener for mouse clicks. I would prefer just simple mouse listener + MouseAdapter and MouseEvent x, y, buttons state.

Swing: GlassPane prevents mouse pointer from changing

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);
}

JFrame and GlassPane - Trouble with repaint()

The likely cause of your frustration is trying to set the glass pane visible (Swing components are visible by default), before setting it as the frames GlassPane.

The JFrame is likely resetting the glass pane to be invisible, meaning that it won't be painted (no point painting something that's not visible)

Try setting the glass pane visible AFTER you apply it to the frame



Related Topics



Leave a reply



Submit