CubicCurve2D connecting two JInternalFrame instances

限于喜欢 提交于 2019-11-26 07:45:13

问题


I have been trying to find a way (in Swing) to connect two JInternalFrames with a CubicCurve2D (otherwise known as a cubic bezier curve). The overall effect I\'m trying to achive is an interface similar to Yahoo! Pipes (the curve should go from the bottom of one internal frame to the top of the other).

Has anybody here done this before? The issue I am running into is that I cannot figure how to draw an updating curve in a way which is visible to the user. Drawing to and then repainting JDesktopPane.getGraphics doesn\'t seem to do anything.

If possible, I would like to use an offscreen buffer.


回答1:


Yes. Here's an example using drawLine(int x1, int y1, int x2, int y2), but invoking draw(Shape s) on your curve is a straightforward extension. You may have to expand the ComponentAdapter to handle resize events, too.

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;

/** @see http://stackoverflow.com/questions/3951383 */
public class JDPTest extends JDesktopPane {

    private static final Stroke s = new BasicStroke(4.0f);
    private MyFrame one = new MyFrame("One", 100, 100);
    private MyFrame two = new MyFrame("Two", 400, 240);

    public JDPTest() {
        this.setPreferredSize(new Dimension(640, 480));
        this.add(one);
        this.add(two);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.lightGray);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        g2d.setColor(Color.blue);
        g2d.setStroke(s);
        int x1 = one.getX() + one.getWidth() / 2;
        int y1 = one.getY() + one.getHeight() / 2;
        int x2 = two.getX() + two.getWidth() / 2;
        int y2 = two.getY() + two.getHeight() / 2;
        g2d.drawLine(x1, y1, x2, y2);
    }

    private final class MyFrame extends JInternalFrame {

        MyFrame(String name, int x, int y) {
            super(name);
            this.setSize(160, 100);
            this.setLocation(x, y);
            this.setVisible(true);
            this.addComponentListener(new ComponentAdapter() {

                @Override
                public void componentMoved(ComponentEvent e) {
                    JDPTest.this.repaint();
                }
            });
        }
    }

    private void display() {
        JFrame f = new JFrame("JDPTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JDPTest().display();
            }
        });
    }
}



回答2:


Try this. I just modified the code given above.

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.geom.CubicCurve2D;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;

/** @see http://stackoverflow.com/questions/3951383 */
public class JDPTest extends JDesktopPane {

    private static final Stroke s = new BasicStroke(4.0f);
    private MyFrame one = new MyFrame("One", 100, 100);
    private MyFrame two = new MyFrame("Two", 400, 240);
    CubicCurve2D cubcurve;
    public JDPTest() {
        this.setPreferredSize(new Dimension(640, 480));
        this.add(one);
        this.add(two);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.lightGray);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        g2d.setColor(Color.blue);
        g2d.setStroke(s);
        int x1 = one.getX() + one.getWidth() / 2;
        int y1 = one.getY() + one.getHeight() / 2;
        int x2 = two.getX() + two.getWidth() / 2;
        int y2 = two.getY() + two.getHeight() / 2;

        cubcurve = new CubicCurve2D.Float(x1,y1,x1+200,y1-115,x2-200,y2+115,x2,y2);
        g2d.draw(cubcurve);

       // g2d.drawLine(x1, y1, x2, y2);
    }

    private final class MyFrame extends JInternalFrame {

        MyFrame(String name, int x, int y) {
            super(name);
            this.setSize(160, 100);
            this.setLocation(x, y);
            this.setVisible(true);
            this.addComponentListener(new ComponentAdapter() {

                @Override
                public void componentMoved(ComponentEvent e) {
                    JDPTest.this.repaint();
                }
            });
        }
    }

    private void display() {
        JFrame f = new JFrame("JDPTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {


            public void run() {
                new JDPTest().display();
            }
        });
    }
}


来源:https://stackoverflow.com/questions/3951383/cubiccurve2d-connecting-two-jinternalframe-instances

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!