保存した「地図」の履歴を表示するパネルを作成しようとしています。最も早いものを一番上に、その後に追加情報を追加したものを続けます。
これまでの 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;
}
}
これで、(0,0) に説明できない余分な領域が HistoryGraph に表示されることを除いて、かなりうまく機能します。何が起こっているかを確認するために HistoryNodes をオレンジ色にしました。これは最初のノードの上にあります。3 つのノードのみを作成し、3 つのノードのみを描画していることを確認しました。
ここに私が得るものの写真があります:
( http://jwooten37830.com/~woo/problems/HistoryGraph.JPG )
また、パネルのサイズをどのように設定すれば、外側のフレームが HistoryGraph よりも小さくなりますが、スクロール バーは表示されますか? 私のやり方では、常に「正しい」サイズです。グラフが長くなる場合は、外側のサイズを深さ 500 に制限したいのですが、内側は 1000 になる可能性があります。