我正在尝试创建一个面板来显示我们存储的一些“地图”的历史。最早的在顶部,其次是那些后来有时有额外信息的人。
迄今为止,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。