두 노드 사이에 가장자리가있는 경우에만 각 노드 그래픽 개체에서 다른 노드 그래픽 개체로 선을 그리려고합니다.
내 그래프는 2 차원 부울 인접 행렬 내부에서 구현됩니다.
어떻게 구현할까요?
지금까지 내가 가진 것은 다음과 같습니다.
// Draw method which will draw the shape of the graph.
public void paint(Graphics g) {
//Define parameters to draw the graph in. Example taken from
//http://www.zetcode.com/gfx/java2d/basicdrawing/
Dimension size = getSize();
Insets insets = getInsets();
int w = size.width - insets.left - insets.right;
int h = size.height - insets.top - insets.bottom;
//Parameters for vertices, to be used later to draw vertices.
int x = 0;
int y = 0;
// Extend to Graphics 2D
Graphics2D graph = (Graphics2D) g;
// Set preferences. This cleans up edges.
graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//Generate vertices as random points on JPanel.
Random r = new Random();
//Draw random points on JPanel for the vertices.
for (int l = 0; l < adj_Matrix_Edges.length; l++){
String str = Integer.toHexString(l);
//Define where a specific vertex will fall on a x, y coordinate
//inside the container.
x = Math.abs(r.nextInt()) % w;
y = Math.abs(r.nextInt()) % h;
//Initialize a node graphics object to represent vertices.
Graphics2D node = (Graphics2D)g;
node.fillOval(x, y, 7, 7); //Creates filled ovals for nodes.
graph.drawString(str, x, y + 20);
}
//Create a nexted for loop to see if there is an edge between vertices.
for (int m = 0; m < adj_Matrix_Edges.length; m++){
for (int n = 0; m < adj_Matrix_Edges[m].length; m++){
if (adj_Matrix_Edges[m][n]){
graph.drawLine(node, y1, x2, y2);
}
}
}
}
}
MadProgrammer가 이미 언급했듯이 상속 된 클래스의 그리기 프로세스 JComponent
는 일반적으로 paintComponent
메서드 에서 수행됩니다 .
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)g;
// Your drawing stuff goes here....
}
그러나 실제 질문과 관련하여 : 그래프 (또는 더 정확하게는 노드 링크 다이어그램)를 그리고 싶다고 가정합니다. 이 작업을위한 많은 정교한 라이브러리가 있습니다. 그리고 가장 간단한 응용 프로그램을 제외하고 는 이러한 라이브러리를 사용 하는 것이 좋습니다. 수동으로 수행하는 것이 다소 까다로울 수 있기 때문입니다.
그러나 현재 주요 문제는 구성 요소를 다시 칠할 때마다 새로운 임의의 점을 생성한다는 것입니다! 어떻게 생겼는지 궁금합니다. 구성 요소의 크기를 조정할 때 이상하게 깜박이는 점이 표시되어야합니다.
나중에이 점들 사이에 선을 그릴 수 있도록 점 (좌표)을 어떻게 든 저장해야합니다.
코드를 거의 수정하지 않으면이 작업을 수행 할 수 있습니다.
//Generate vertices as random points on JPanel.
// Pass "0" as the argument to the constructor of Random, so that it
// will always create the same sequence of random numbers
Random r = new Random(0);
// Create lists that will store the point coordinates
List<Integer> pointsX = new ArrayList<Integer>();
List<Integer> pointsY = new ArrayList<Integer>();
for (int l = 0; l < adj_Matrix_Edges.length; l++){
String str = Integer.toHexString(l);
//Define where a specific vertex will fall on a x, y coordinate
//inside the container.
x = Math.abs(r.nextInt()) % w;
y = Math.abs(r.nextInt()) % h;
// Store the coordinates of the points:
pointsX.add(x);
pointsY.add(y);
//Initialize a node graphics object to represent vertices.
Graphics2D node = (Graphics2D)g;
node.fillOval(x, y, 7, 7); //Creates filled ovals for nodes.
graph.drawString(str, x, y + 20);
}
//Create a nexted for loop to see if there is an edge between vertices.
for (int m = 0; m < adj_Matrix_Edges.length; m++){
for (int n = 0; m < adj_Matrix_Edges[m].length; m++){
if (adj_Matrix_Edges[m][n]){
// Fetch the coordinates of the points from the list
int xm = pointsX.get(m);
int ym = pointsY.get(m);
int xn = pointsX.get(n);
int yn = pointsY.get(n);
graph.drawLine(xm,ym,xn,yn);
}
}
}
하지만 이렇게하는 것은 권장 하지 않습니다 . 이는 코드를 최소한으로 수정하여 이것이 어떻게 달성 될 수 있는지 보여주는 간단한 방법입니다. 일반적으로, 당신은해야 하지 페인팅 동안 데이터 구조를 구축 할 수 있습니다. 페인팅 코드는 최대한 짧고 간단해야합니다.
대신 인접 행렬을 초기화 할 때 노드를 나타내는 데이터 구조를 만들어야합니다. 적어도 다음과 같은 클래스를 만들 수 있습니다.
class Node
{
String name;
// Coordinates, between 0 and 1
double x;
double y;
}
그리고 adj_Matrix_Edges
가 선언되고 초기화 되는 곳에서 다음 과 같이 노드 목록을 만들 수도 있습니다.
boolean adj_Matrix_Edges[][];
List<Node> nodes;
void initializeMatrix()
{
adj_Matrix_Edges = ...;
// Create the nodes
Random random = new Random(0);
nodes= new ArrayList<Node>();
for (int m = 0; m < adj_Matrix_Edges.length; m++)
{
Node node= new Node();
node.name = Integer.toHexString(m);
node.x = random.nextDouble();
node.y = random.nextDouble();
nodes.add(node);
}
}
나중에 페인트 할 때 이러한 노드에 액세스하여 직접 페인트 할 수 있습니다.
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)g;
for (int l = 0; l < adj_Matrix_Edges.length; l++){
// Compute the x- and y-coordinates that the
// node will have in this component. (That's
// why the coordinates that are stored in
// the "Node" class should always be
// between 0 and 1!)
Node node = nodes.get(l);
int ix = (int)(node.x * getWidth());
int iy = (int)(node.y * getHeight());
g.fillOval(ix, iy, 7, 7);
graph.drawString(node.name, ix, iy + 20);
}
//Create a nested for loop to see if there is an edge between vertices.
for (int m = 0; m < adj_Matrix_Edges.length; m++){
for (int n = 0; m < adj_Matrix_Edges[m].length; m++){
if (adj_Matrix_Edges[m][n]){
Node nodeM = nodes.get(m);
Node nodeN = nodes.get(n);
int xm = (int)(nodeM.x * getWidth());
int ym = (int)(nodeM.y * getHeight());
int xn = (int)(nodeN.x * getWidth());
int yn = (int)(nodeN.y * getHeight());
graph.drawLine(xm,ym,xn,yn);
}
}
}
}
일반적으로 위에서 스케치 한 클래스 와 유사한 가장자리도 표시 Node
되지만 JUNG http://jung.sourceforge.net/ 또는 JGraphX 와 같은 라이브러리를 사용하는 것을 정당화하는 복잡성에 천천히 접근하고 있습니다. https://github.com/jgraph/jgraphx (많은 그래프 라이브러리가 있으며 이들은 아마도 가장 인기있는 두 가지 라이브러리이지만 여기에서는 예제로만 고려되어야합니다)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다