Я пытаюсь создать панель, которая показывает историю некоторых «карт», которые мы храним. Самое раннее в верхней части, а затем те, кто позже с дополнительной информацией время от времени.Проблемы с созданием панели с несколькими прямоугольниками
Основной код HistoryGraph до сих пор является:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/**
* @author woo Apr 29, 2013
*
* TODO
*
* freemind freemind.database.graphics
*/
public class HistoryGraph extends JPanel
{
public HistoryGraph()
{
super();
}
private List<HistoryNode> nodes = new ArrayList<HistoryNode>();
public void add(int startX, int startY, HistoryNode node)
{
node.setPosition(startX, startY);
nodes.add(node);
System.out.println("There are now " + nodes.size() + " nodes");
}
@Override
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g2.setColor(getBackground());
g2.fillRect(getX(), getY(), getWidth(), getHeight());
g2.setColor(Color.black);
int lastX = 0;
int lastY = 0;
int k = 0;
for (int i = 0; i < nodes.size(); i++)
{
HistoryNode node = nodes.get(i);
node.paintComponent(g2);
if (k > 0)
{
int x = node.getX() + node.getWidth()/2;
int y = node.getY();
g2.draw(new Line2D.Double(lastX, lastY, x, y));
}
lastX = node.getX() + node.getWidth()/2;
lastY = node.getY() + node.getHeight();
k++;
}
}
/**
* @param args
*/
public static void main(String[] args)
{
JFrame f = new JFrame("History of Map X");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
List<HistoryNode> nodes = new ArrayList<HistoryNode>();
HistoryGraph panel = new HistoryGraph();
panel.setBackground(Color.green);
nodes.add(new HistoryNode("2012-04-09,Version 1.2"));
nodes.add(new HistoryNode("2012-05-01,Release 1.1"));
nodes.add(new HistoryNode("2012-05-03,Release 1.2,Version 1.3,Test"));
int x = 50;
int y = 50;
int deltaY = 100;
for (int i = 0; i < nodes.size(); i++)
{
HistoryNode node = nodes.get(i);
node.setBackground(Color.orange);
panel.add(x, y, node);
y += deltaY;
}
И код HistoryNode является:
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @author woo Apr 29, 2013
*
* TODO
*
* freemind freemind.database.graphics
*/
public class HistoryNode extends JPanel
{
public HistoryNode(String text)
{
super();
this.text = text;
}
private double x;
private double y;
private double width;
private double height;
private String text;
private Double r;
@Override
public int getHeight()
{
return (int) height;
}
@Override
public int getWidth()
{
return (int) width;
}
@Override
public int getX()
{
return (int) x;
}
@Override
public int getY()
{
return (int) y;
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
FontRenderContext frc = g2d.getFontRenderContext();
Font font = g2d.getFont().deriveFont(12f);
g2d.setFont(font);
List<String> lines = new ArrayList<String>();
StringTokenizer tokenizer = new StringTokenizer(text, ",");
float sw = 0.0f;
float sh = 0.0f;
List<Float> depths = new ArrayList<Float>();
List<Float> widths = new ArrayList<Float>();
List<Float> descents = new ArrayList<Float>();
while (tokenizer.hasMoreTokens())
{
String s = tokenizer.nextToken();
float sb = (float) font.getStringBounds(s, frc).getWidth();
widths.add(sb);
if (sb > sw)
{
sw = sb;
}
lines.add(s);
LineMetrics lm = font.getLineMetrics(s, frc);
float depth = lm.getAscent() + lm.getDescent();
depths.add(depth);
if (depth > sh)
{
sh = depth;
}
descents.add(lm.getDescent());
}
width = sw + 10;
double padding = sh;
height = (descents.size()) * sh + padding;
r = new Rectangle2D.Double(x, y, width, height);
g2d.setColor(getBackground());
g2d.fillRect(getX(), getY(), getWidth(), getHeight());
g2d.setColor(Color.black);
g2d.draw(r);
float dy = 0.0f;
for (int i = 0; i < depths.size(); i++)
{
sh = depths.get(i);
sw = widths.get(i);
float descent = descents.get(i);
// scale text to fit and center in r
float sx = (float) (r.x + (r.width - sw)/2);
float sy = dy + (float) (r.y + sh + padding/2);
dy += sh;
String s = lines.get(i);
g2d.drawString(s, sx, sy);
}
}
/**
* @param startX
* @param startY
*/
public void setPosition(int startX, int startY)
{
x = startX;
y = startY;
}
}
Теперь все работает достаточно хорошо, кроме того, что я получаю дополнительное место на HistoryGraph, который я не могу объяснить, находится в (0,0). Я покрасил оранжевый цвет HistoryNodes, чтобы увидеть, что происходит, и он находится поверх первого узла. Я проверил, что я создаю только 3 узла и всего лишь 3 узла.
Вот картина того, что я получаю:
(http://jwooten37830.com/~woo/problems/HistoryGraph.JPG)
Кроме того, как я должен установить размер для панели так, что внешний кадр меньше HistoryGraph, но будет иметь свиток бары? То, как у меня это, всегда «правильный» размер. Если мой график будет длиннее, я хочу ограничить внешний размер, чтобы сказать 500 глубиной, но внутри может быть 1000.
Спасибо за помощь. Наверное, я что-то не понимаю.Я удалил все fillRect и добавил super.paintComponent, где он отсутствовал. Теперь я устанавливаю фон HistoryGraph в основной программе. Я получаю полный зеленый фон, а HistoryNodes также зеленый, а квадрат lightGray в верхнем левом углу - 0,0. Как это получается? То есть без fillRects, я получаю то же самое, что и раньше, без апельсиновых квадратов и одного светло-серого в верхнем левом углу. –
Я заметил, что он рисует правильно, но любое событие изменения размера приводит к появлению дополнительных фигур в верхнем левом углу, оставляя все остальное в одиночестве. Я прочитал источники, о которых вы упоминали, но ничего не видите о нескольких рисунках, как я делаю, и не вижу, где я отклонился. –
При чтении, все еще не понимая, как я получаю HistoryGraph для отображения его компонента HistoryNodes. Документация говорит, что я не должен сам называть paintComponent. Если я не использую метод PaintComponent в HistoryGraph, узлы не получаются! Если да, то они рисуются правильно, но изменение размера создает артефакты. Что я не правильно храню в HistoryNode или HistoryGraph для перерисовки? –