Draw Connecting Lines Between Swing Components

Hi all,

I'm writing a program to export data from one database to another one and I would like to provide a gui such as.:

- - - - - - - - - -- - - - - - - - - -

| column_01 | - - - - - - - | dest_01 |

- - - - - - - - - -- - - - - - - - - -

| column_02 || dest_02 |

- - - - - - - - - -- - - - - - - - - -

Could someone point me on how to resolve questions below ?

Q1. How can I write a line connecting two swing components ?

Q2. These swing components are inside of a scrolled component, How to keep track of the lines position ?

Thank you very much

Marcos

[634 byte] By [marcossofta] at [2007-10-2 21:50:13]
# 1

what kind of swing components are they? and is the scrolling of each synchronized?

i.e. when one column scrolls, does the other as well? will the lines ALWAYS be horizontal?

if so, it may be worth while to create a customized compound component. For example, make each row of this GUI a component that uses the border layout to put the column_0x in the west location, the dest_0x in the east location, and in the center location, put a customized component in which you override the paintComponent method to g.drawLine(0, height / 2, width, height / 2).

that should do the trick for you. If you don't know how to create custom swing components, let me know, and I can help you out.

- Adam

guitar_man_Fa at 2007-7-14 1:06:00 > top of Java-index,Security,Cryptography...
# 2

How can I write a line connecting two swing components ?

One way is to draw the line on the parent container.

These swing components are inside of a scrolled component, How to keep track of the lines position ?

Let the components keep track of things.

import java.awt.*;

import java.awt.geom.*;

import java.text.NumberFormat;

import javax.swing.*;

public class ConnectingLine

{

NumberFormat nf;

public ConnectingLine()

{

nf = NumberFormat.getInstance();

nf.setMinimumIntegerDigits(2);

}

private JPanel getContent()

{

JPanel panel = new JPanel(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.insets = new Insets(20,0,20,0);

gbc.weightx = 1.0;

gbc.fill = GridBagConstraints.HORIZONTAL;

gbc.gridwidth = GridBagConstraints.REMAINDER;

for(int j = 0, k = 1; j < 5; j++, k+=2)

panel.add(getPanel(k), gbc);

return panel;

}

private JPanel getPanel(int n)

{

ConnectingPanel panel = new ConnectingPanel();

panel.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.insets = new Insets(5,5,5,5);

gbc.weightx = 1.0;

panel.add(getChild("column_", n), gbc);

panel.add(getChild("dest_", n), gbc);

return panel;

}

private JPanel getChild(String s, int n)

{

JPanel panel = new JPanel(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.weightx = 1.0;

gbc.weighty = 1.0;

gbc.fill = GridBagConstraints.BOTH;

gbc.gridwidth = GridBagConstraints.REMAINDER;

panel.setOpaque(false); // no tricks

panel.setPreferredSize(new Dimension(125, 75));

panel.setBorder(BorderFactory.createEtchedBorder());

panel.add(new JLabel(s + nf.format(n), JLabel.CENTER), gbc);

gbc.weighty = 0.0;

panel.add(new JSeparator(), gbc);

gbc.weighty = 1.0;

panel.add(new JLabel(s + nf.format(n+1), JLabel.CENTER), gbc);

return panel;

}

public static void main(String[] args)

{

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setContentPane(new JScrollPane(new ConnectingLine().getContent()));

f.setSize(500,400);

f.setLocation(200,200);

f.setVisible(true);

}

}

class ConnectingPanel extends JPanel

{

final int HI = 0;// top JLabel

// JSeparator is middle component

final int LO = 2;// bottom JLabel

protected void paintComponent(Graphics g)

{

super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.setPaint(Color.blue);

Component[] c = getComponents();

for(int j = 0; j < c.length; j++)

{

for(int k = j+1; k < c.length; k++)

{

Point p1 = //getPointForParent(c[j], c[k]);

getPointForChild(c[j], c[k], HI);

Point p2 = //getPointForParent(c[k], c[j]);

getPointForChild(c[k], c[j], HI);

g2.draw(new Line2D.Double(p1, p2));

}

}

}

/** middle of parent JPanel that contains the two JLabels */

private Point getPointForParent(Component c1, Component c2)

{

Rectangle r1 = c1.getBounds();

Rectangle r2 = c2.getBounds();

Point p = new Point();

int outcode = r1.outcode(r2.getCenterX(), r2.getCenterY());

switch(outcode)

{

case Rectangle2D.OUT_TOP:

break;

case Rectangle2D.OUT_LEFT:

p.x = r1.x;

p.y = r1.y + r1.height/2 -1;

break;

case Rectangle2D.OUT_BOTTOM:

break;

case Rectangle2D.OUT_RIGHT:

p.x = r1.x + r1.width -1;

p.y = r1.y + r1.height/2 -1;

break;

default:

System.out.println("outcode for center or corners " + outcode);

}

return p;

}

/** center of top (or bottom) JLabel - as shown in ascii art above */

private Point getPointForChild(Component c1, Component c2, int index)

{

Rectangle r1 = c1.getBounds();

Point cp = getCenter(c1, index);

Rectangle r2 = c2.getBounds();

Point p = new Point();

int outcode = r1.outcode(r2.getCenterX(), r2.getCenterY());

switch(outcode)

{

case Rectangle2D.OUT_TOP:

break;

case Rectangle2D.OUT_LEFT:

p.x = r1.x;

p.y = cp.y;

break;

case Rectangle2D.OUT_BOTTOM:

break;

case Rectangle2D.OUT_RIGHT:

p.x = r1.x + r1.width -1;

p.y = cp.y;

break;

default:

System.out.println("outcode for center or corners " + outcode);

}

return p;

}

private Point getCenter(Component parent, int childIndex)

{

Component child = ((Container)parent).getComponent(childIndex);

Rectangle r = child.getBounds();

Rectangle parentBounds = parent.getBounds();

Point p = new Point();

p.x = parentBounds.width/2;

p.y = parentBounds.y + r.y + r.height/2;

return p;

}

}

74philipa at 2007-7-14 1:06:00 > top of Java-index,Security,Cryptography...