行没有出现在JDesktopPane上

我想在两个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; } } }); } } 

我很困惑。 您从JDesktop扩展您的类,但继续将其添加到JLayedPaneJDesktop extends。

默认情况下没有布局管理器, JDesktopPane将添加到JLayeredPane ,大小为0x0 ..

我不确定你希望通过这个实现目标。

以示例更新

您面临的问题是paintComponent将始终在组件下paint ,而理论上绘制将绘制组件,它可以从更新中排除(因为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注册到MosueListener中的任何组件,鼠标事件将被转换为相对于坐标空间。 这会让生活变得有点混乱。

此示例进行了两项重大更改。

  1. 它将一个Mouse/MotionListener添加到JLayeredPane 。 然后,该监听器处理确定点击的内容并管理该过程
  2. LinkPane的“设置”代码移动到updateLinks方法。 然后, LinkPaneComponentListener注册到它链接到的每个面板,并在位置或大小发生变化时更新链接...

    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 {

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

    }

它看起来像你看到trashgod的例子,并试图修改它。

如果要像示例那样使用桌面窗格,请使用示例中的代码。 不要试图混合使用JLayeredPane。

如果要使用JLayeredPane,则不要使用JDesktopPane对连接两个组件的线进行自定义绘制。 桌面窗格是用于容纳其他组件的容器。 如果您想进行自定义绘画,请使用更合适的组件。 您可以覆盖任何组件的paintComponent()方法,因此在这种情况下,您可以在JComponent中进行自定义绘制。

在尝试使用JLayeredPane之前,请阅读有关如何使用分层窗格的Swing教程。 您不只是将组件添加到分层窗格。 您需要指定组件和Integer值。 整数值用于确定分层的顺序。 因此,如果要将3个组件添加到3个不同的层,则需要指定3个不同的整数。 或者您可能使用两个组件创建面板,然后使用第二个面板绘制线连接。