我想在两个JPanel之间画线,但是line不会出现在layeredPane上。
这就是我所做的,请仔细阅读,编译。请尝试更正此代码。我尝试过这种方式在内部框架上绘制线条,但它不适用于JPanels。
package build;
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 java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
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 LinkLayerPane1 {
public static void main(String[] args) {
new LinkLayerPane1();
}
public LinkLayerPane1() {
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);
Point Red= new Point();
Red.x=red.getX()+(red.getWidth()/2);
Red.y=red.getY()-(red.getHeight()/2);
Point Blue= new Point();
Blue.x=blue.getX()+(blue.getWidth()/2);
Blue.y=blue.getY()-(blue.getHeight()/2);
handleDrag(red,Blue);
handleDrag(blue,Red);
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();
}
}
//Dragging
public static void handleDrag(final JPanel Tpanel,final Point to)
{
final JPanel p = Tpanel;
Tpanel.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent me) {
me.translatePoint(me.getComponent().getLocation().x, me.getComponent().getLocation().y);
//Handling Panel Dragging
p.setLocation(me.getX(), me.getY());
//Finding new point
Point p1 = Tpanel.getLocation();
Point p2=to;
Point startPoint = new Point();
Point endPoint = new Point();
Point from = new Point();
if (p1.x < p2.x) {
from.x = p1.x + (Tpanel.getWidth() / 2);
to.x = p2.x + (Tpanel.getWidth() / 2);
} else {
from.x = p2.x + (Tpanel.getWidth() / 2);
to.x = p1.x + (Tpanel.getWidth() / 2);
startPoint.x = p2.x;
}
if (p1.y < p2.y) {
from.y = p1.y + (Tpanel.getHeight()/ 2);
to.y = p2.y + (Tpanel.getHeight()/ 2);
} else {
from.y = p2.y + (Tpanel.getHeight()/ 2);
to.y = p1.y + (Tpanel.getHeight()/ 2);
}
int width = Math.max(1, to.x - from.x);
int height = Math.max(1, to.y - from.y);
if (p1.x < p2.x) {
startPoint.x = 0;
endPoint.x = Tpanel.getWidth();
} else {
startPoint.x = Tpanel.getWidth();
endPoint.x = 0;
}
if (p1.y < p2.y) {
startPoint.y = 0;
endPoint.y = Tpanel.getHeight();
} else {
startPoint.y = Tpanel.getHeight();
endPoint.y = 0;
}
}
});
}
}
答案 0 :(得分:3)
我很困惑。您将课程从JDesktop
扩展,但随后继续将其添加到JLayedPane
... JDesktop
范围。
默认情况下,如果没有布局管理器,JDesktopPane
将添加到JLayeredPane
,大小为0x0 ..
我不确定你希望通过这个实现目标。
使用示例更新
您面临的问题是paintComponent
将始终在组件下绘制,而理论上paint
将绘制组件,它可以从更新中排除(作为{{ 1}}可以指向需要更新的组件。
虽然我仍然认为使用玻璃窗格是最简单的解决方案,如演示here,您可以通过添加&#34; connect&#34;来简单地利用图层窗格。从一个点到另一个点绘制一条线的窗格,只需将其添加到RepaintManager
...
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();
}
}
}
注册的组件。也就是说,如果将MouseListener
注册到MosueListener
中的任何组件,鼠标事件将被转换为相对于那里的坐标空间。这会让生活变得有点混乱。
此示例进行了两项重大更改。
JLayeredPane
添加了Mouse/MotionListener
。然后,这个监听器处理找出点击的内容并管理流程移动&#34;设置&#34; JLayeredPane
到LinkPane
方法的代码。 updateLinks
然后向其链接的每个面板注册LinkPane
,并在位置或大小发生变化时更新链接...
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;
公共类LinkLayerPane {ComponentListener
}
答案 1 :(得分:2)
在我看来,就像你看到了trashgod的例子,并试图修改它。
如果您想像示例一样使用桌面窗格,请使用示例中的代码。不要试图混合使用JLayeredPane。
如果要使用JLayeredPane,请不要使用JDesktopPane对连接两个组件的线进行自定义绘制。桌面窗格是用于容纳其他组件的容器。如果您想进行自定义绘画,请使用更合适的组件。您可以覆盖任何组件的paintComponent()方法,因此在这种情况下,您可以在JComponent中进行自定义绘制。
在尝试使用JLayeredPane之前,请阅读How to Use Layered Panes上的Swing教程。您不只是将组件添加到分层窗格。您需要指定组件和Integer值。整数值用于确定分层的顺序。因此,如果要将3个组件添加到3个不同的层,则需要指定3个不同的整数。或者,您可能使用两个组件创建一个面板,然后使用第二个面板绘制线连接。