I want to draw line between two JPanels but line is not appearing on layeredPane.
This is what i have done please go through it, compilable.Do try and correct this c
It looks to me like you saw trashgod's example and are trying to modify it.
If you want to use a desktop pane like the example does, then use the code from the example. Don't try to mix in a JLayeredPane.
If you want to use a JLayeredPane, then don't use a JDesktopPane to do your custom painting of the line joining two components. A desktop pane is a container used to hold other components. If you want to do custom painting then use a more appropriate component. You can override the paintComponent() method of any component so in this case you could do your custom painting in a JComponent.
Before attempting to play with a JLayeredPane read the Swing tutorial on How to Use Layered Panes. You don't just add components to a layered pane. You need to specify the component and an Integer value. The integer value is used to determine the order of the layering. So if you want to add 3 components to 3 different layers then you need to specify 3 different integers. Or maybe you create a panel with your two components and then a second panel to draw the line connection.
I'm confused. You extend your class from JDesktop
, but then proceed to add it to a JLayedPane
...JDesktop
extends.
Without a layout manger by default, the JDesktopPane
will be added to the JLayeredPane
with a size of 0x0..
I'm not sure what you hoped to achieve by this.
Update with example
The problem(s) you are facing is that paintComponent
will always paint under the components, while paint
in theory will paint over the components, it can be excluded from updates (as the RepaintManager
can go direct the component that needs to be updated).
While I still think using the glass pane is the simplest solution, as demonstrated here, you could simply take advantage of the layer pane by adding a "connect" pane that draws a line from one point to another and simply add it to the LayeredPane
...
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.Point;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class LinkLayerPane {
public static void main(String[] args) {
new LinkLayerPane();
}
public LinkLayerPane() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JLayeredPane layer = new JLayeredPane();
JPanel red = new JPanel();
red.setBackground(Color.RED);
JPanel blue = new JPanel();
blue.setBackground(Color.BLUE);
red.setBounds(50, 50, 50, 50);
blue.setBounds(125, 125, 50, 50);
layer.add(red);
layer.add(blue);
layer.add(new LinkPane(red, blue), new Integer(JLayeredPane.DEFAULT_LAYER + 1));
layer.setPreferredSize(new Dimension(250, 250));
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(layer);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class LinkPane extends JPanel {
private Point startPoint;
private Point endPoint;
public LinkPane(JPanel panel1, JPanel panel2) {
setOpaque(false);
Point p1 = panel1.getLocation();
Point p2 = panel2.getLocation();
startPoint = new Point();
endPoint = new Point();
Point from = new Point();
Point to = new Point();
if (p1.x < p2.x) {
from.x = p1.x + (panel1.getWidth() / 2);
to.x = p2.x + (panel2.getWidth() / 2);
} else {
from.x = p2.x + (panel2.getWidth() / 2);
to.x = p1.x + (panel1.getWidth() / 2);
startPoint.x = p2.x;
}
if (p1.y < p2.y) {
from.y = p1.y + (panel1.getHeight()/ 2);
to.y = p2.y + (panel2.getHeight()/ 2);
} else {
from.y = p2.y + (panel2.getHeight()/ 2);
to.y = p1.y + (panel1.getHeight()/ 2);
}
int width = Math.max(1, to.x - from.x);
int height = Math.max(1, to.y - from.y);
setLocation(from);
setSize(width, height);
System.out.println(getBounds());
if (p1.x < p2.x) {
startPoint.x = 0;
endPoint.x = getWidth();
} else {
startPoint.x = getWidth();
endPoint.x = 0;
}
if (p1.y < p2.y) {
startPoint.y = 0;
endPoint.y = getHeight();
} else {
startPoint.y = getHeight();
endPoint.y = 0;
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
g2d.dispose();
}
}
}
Remember, mouse events a relative to the component that MouseListener
is registered to. That is, if you register the MosueListener
to any of the components within the JLayeredPane
, the mouse events will be translated to be relative to there coordinate space. This can make life a little confusing.
This example makes two significant changes.
Mouse/MotionListener
to the JLayeredPane
. This listener then deals with figuring out what was clicked and managing the processMoves the "setup" code for the LinkPane
to a updateLinks
method. The LinkPane
then registers a ComponentListener
to each of the panels it is linking to and updates the link when there position or size changes...
import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException;
public class LinkLayerPane {
public static void main(String[] args) {
new LinkLayerPane();
}
public LinkLayerPane() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JLayeredPane layer = new JLayeredPane();
JPanel red = new JPanel();
red.setBackground(Color.RED);
JPanel blue = new JPanel();
blue.setBackground(Color.BLUE);
red.setBounds(50, 50, 50, 50);
blue.setBounds(125, 125, 50, 50);
layer.add(red);
layer.add(blue);
layer.add(new LinkPane(red, blue), new Integer(JLayeredPane.DEFAULT_LAYER + 1));
layer.setPreferredSize(new Dimension(250, 250));
MouseAdapter ma = new MouseAdapter() {
private Point offset;
private Component dragComponent;
@Override
public void mousePressed(MouseEvent e) {
JLayeredPane layer = (JLayeredPane) e.getComponent();
dragComponent = layer.getComponentAt(e.getPoint());
if (dragComponent != null && !dragComponent.equals(layer) && !(dragComponent instanceof LinkPane)) {
offset = e.getPoint();
offset.x = dragComponent.getX() - offset.x;
offset.y = dragComponent.getY() - offset.y;
} else {
dragComponent = null;
}
}
@Override
public void mouseReleased(MouseEvent e) {
dragComponent = null;
offset = null;
}
@Override
public void mouseDragged(MouseEvent e) {
if (dragComponent != null) {
Point dragTo = e.getPoint();
dragTo.x += offset.x;
dragTo.y += offset.y;
dragComponent.setLocation(dragTo);
}
}
};
layer.addMouseListener(ma);
layer.addMouseMotionListener(ma);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(layer);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class LinkPane extends JPanel {
private Point startPoint;
private Point endPoint;
private JPanel[] links;
public LinkPane(JPanel panel1, JPanel panel2) {
setOpaque(false);
links = new JPanel[]{panel1, panel2};
ComponentAdapter ca = new ComponentAdapter() {
@Override
public void componentMoved(ComponentEvent e) {
updateLinks();
}
@Override
public void componentResized(ComponentEvent e) {
updateLinks();
}
};
links[0].addComponentListener(ca);
links[1].addComponentListener(ca);
updateLinks();
}
protected void updateLinks() {
Point p1 = links[0].getLocation();
Point p2 = links[1].getLocation();
startPoint = new Point();
endPoint = new Point();
Point from = new Point();
Point to = new Point();
if (p1.x < p2.x) {
from.x = p1.x + (links[0].getWidth() / 2);
to.x = p2.x + (links[1].getWidth() / 2);
} else {
from.x = p2.x + (links[1].getWidth() / 2);
to.x = p1.x + (links[0].getWidth() / 2);
startPoint.x = p2.x;
}
if (p1.y < p2.y) {
from.y = p1.y + (links[0].getHeight() / 2);
to.y = p2.y + (links[1].getHeight() / 2);
} else {
from.y = p2.y + (links[1].getHeight() / 2);
to.y = p1.y + (links[0].getHeight() / 2);
}
int width = Math.max(1, to.x - from.x);
int height = Math.max(1, to.y - from.y);
setLocation(from);
setSize(width, height);
System.out.println(getBounds());
if (p1.x < p2.x) {
startPoint.x = 0;
endPoint.x = getWidth();
} else {
startPoint.x = getWidth();
endPoint.x = 0;
}
if (p1.y < p2.y) {
startPoint.y = 0;
endPoint.y = getHeight();
} else {
startPoint.y = getHeight();
endPoint.y = 0;
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
g2d.dispose();
}
}
}