0

保存した「地図」の履歴を表示するパネルを作成しようとしています。最も早いものを一番上に、その後に追加情報を追加したものを続けます。

これまでの 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 になる可能性があります。

4

1 に答える 1