我很困惑。您从扩展了类
JDesktop,但随后将其添加到
JLayedPane…
JDesktop扩展中。
默认情况下,如果没有布局管理器,
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(); } } }Now with dragging
请记住,鼠标事件是相对于MouseListener已注册组件的事件。也就是说,如果您将登记MosueListener到中的任何
组件JLayeredPane,则鼠标事件将转换为相对于那里的坐标空间。这会使生活有些混乱。
本示例进行了两个重大更改。
它增加了一个Mouse/MotionListener到JLayeredPane。然后,该侦听器负责确定被单击的内容并管理流程
将的“设置”代码linkPane移至updatelinks方法。在linkPane随后注册了一个ComponentListener在每次被链接到面板,并更新链接时出现的位置或大小的变化…
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(); }}}



