2013-10-11 3 views
7

私は(ちょうどそれらを埋める簡単なものを維持するために)グリッドを描画し、細胞内のものを描きたいです。 全体的には、一部のパネルサイズでしか動作しません。セルは、配置する場所(線が重なる部分)から約1ピクセル離れています。 TBH私は実際には自分自身で答えを見つけ出すのに十分な計算をしていないので、それについて私の謝罪をしています。計算セルサイズと(その間の線で)描く彼らは

とにかく、ここでのコードは次のとおりです。あなたはそれを実行した場合

public class Gui extends JFrame { 

public static void main(String[] args) { 
    new Gui().setVisible(true); 
} 

public Gui() { 
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    add(new JPanel() { 
     public static final int SIZE = 3; 
     /** Line thickness ratio to a block */ 
     public static final float LINE_THICKNESS = 0.1f; 

     /** @return the width of a block. */ 
     protected final int getBlockWidth() { 
      return getWidth()/SIZE; 
     } 

     /** @return the height of a block. */ 
     protected final int getBlockHeight() { 
      return getHeight()/SIZE; 
     } 

     /** @return the width of a cell. */ 
     protected final int getCellWidth() { 
      return (int) Math.ceil(getBlockWidth()*(1-LINE_THICKNESS)); 
     } 

     /** @return the height of a cell. */ 
     protected final int getCellHeight() { 
      return (int) Math.ceil(getBlockHeight()*(1-LINE_THICKNESS)); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      g.setColor(new Color(0, 0, 255, 100)); 
      int lineWidth = (int) (LINE_THICKNESS * getBlockWidth()); 
      int lineHeight = (int) (LINE_THICKNESS * getBlockHeight()); 
      for(int i = 0; i <= SIZE; i++) { 
       g.fillRect(i * getBlockWidth() - lineWidth/2, 0, lineWidth, getHeight()); 
       g.fillRect(0, i * getBlockHeight() - lineHeight/2, getWidth(), lineHeight); 
      } 
      g.setColor(new Color(255, 0, 0, 100)); 
      for(int i = 0; i < SIZE; i++) { 
       for(int j = 0; j < SIZE; j++) { 
        int x = j * getBlockWidth() + lineWidth/2; 
        int y = i * getBlockHeight() + lineHeight/2; 
        Graphics temp = g.create(x, y, getCellWidth(), getCellHeight()); 
        drawCell(temp, i, j); 
       } 
      } 
     } 

     private void drawCell(Graphics g, int i, int j) { 
      g.fillRect(0, 0, getCellWidth(), getCellHeight()); 
     } 
    }); 
    setLocation(new Point(500, 200)); 
    setSize(new Dimension(600, 600)); 
} 
} 

あなたはおそらく、私が何を意味するかわかります。私は言葉で良い説明を考えることができません。最初は、xとyに+ 1を加えなければならないと思ったので、私はその線の隣に描画したいと思っていましたが、これは(明らかに)問題をもう一方の側にシフトするだけです。 (30など)SIZE大きなでこれを実行する

は私にそれを脇にオープンスペースを与える別のバグを与えます。私は整数を使用しているのでこれがわかっている(または仮定している)が、それはあまりにも大きな問題ではない。しかし、(一般的に)より良いアプローチのヒントはいつでも歓迎します。

+0

+1。 – Dariusz

答えて

4

これを解決する方法はいくつかあります。私はあなたがあなたの質問をどのように頼っているかに基づいて、自分で問題を考え、解決したいと思っている人のひとりであると信じているので、コードを与えません。すべての

:まず最初にパネル全体に背景を描画して、線を描きます。ラインや描画が少し速くなることはありません。

第二の方法:描画の順序が重要です。バックグラウンドを最初に(重なっていても)安全に描画してから、境界線で上書きすることができます。

第3の方法:intを使用しないでください。フロートやダブルスを使用してください。あなたの悩みはすべて消えてしまいます。

第四の方法:余りを計算します。線が描かれているかどうかを予測することができます。それを予測し、適切に描く。

0

こんにちは、私はあなたと同じ問題を抱えていたが、私は実装ソリューションは、複数行のテキストを描画するためのJavaチュートリアルから入手したサンプルに触発され、テキストAPIを使用してセルにテキストを描画しています。良いSSCCE.orgと明確な、分かりやすい質問に対する明確な

http://java.sun.com/docs/books/tutorial/2d/text/drawmulstring.html

import java.awt.Component; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.font.FontRenderContext; 
import java.awt.font.LineBreakMeasurer; 
import java.awt.font.TextLayout; 
import java.text.AttributedCharacterIterator; 
import java.text.AttributedString; 
import java.text.BreakIterator; 

import javax.swing.JTable; 
import javax.swing.table.DefaultTableCellRenderer; 
import javax.swing.table.TableCellRenderer; 


public class MultilineTableCell 
    implements TableCellRenderer { 
    class CellArea extends DefaultTableCellRenderer { 
     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 
     private String text; 
     protected int rowIndex; 
     protected int columnIndex; 
     protected JTable table; 
     protected Font font; 
     private int paragraphStart,paragraphEnd; 
     private LineBreakMeasurer lineMeasurer; 

     public CellArea(String s, JTable tab, int row, int column,boolean isSelected) { 
      text = s; 
      rowIndex = row; 
      columnIndex = column; 
      table = tab; 
      font = table.getFont(); 
      if (isSelected) { 
       setForeground(table.getSelectionForeground()); 
       setBackground(table.getSelectionBackground()); 
      } 
     } 
     public void paintComponent(Graphics gr) { 
      super.paintComponent(gr); 
      if (text != null && !text.isEmpty()) { 
       Graphics2D g = (Graphics2D) gr; 
       if (lineMeasurer == null) { 
        AttributedCharacterIterator paragraph = new AttributedString(text).getIterator(); 
        paragraphStart = paragraph.getBeginIndex(); 
        paragraphEnd = paragraph.getEndIndex(); 
        FontRenderContext frc = g.getFontRenderContext(); 
        lineMeasurer = new LineBreakMeasurer(paragraph,BreakIterator.getWordInstance(), frc); 
       } 
       float breakWidth = (float)table.getColumnModel().getColumn(columnIndex).getWidth(); 
       float drawPosY = 0; 
       // Set position to the index of the first character in the paragraph. 
       lineMeasurer.setPosition(paragraphStart); 
       // Get lines until the entire paragraph has been displayed. 
       while (lineMeasurer.getPosition() < paragraphEnd) { 
        // Retrieve next layout. A cleverer program would also cache 
        // these layouts until the component is re-sized. 
        TextLayout layout = lineMeasurer.nextLayout(breakWidth); 
        // Compute pen x position. If the paragraph is right-to-left we 
        // will align the TextLayouts to the right edge of the panel. 
        // Note: this won't occur for the English text in this sample. 
        // Note: drawPosX is always where the LEFT of the text is placed. 
        float drawPosX = layout.isLeftToRight() 
         ? 0 : breakWidth - layout.getAdvance(); 
        // Move y-coordinate by the ascent of the layout. 
        drawPosY += layout.getAscent(); 
        // Draw the TextLayout at (drawPosX, drawPosY). 
        layout.draw(g, drawPosX, drawPosY); 
        // Move y-coordinate in preparation for next layout. 
        drawPosY += layout.getDescent() + layout.getLeading(); 
       } 
       table.setRowHeight(rowIndex,(int) drawPosY); 
      } 
     } 
    } 
    public Component getTableCellRendererComponent(
      JTable table, Object value,boolean isSelected, boolean hasFocus, int row,int column 
     ) 
    { 
     CellArea area = new CellArea(value.toString(),table,row,column,isSelected); 
     return area; 
    } 
} 
It resizes row heigth too but it does it well only when this renderer is used for a single column. 

And this is the way I used to invoke it for render my table. 

final int wordWrapColumnIndex = ...; 
myTable = new JTable() {  
    public TableCellRenderer getCellRenderer(int row, int column) { 
     if (column == wordWrapColumnIndex) { 
      return wordWrapRenderer; 
     } 
     else { 
      return super.getCellRenderer(row, column); 
     } 
    } 
}; 
関連する問題