0

我想在两个 JPanel 之间画线,但线没有出现在 layeredPane 上。

这就是我所做的,请通过它,可编译。请尝试并更正此代码。我曾尝试以这种方式在内部框架上绘制线条,但它不适用于 JPanel。

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


       }

     });
     }    

}
4

2 回答 2

3

我很困惑。您从 扩展您的类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();
        }        
    }    
}

现在拖动

请记住,鼠标事件相对于MouseListener注册到的组件。也就是说,如果您将 注册MosueListener到 中的任何组件JLayeredPane,鼠标事件将被转换为相对于那里的坐标空间。这会让生活变得有点混乱。

这个例子做了两个重要的改变。

  1. Mouse/MotionListenerJLayeredPane. 然后,此侦听器负责确定单击的内容并管理该过程
  2. 将 的“设置”代码移动LinkPaneupdateLinks方法。然后LinkPane将 a 注册ComponentListener到它链接到的每个面板,并在位置或大小发生变化时更新链接......

    导入 java.awt.BasicStroke;导入 java.awt.BorderLayout;导入 java.awt.Color;导入 java.awt.Component;导入 java.awt.Dimension;导入 java.awt.EventQueue;导入 java.awt.Graphics;导入 java.awt.Graphics2D;导入 java.awt.Point;导入 java.awt.event.ComponentAdapter;导入 java.awt.event.ComponentEvent;导入 java.awt.event.MouseAdapter;导入 java.awt.event.MouseEvent;导入 javax.swing.JFrame;导入 javax.swing.JLayeredPane;导入 javax.swing.JPanel;导入 javax.swing.UIManager;导入 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();
        }
    }
    

    }

于 2013-05-18T22:56:21.390 回答
2

在我看来,您好像看到了垃圾神的示例并正在尝试对其进行修改。

如果您想像示例一样使用桌面窗格,请使用示例中的代码。不要尝试混入 JLayeredPane。

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

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

于 2013-05-19T03:56:49.160 回答