行没有出现在JDesktopPane上

时间:2013-05-18 22:19:25

标签: java swing graphics2d repaint jlayeredpane

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


       }

     });
     }    

}

2 个答案:

答案 0 :(得分:3)

我很困惑。您将课程从JDesktop扩展,但随后继续将其添加到JLayedPane ... JDesktop范围。

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

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

使用示例更新

您面临的问题是paintComponent将始终在组件下绘制,而理论上paint将绘制组件,它可以从更新中排除(作为{{ 1}}可以指向需要更新的组件。

虽然我仍然认为使用玻璃窗格是最简单的解决方案,如演示here,您可以通过添加&#34; connect&#34;来简单地利用图层窗格。从一个点到另一个点绘制一条线的窗格,只需将其添加到RepaintManager ...

enter image description here

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中的任何组件,鼠标事件将被转换为相对于那里的坐标空间。这会让生活变得有点混乱。

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

  1. 它向JLayeredPane添加了Mouse/MotionListener。然后,这个监听器处理找出点击的内容并管理流程
  2. 移动&#34;设置&#34; JLayeredPaneLinkPane方法的代码。 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个不同的整数。或者,您可能使用两个组件创建一个面板,然后使用第二个面板绘制线连接。