|JAVA|画一棵树,JPanel repaint() 不起作用
|JAVA| Draw a Tree, JPanel repaint() does not work
我想画一棵树,但是repaint函数没有调用paintComponent函数。
我将每个节点保存在一个数组中。
我的主要class:
public class Main {
public static void main(String[] args) {
GUI g = new GUI();
g.setVisible(true);
}
}
我的 GUI class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI extends JFrame {
private JPanel cp;
private Node[] tree;
private displayTree dtree = new displayTree();
public GUI() {
this.setTitle("Tree");
this.setSize(900, 700);
this.setLocation(300, 100);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cp = (JPanel) this.getContentPane();
cp.setLayout(null);
cp.setBackground(Color.WHITE);
Node a = new Node("+");
Node b = new Node("3");
Node c = new Node("x");
a.left = b;
a.right = c;
tree = new Node[3];
tree[0] = a;
tree[1] = b;
tree[2] = c;
System.out.print(tree[0].data);
System.out.print(tree[0].left.data);
System.out.print(tree[0].right.data);
// Nothing like that works
dtree.revalidate();
dtree.repaint();
this.repaint();
System.out.print("a");
}
class displayTree extends JPanel {
private int radius = 25;
private int padding = 70;
@Override
public void paintComponent(Graphics g) {
// Should be displayed but doesn't
System.out.print("It works");
super.paintComponent(g);
displayTree(g, tree[0], getWidth() / 2, 30, getWidth() / 4);
}
private void displayTree(Graphics g, Knoten k, int x, int y, int tempPadding) {
g.drawOval(x - radius, y - radius, 2 * radius, 2 * radius);
g.drawString(k.data, x - 6, y + 4);
if (k.left != null) {
displayNode(g, x - tempPadding, y + padding, x, y);
displayTree(g, k.left, x - tempPadding, y + padding, tempPadding / 2);
}
if (k.right != null) {
displayNode(g, x + tempPadding, y + padding, x, y);
displayTree(g, k.right, x + tempPadding, y + padding, tempPadding / 2);
}
}
private void displayNode(Graphics g, int x1, int y1, int x2, int y2) {
double d = Math.sqrt(padding * padding + (x2 - x1) * (x2 - x1));
int x11 = (int) (x1 - radius * (x1 - x2) / d);
int y11 = (int) (y1 - radius * (y1 - y2) / d);
int x21 = (int) (x2 + radius * (x1 - x2) / d);
int y21 = (int) (y2 + radius * (y1 - y2) / d);
g.drawLine(x11, y11, x21, y21);
}
}
}
节点 class 是这样的:
import javax.swing.JPanel;
public class Node extends JPanel {
String data;
Knoten left;
Knoten right;
public Node(String data) {
this.data = data;
}
}
你能帮帮我吗?
我如何绘制节点?
两件事:
您没有将 dtree
添加到内容窗格,而是将内容窗格的布局设置为 null,这对您的情况毫无用处。
public GUI() {
this.setTitle("Tree");
this.setSize(900, 700);
this.setLocation(300, 100);
this.setResizable(false);
setBackground(Color.red);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cp = (JPanel) this.getContentPane();
//REMOVE null layout.
//cp.setLayout(null);
cp.setBackground(Color.WHITE);
Node a = new Node("+");
Node b = new Node("3");
Node c = new Node("x");
a.left = b;
a.right = c;
tree = new Node[3];
tree[0] = a;
tree[1] = b;
tree[2] = c;
System.out.print(tree[0].data);
System.out.print(tree[0].left.data);
System.out.print(tree[0].right.data);
// No useless repaints/revalidates
//Add the tree to the content pane
cp.add(dtree);
System.out.print("a");
}
如果您确实需要(不,您不应该)在内容窗格上使用空布局,则必须调整树面板的大小:
[...]
// No useless repaints/revalidates
//Size the content pane, otherwise with null layout its size will be 0x0
dtree.setSize(900,700);
//Add the tree to the content pane
cp.add(dtree);
我想画一棵树,但是repaint函数没有调用paintComponent函数。 我将每个节点保存在一个数组中。
我的主要class:
public class Main {
public static void main(String[] args) {
GUI g = new GUI();
g.setVisible(true);
}
}
我的 GUI class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI extends JFrame {
private JPanel cp;
private Node[] tree;
private displayTree dtree = new displayTree();
public GUI() {
this.setTitle("Tree");
this.setSize(900, 700);
this.setLocation(300, 100);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cp = (JPanel) this.getContentPane();
cp.setLayout(null);
cp.setBackground(Color.WHITE);
Node a = new Node("+");
Node b = new Node("3");
Node c = new Node("x");
a.left = b;
a.right = c;
tree = new Node[3];
tree[0] = a;
tree[1] = b;
tree[2] = c;
System.out.print(tree[0].data);
System.out.print(tree[0].left.data);
System.out.print(tree[0].right.data);
// Nothing like that works
dtree.revalidate();
dtree.repaint();
this.repaint();
System.out.print("a");
}
class displayTree extends JPanel {
private int radius = 25;
private int padding = 70;
@Override
public void paintComponent(Graphics g) {
// Should be displayed but doesn't
System.out.print("It works");
super.paintComponent(g);
displayTree(g, tree[0], getWidth() / 2, 30, getWidth() / 4);
}
private void displayTree(Graphics g, Knoten k, int x, int y, int tempPadding) {
g.drawOval(x - radius, y - radius, 2 * radius, 2 * radius);
g.drawString(k.data, x - 6, y + 4);
if (k.left != null) {
displayNode(g, x - tempPadding, y + padding, x, y);
displayTree(g, k.left, x - tempPadding, y + padding, tempPadding / 2);
}
if (k.right != null) {
displayNode(g, x + tempPadding, y + padding, x, y);
displayTree(g, k.right, x + tempPadding, y + padding, tempPadding / 2);
}
}
private void displayNode(Graphics g, int x1, int y1, int x2, int y2) {
double d = Math.sqrt(padding * padding + (x2 - x1) * (x2 - x1));
int x11 = (int) (x1 - radius * (x1 - x2) / d);
int y11 = (int) (y1 - radius * (y1 - y2) / d);
int x21 = (int) (x2 + radius * (x1 - x2) / d);
int y21 = (int) (y2 + radius * (y1 - y2) / d);
g.drawLine(x11, y11, x21, y21);
}
}
}
节点 class 是这样的:
import javax.swing.JPanel;
public class Node extends JPanel {
String data;
Knoten left;
Knoten right;
public Node(String data) {
this.data = data;
}
}
你能帮帮我吗? 我如何绘制节点?
两件事:
您没有将 dtree
添加到内容窗格,而是将内容窗格的布局设置为 null,这对您的情况毫无用处。
public GUI() {
this.setTitle("Tree");
this.setSize(900, 700);
this.setLocation(300, 100);
this.setResizable(false);
setBackground(Color.red);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cp = (JPanel) this.getContentPane();
//REMOVE null layout.
//cp.setLayout(null);
cp.setBackground(Color.WHITE);
Node a = new Node("+");
Node b = new Node("3");
Node c = new Node("x");
a.left = b;
a.right = c;
tree = new Node[3];
tree[0] = a;
tree[1] = b;
tree[2] = c;
System.out.print(tree[0].data);
System.out.print(tree[0].left.data);
System.out.print(tree[0].right.data);
// No useless repaints/revalidates
//Add the tree to the content pane
cp.add(dtree);
System.out.print("a");
}
如果您确实需要(不,您不应该)在内容窗格上使用空布局,则必须调整树面板的大小:
[...]
// No useless repaints/revalidates
//Size the content pane, otherwise with null layout its size will be 0x0
dtree.setSize(900,700);
//Add the tree to the content pane
cp.add(dtree);