2011-02-05 26 views
1

JComponentを継承するクラスCellがあります。目標は、セルのグリッドが表示され、それぞれが独自のクリックイベントなどを処理できることです。基本的にフラットボタンです。JPanelはボタンを正しく表示しますが、カスタムJComponentは正しく表示されません

JPanelに複数のセルを追加すると、そのうちの1つだけが表示されます。同じコードを使用して、セルをボタンで置き換えると、すべてが期待通りに機能します。

私には何が欠けていますか?

メインメソッド

public static void main(String[] args){ 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.setSize(new Dimension(300,300)); 
    JPanel jp = new JPanel(); 
    jp.setLayout(new GridLayout(1, 3)); 
    if(true){//Use buttons instead of cells 
     jp.add(new JButton("Button 1")); 
     jp.add(new JButton("Button 2")); 
     jp.add(new JButton("Button 3")); 
    } 
    else{ //Use cells instead of buttons 
     Cell a = new Cell(10,0,0); 
     Cell b = new Cell(10,0,1); 
     Cell c = new Cell(10,0,2); 
     jp.add(a,0); 
     jp.add(b,1); 
     jp.add(c,2); 
    } 

    f.add(jp); 
    f.setVisible(true); 
    } 

セルクラス

public class Cell extends JComponent{ 
    private static int numCells=0; 
    private Dimension size; 
    private int dt; 
    private int dl; 
    private Color color; 
    public Cell(int size, int dt, int dl){ 
     numCells++; 
     Random rand = new Random(); 
     this.size = new Dimension(size,size); 
     this.dt = dt; 
     this.dl = dl; 
     this.color = new Color(//Random color, but only in one :r, g, or b 
      (numCells%3==0)?rand.nextInt(255):0, 
      (numCells%3==1)?rand.nextInt(255):0, 
      (numCells%3==2)?rand.nextInt(255):0 
    ); 
     this.setPreferredSize(this.size); 
     this.setMaximumSize(this.size); 
     this.setMinimumSize(this.size); 
     this.setBackground(color); 
     this.setVisible(true); 
     this.setOpaque(true); 
    } 
    public void amClicked(){ 
     JOptionPane.showMessageDialog(this.getParent(), 
       this.toString()); 
    } 

    public String toString(){ 
     return ""+dt+","+dl; 
    } 
    public void paintComponent(Graphics g){ 
       Graphics ng = g.create(); 
    try{ 
     super.paintComponent(ng); 
     ng.setColor(color); 
     System.out.println(String.format("%d,%d,%d,%d(%d,%d,%d)", 
       this.getX(), this.getY(), this.getWidth(), this.getHeight(), 
       this.color.getRed(),this.color.getGreen(),this.color.getBlue())); 
     ng.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight()); 
    } 
    finally{ 
     ng.dispose(); 
    } 
    } 


} 

答えて

1

3つのコンポーネントを追加していますが、1つだけ黒く塗りつぶしています。見るためにあなたの細胞に赤い線の境界線を追加します。

public Cell(int size, int dt, int dl) { 
    numCells++; 
    //.... code deleted 

    // !!this.color = new Color(Color.BLACK); // *** won't compile! 
    color = Color.black; 

    //.... code deleted 

    this.setOpaque(true); 
    setBorder(BorderFactory.createLineBorder(Color.red, 2)); // **** add this 
    } 

は編集:この行は、私には大雑把になります。

 g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight()); 

は、なぜあなたはここのgetXとのgetYを使用していますか?これらのメソッドは、セルではなくコンテナを基準にした位置情報を返しますが、コンテナではなくセルとの相対的な位置に描画するために使用しているため、黒い矩形が表示されているセルから引き出されます。あなたが欲しいものはありません。おそらく、どちらも代わりに0を使用する必要があります:

 g.fillRect(0, 0, this.getWidth(), this.getHeight()); 
+0

私はもともとランダムな色を持っていましたが、色は赤、緑、または青のみにしたいと考えていました。混乱を避けるために、投稿する前にそのコードを削除しました。私は "混乱を避ける"部分がうまく動作しないために戻しました。 – amccormack

+0

私はあなたのコードがうまくいかない理由を知ります。それはあなたのgetX()とgetY()の使用です。上記の私の答えを見てください。 –

+0

this.getX()とthis.getY()を0,0に変更すると、そのトリックが実行されました。 – amccormack

1

一つ、このコードでは明らかにバグがあなたがsetColorを(を経由して、Graphicsオブジェクトに変更を適用するという事実である)が、あなたはそれらをロールバックしません。

この

は明らかに Javadocsに記載されて:あなたは、サブクラスでこのメソッドをオーバーライドする場合は、グラフィックスに渡された永続的な変更を加えるべきではありません

一般的な解決策は、新しいグラフィックスはtry-finallyブロック内のコードをラップし、新しいグラフィックスは、finally節でGraphics.dispose()を経由してオブジェクトを配置し、あなたがGraphics.create()を経由して、パラメータとして取得するのオフオブジェクト出現することです。

関連する問題