This programming assignment has me stumped; the code is as follows:
import java.awt.*;
import javax.swing.*;
public class HTree extends JPanel {
private Color color = new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256));
public void draw(Graphics g, int n, double sz, double x, double y) {
if (n == 0) return;
double x0 = x - sz/2, x1 = x + sz/2;
double y0 = y - sz/2, y1 = y + sz/2;
// draw the 3 line segments of the H
g.setColor(color);
g.drawLine((int)x0, (int)y, (int)x1, (int)y);
g.drawLine((int)x0, (int)y0, (int)x0, (int)y1);
g.drawLine((int)x1, (int)y0, (int)x1, (int)y1);
// recursively draw 4 half-size
// H-trees of order n-1
g.setColor(color);
draw(g, n-1, sz/2, x0, y0);
draw(g, n-1, sz/2, x0, y1);
draw(g, n-1, sz/2, x1, y0);
draw(g, n-1, sz/2, x1, y1);
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g, 3, .5, .5, .5);
}
public static void main(String[] args) {
HTree h = new HTree();
JFrame application = new JFrame("HTree");
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(h);
application.setSize(1000, 1000);
application.setVisible(true);
}
}
It compiles correctly, but when running the program, all I get is an empty JFrame. I am not too familiar with Swing, but I think the problem is that either the HTree constructor is wrong, or I may need to call draw() in main—I'm not sure how to call it with a Graphics object. Any help is appreciated, Thank you!
Some observations:
Use integer coordinates relative to the panel's current size.
Override getPreferredSize() to establish the initial geometry.
Use Color.getHSBColor() to get bright, saturated colors; consider creating a gamut of hues, selecting a different one at each level, for example.
Construct and manipulate Swing GUI objects only on the event dispatch thread.
Consider using a JSpinner or JSlider to control recursion depth interactively, as suggested here and here.
Don't invoke repaint() recursively; use it to schedule a call to your implementation of paintComponent(), as when the recursion depth charges in response to some input.
Consider using setStroke() and rendering hints, as shown here.
Consider using a javax.swing.Timer, increasing the recursion depth by one level each time the ActionListener is called.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see https://stackoverflow.com/a/37450393/230513
*/
public class HTree {
private void display() {
JFrame f = new JFrame("HTree");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Tree());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class Tree extends JPanel {
private final Color color = Color.getHSBColor((float) Math.random(), 1, 1);
public void draw(Graphics g, int n, double sz, double x, double y) {
if (n == 0) {
return;
}
double x0 = x - sz / 2, x1 = x + sz / 2;
double y0 = y - sz / 2, y1 = y + sz / 2;
// draw the 3 line segments of the H
g.setColor(color);
g.drawLine((int) x0, (int) y, (int) x1, (int) y);
g.drawLine((int) x0, (int) y0, (int) x0, (int) y1);
g.drawLine((int) x1, (int) y0, (int) x1, (int) y1);
// recursively draw 4 half-size
// H-trees of order n-1
g.setColor(color);
draw(g, n - 1, sz / 2, x0, y0);
draw(g, n - 1, sz / 2, x0, y1);
draw(g, n - 1, sz / 2, x1, y0);
draw(g, n - 1, sz / 2, x1, y1);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g, 3, getWidth() / 2, getWidth() / 2, getHeight() / 2);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new HTree()::display);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With