2011-07-06 7 views
2

アプリケーションフレームにテーブルを追加してサイズを設定すると、テーブルからバッファリングされた画像を作成しようとしていますが、画像を正しく表示できますが、画像に変換すると私は、テーブルの外の最初の行とテーブルの外、ヘッダーなしの部分だけを見ることができます。jtableから画像変換が正しく行われない

コードテーブルは

table = new JTable(); 

    String[] table_header = null; 

    TextAreaRenderer textAreaRenderer = new TextAreaRenderer(); 
    table_model = new DefaultTableModel() { 

     @Override 
     public boolean isCellEditable(int row, int column) { 
      return false; 
     } 
    }; 

    table.setModel(table_model); 
    table.setSize(300, 700); 
    JScrollPane pane = new JScrollPane(table); 
    createTableDataSet(input1, input2, varient, headertype); 
    TableColumnModel cmodel = table.getColumnModel(); 
    table_header = obtainTableHeader(headertype); 
    for (int i = 0; i < table_header.length; i++) { 
     cmodel.getColumn(i).setCellRenderer(textAreaRenderer); 
    } 


    return table; 

画像を生成するためのコードで生成である:私は発見したことがあります。

JTableHeader header =table.getTableHeader(); 
    int w = Math.max(table.getWidth(), header.getWidth()); 
    int h = table.getHeight() + header.getHeight(); 
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2 = bi.createGraphics(); 
    header.paint(g2); 
    g2.translate(0, header.getHeight()); 
    table.paint(g2); 
    g2.dispose(); 
    try { 
     ImageIO.write(bi, "png", new File("year.png")); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

テーブルの画像はhere

アップデート1問題の原因テキストがセルにラップされるように、セルのサイズを大きくするために、次のコードスニペットを使用しています。問題の原因となっているコードを含めます。 プライベートfinal DefaultTableCellRendererレンダラー= new DefaultTableCellRenderer();

// Column heights are placed in this Map 
private final Map<JTable, Map<Object, Map<Object, Integer>>> tablecellSizes = new HashMap<JTable, Map<Object, Map<Object, Integer>>>(); 

/** 
* Creates a text area renderer. 
*/ 
public TextAreaRenderer() { 
    setLineWrap(true); 
    setWrapStyleWord(true); 
} 

/** 
* Returns the component used for drawing the cell. This method is 
* used to configure the renderer appropriately before drawing. 
* 
* @param table  - JTable object 
* @param value  - the value of the cell to be rendered. 
* @param isSelected - isSelected true if the cell is to be rendered with the selection highlighted; 
*     otherwise false. 
* @param hasFocus - if true, render cell appropriately. 
* @param row  - The row index of the cell being drawn. 
* @param column  - The column index of the cell being drawn. 
* @return - Returns the component used for drawing the cell. 
*/ 
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, 
               boolean hasFocus, int row, int column) { 
    // set the Font, Color, etc. 
    renderer.getTableCellRendererComponent(table, value, 
      isSelected, hasFocus, row, column); 
    setForeground(renderer.getForeground()); 
    setBackground(renderer.getBackground()); 
    setBorder(renderer.getBorder()); 
    setFont(renderer.getFont()); 
    setText(renderer.getText()); 

    TableColumnModel columnModel = table.getColumnModel(); 
    setSize(columnModel.getColumn(column).getWidth(), 0); 
    int height_wanted = (int) getPreferredSize().getHeight(); 
    addSize(table, row, column, height_wanted); 
    height_wanted = findTotalMaximumRowSize(table, row); 
    if (height_wanted != table.getRowHeight(row)) { 
     table.setRowHeight(row, height_wanted); 
    } 
    return this; 
} 

/** 
* @param table - JTable object 
* @param row - The row index of the cell being drawn. 
* @param column - The column index of the cell being drawn. 
* @param height - Row cell height as int value 
*    This method will add size to cell based on row and column number 
*/ 
private void addSize(JTable table, int row, int column, int height) { 
    Map<Object, Map<Object, Integer>> rowsMap = tablecellSizes.get(table); 
    if (rowsMap == null) { 
     tablecellSizes.put(table, rowsMap = new HashMap<Object, Map<Object, Integer>>()); 
    } 
    Map<Object, Integer> rowheightsMap = rowsMap.get(row); 
    if (rowheightsMap == null) { 
     rowsMap.put(row, rowheightsMap = new HashMap<Object, Integer>()); 
    } 
    rowheightsMap.put(column, height); 
} 

/** 
* Look through all columns and get the renderer. If it is 
* also a TextAreaRenderer, we look at the maximum height in 
* its hash table for this row. 
* 
* @param table -JTable object 
* @param row - The row index of the cell being drawn. 
* @return row maximum height as integer value 
*/ 
private int findTotalMaximumRowSize(JTable table, int row) { 
    int maximum_height = 0; 
    Enumeration<TableColumn> columns = table.getColumnModel().getColumns(); 
    while (columns.hasMoreElements()) { 
     TableColumn tc = columns.nextElement(); 
     TableCellRenderer cellRenderer = tc.getCellRenderer(); 
     if (cellRenderer instanceof TextAreaRenderer) { 
      TextAreaRenderer tar = (TextAreaRenderer) cellRenderer; 
      maximum_height = Math.max(maximum_height, 
        tar.findMaximumRowSize(table, row)); 
     } 
    } 
    return maximum_height; 
} 

/** 
* This will find the maximum row size 
* 
* @param table - JTable object 
* @param row - The row index of the cell being drawn. 
* @return row maximum height as integer value 
*/ 
private int findMaximumRowSize(JTable table, int row) { 
    Map<Object, Map<Object, Integer>> rows = tablecellSizes.get(table); 
    if (rows == null) return 0; 
    Map<Object, Integer> rowheights = rows.get(row); 
    if (rowheights == null) return 0; 
    int maximum_height = 0; 
    for (Map.Entry<Object, Integer> entry : rowheights.entrySet()) { 
     int cellHeight = entry.getValue(); 
     maximum_height = Math.max(maximum_height, cellHeight); 
    } 
    return maximum_height; 
} 

これが正しく表示されない細胞を引き起こしています。このコードを削除すると、テーブルはkleopatraのコードを含めて適切に生成されます。しかし、私はセル内の単語の折り返しの問題に固執しています。

おかげで、 バウィヤ

P.S.私は、テーブルオブジェクトが新しいJTable(行、フィールド)を使ってコード内で作成されたときに、画像を生成するために上記の同じコードを使用しました。

+0

table.getPreferredSize()。heightについてはどうですか?それは何を返すのですか? – SteeveDroz

+0

@Oltarus申し訳ありませんが、画像を直接作成しようとすると、テーブルの高さの値が取得されていて、データが正しく表示されない場合、アプリケーションフレームにテーブルを追加していたためです。テーブル – bhavs

+0

私はheader.getHeightが0を返していることを知っています、私はtable_modelにヘッダを追加して、table_modelをテーブルに追加します。このための回避策はありますか? – bhavs

答えて

1

いくつかの問題がありますここに。

  • 画像に描画するときは、paintAllを使用する必要があります。

  • テーブルの高さは、パックメソッドが呼び出されたときに設定されますが、テーブルに値が設定される前です。テーブルを生成した直後にイメージを作成する場合は、サイズが設定されていない可能性があります。フレームをパックする前にテーブルを作成する必要があります。これは、必要なときにサイズを確保できるようにする必要があります。

EDIT:あなたのコードの変更に伴い、私は(クレオパトラが示唆したように)スクロールペインを削除し、その後のprintAllを使用してお勧めします。ダブルバッファリングを使用できるため、画像にはペイントを使用しないでください。ヘッダーを表示するには、kleopatraが提供するコードを使用してサイズを設定する必要があります。ヘッダのサイズはテーブルとは独立しているため、テーブルのsetSizeを呼び出すことによってヘッダが変更されることはありません。

+0

私は塗料をprintAllに置き換えてチェックしましたが、私はまだこの問題に直面しています。はい、私はテーブルを作成した直後にイメージを作成していますが、私はアプリケーションフレームでそれを試しても、私は上記と同じイメージを取得しています。また、私はサーブレットによって表示されるテーブルオブジェクトを渡すので、JFrameまたはApplicationFrameを使用したくありません。 – bhavs

+0

@Russ Hayward 'JTable'は' JScrollPane'に追加し、 'ViewPort'について提案するべきですが、誰もOPの説明を注文しないでください – mKorbel

+0

@mKorbel random guesses again ;-) – kleopatra

2

基本的には、すべてのイメージにペイントしたいコンポーネント(この場合はテーブルとtableHeaderの両方)のサイズを設定する(プレフィックを使用する)必要があります。

ところで、JScrollPaneに追加することは、ペインが実現されている場合を除いて、(見てきたように)役に立ちません。ヘッダーの追加はaddNotifyのテーブルによって行われます。

JTable table = new JTable(new AncientSwingTeam()); 
    JTableHeader header =table.getTableHeader(); 
    table.setSize(table.getPreferredSize()); 
    header.setSize(header.getPreferredSize()); 
    int w = Math.max(table.getWidth(), header.getWidth()); 
    int h = table.getHeight() + header.getHeight(); 
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2 = bi.createGraphics(); 
    header.paint(g2); 
    g2.translate(0, header.getHeight()); 
    table.paint(g2); 
    g2.dispose(); 
    JLabel label = new JLabel(new ImageIcon(bi)); 
    showInFrame(label, "image of table"); 

編集:一般的なルールは決して史上かつてないレンダラーのgetXXRendererComponentで呼び出し元のテーブルを変更することですTextAreaRenderer

にコメント、パラメータとして与えられたテーブルは、厳密には、読み取り専用とみなされるべきです。ルールを壊すと、ここで見ているように、醜いループ(描画中に新しいrowHeightを設定すると新しい塗りつぶし要求を引き起こす)やアーティファクト(レンダラーが呼び出されたときには保証されないため、正しい行の高さが設定される場合があります)

代わりに外側の測定を行います。サイズを更新する可能性のある変更(モデルのf.i.)を検出すると、行を移動し、そのセルをすべて測定し、最大値に更新します。レンダラーからすべてのサイジングコードを抽出するだけです。

+0

簡単に、私の悪い私は再び単純なものを複雑に+1 – mKorbel

+0

@kleopatraこのコードスニペットに感謝していますテーブルヘッダーが表示されるようになりました。 – bhavs

0

私はこの場所の郵便番号Truncated JTable print outputを調べ、その場所に答えが含まれていれば、今は正常に動作しているようです。

ありがとうご協力ありがとうございます

+1

あなたの特定のケースではうまくいくかもしれませんが、その答えは間違っています。行う。ない。変化する。 Caller's.State.In.Renderer。ここで私の答えと私のコメントを参照してください – kleopatra

関連する問題