Добавление JPanel в JScrollPane
У меня есть JPanel, в котором отрисовывается дерево и, очевидно, размер дерева может превышать размер экрана. Поэтому мне нужно добавить JPanel в JScrollPane, но скролл наотрез отказывается работать (даже глупое копирование рабочего кода для моей конкретной задачи не помог спасти ситуацию).
Класс App, в котором реализовано все окно
import javax.swing.*;
import java.awt.*;
public class App {
private JFrame frame;
private JTextField heightTextFiled;
private PaintPanel graphicPanel;
public App() {
createFrame();
initElements();
}
private void createFrame() {
frame = new JFrame("Моё страдание");
frame.setSize(1280, 720);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
}
public void show() {
frame.setVisible(true);
}
private void initElements() {
frame.setLayout(new BorderLayout());
Box leftPanel = createLeftPanel();
frame.add(leftPanel, BorderLayout.WEST);
graphicPanel = new PaintPanel();
JScrollPane scrollPanel = new JScrollPane(graphicPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
frame.add(scrollPanel);
}
private Box createLeftPanel() {
Box panel = Box.createVerticalBox();
JLabel title = new JLabel("Раскраска дерева");
Font font = new Font(Font.SANS_SERIF, Font.BOLD, 20);
title.setFont(font);
panel.add(title);
panel.add(Box.createVerticalStrut(40));
JLabel inputLabel = new JLabel("Введите высоту дерева");
inputLabel.setFont(font);
panel.add(inputLabel);
panel.add(Box.createVerticalStrut(10));
heightTextFiled = new JTextField();
heightTextFiled.setMaximumSize(new Dimension(500, 30));
heightTextFiled.setFont(new Font(Font.DIALOG_INPUT, Font.PLAIN, 20));
panel.add(heightTextFiled);
panel.add(Box.createVerticalStrut(10));
JButton buttonPaint = new JButton("Нарисовать");
buttonPaint.setMaximumSize(new Dimension(400, 50));
buttonPaint.setFont(font);
panel.add(buttonPaint);
buttonPaint.addActionListener(e -> {
if (!heightTextFiled.getText().equals("")) {
try {
int height = Integer.parseInt(heightTextFiled.getText());
if (height <= 0) {
throw new NumberFormatException();
}
graphicPanel.paintTree(height);
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null, "Invalid input", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
panel.add(Box.createVerticalGlue());
return panel;
}
}
Класс PaintPanel
import javax.swing.*;
import java.awt.*;
public class PaintPanel extends JPanel {
private ColoredBinaryTree tree = new ColoredBinaryTree(1);
public void paint(Graphics g) {
tree.colorize();
g.setColor(Color.lightGray);
g.fillRect(0, 0, getWidth(), getHeight());
PaintTree.point(tree, g);
}
public void paintTree(int height){
this.tree = new ColoredBinaryTree(height);
repaint();
}
}
Клас PaintTRee - отрисовка дерева
import java.awt.*;
class PaintTree {
private static final int TREE_NODE_WIDTH = 70,
TREE_NODE_HEIGHT = 30,
HORIZONTAL_INDENT = 10,
VERTICAL_INDENT = 50;
private static class NodeDrawResult {
int center;
int maxX;
int maxY;
NodeDrawResult(int center, int maxX, int maxY) {
this.center = center;
this.maxX = maxX;
this.maxY = maxY;
}
}
private static NodeDrawResult paint(ColoredBinaryTree.Node node, Graphics2D g2d, int x, int y) {
if (node == null) {
return null;
}
NodeDrawResult leftResult = paint(node.getLeft(), g2d, x, y + (TREE_NODE_HEIGHT + VERTICAL_INDENT));
int rightX = (leftResult != null) ? leftResult.maxX : x + (TREE_NODE_WIDTH + HORIZONTAL_INDENT) / 2;
NodeDrawResult rightResult = paint(node.getRight(), g2d, rightX, y + (TREE_NODE_HEIGHT + VERTICAL_INDENT));
int thisX;
if (leftResult == null) {
thisX = x;
} else if (rightResult == null) {
thisX = Math.max(x + (TREE_NODE_WIDTH + HORIZONTAL_INDENT) / 2, leftResult.center + HORIZONTAL_INDENT / 2);
} else {
thisX = (leftResult.center + rightResult.center) / 2 - TREE_NODE_WIDTH / 2;
}
g2d.setColor(node.getColor());
g2d.fillRect(thisX, y, TREE_NODE_WIDTH, TREE_NODE_HEIGHT);
g2d.setColor(Color.BLACK);
if (leftResult != null) {
g2d.drawLine(thisX + TREE_NODE_WIDTH / 2, y + TREE_NODE_HEIGHT, leftResult.center, y + TREE_NODE_HEIGHT + VERTICAL_INDENT);
}
if (rightResult != null) {
g2d.drawLine(thisX + TREE_NODE_WIDTH / 2, y + TREE_NODE_HEIGHT, rightResult.center, y + TREE_NODE_HEIGHT + VERTICAL_INDENT);
}
g2d.drawRect(thisX, y, TREE_NODE_WIDTH, TREE_NODE_HEIGHT);
int maxX = Math.max((leftResult == null) ? 0 : leftResult.maxX, (rightResult == null) ? 0 : rightResult.maxX);
int maxY = Math.max((leftResult == null) ? 0 : leftResult.maxY, (rightResult == null) ? 0 : rightResult.maxY);
return new NodeDrawResult(
thisX + TREE_NODE_WIDTH / 2,
Math.max(thisX + TREE_NODE_WIDTH + HORIZONTAL_INDENT, maxX),
Math.max(y + TREE_NODE_HEIGHT, maxY)
);
}
static void point(ColoredBinaryTree tree, Graphics gr) {
Graphics2D g2d = (Graphics2D) gr;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
NodeDrawResult rootResult = paint(tree.getRoot(), g2d, HORIZONTAL_INDENT, HORIZONTAL_INDENT);
new Point((rootResult == null) ? 0 : rootResult.maxX, (rootResult == null) ? 0 : rootResult.maxY + HORIZONTAL_INDENT);
}
}
Ответы (1 шт):
Автор решения: Олексій Моренець
→ Ссылка
После создания панели PaintPanel добавьте строку
graphicPanel.setPreferredSize(new Dimension(1000, 600));
Размеры сами придумайте какие вам нужны.
