2017-02-01 4 views
0

私はカードゲームをデザインしています。カードをパネルに描画(ペイント)したいと思います。私がペイントすると、画像のほんの一部しか表示されません。あなたは、ソートのこのスクリーンショットでそれを見ることができます。バッファリングされた画像の部分だけを描画する

Image of frame and small section of card

私はBufferedImageのためにラッパークラス(CardImage)を書いた:

import java.awt.image.BufferedImage; 
import java.io.File; 

import javax.imageio.ImageIO; 

public class CardImage { 

BufferedImage img = null; 

public CardImage() { 

} 

public BufferedImage setImage(Card c) { 
    try { 
     img = ImageIO.read(new File("/media/billy/HOME/workspace/Shithead/src/cards/" + toName(c))); 
    } catch(Exception e) { 
     System.out.println(e); 
    } 

    /* 
    int scale_factor = 8; 
    System.out.println(img.getHeight()); 
    Image dimg = img.getScaledInstance((int)img.getWidth()/scale_factor, (int)img.getHeight()/scale_factor, Image.SCALE_SMOOTH); 


    Graphics g = img.createGraphics(); 
    g.drawImage(dimg, 0, 0, null); 
    g.dispose(); 
    */ 


    return img; 
} 

public String toName(Card c) { 
    String tmp = c.toString().replaceAll(" ", "_"); 
    tmp = tmp.toLowerCase(); 
    tmp = tmp + ".png"; 
    return tmp; 
} 

} 

と欲しい商品がでのJPanelを拡張HandPanelを持っていますCardImage BufferedImageを描画する:

import java.awt.Graphics; 

import java.awt.image.BufferedImage; 


import javax.swing.JPanel; 


public class HandPanel extends JPanel { 

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 

    CardImage cardImage = new CardImage(); 

    Card card = new Card(2,2); 
    BufferedImage img = cardImage.setImage(card); 
    System.out.println(img.getHeight(null) + " " + img.getWidth(null)); 

    g.drawImage(img, 0, 0, null); 

} 


} 

そして私はHandPanelを格納するための別のクラスがあります。

import java.awt.Dimension; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class ShitGUI { 
public static void main(String[] args) { 
    ShitGUI gui = new ShitGUI(); 
} 


JFrame frame = new JFrame(); 
JPanel mainPanel = new JPanel(); 
public ShitGUI() { 
    mainPanel.setPreferredSize(new Dimension(500,500)); 

    HandPanel pan = new HandPanel(); 

    mainPanel.add(pan); 

    frame.add(mainPanel); 
    frame.pack(); 
    frame.setVisible(true); 
} 



} 

カードの画像はかなり大きいです(カード(2,2)を作成するのはハーツの2つで、正しくパスを取得することができます)。

何か助けていただければ幸いです。ありがとう!

N.B. dimgを含むセクションのコメントを外すと、赤と緑以外の縮尺の赤いカードが表示されます。私はスケーリングを理解していますが、なぜ私のアプローチが私に白黒イメージを与えているのか分かりません。

+3

paintComponent()メソッドにCard、CardImage、BufferedImageの新しいインスタンスを作成しないでください。このメソッドは何百回も呼び出される可能性があります。システムがリフレッシュする必要があると思うときはいつでも。 – FredK

+1

すぐに問題が起こる可能性が高いのは、レイアウトマネージャがレイアウトを許可するのに十分なサイズのヒントがHandPanelから返されていないことです。デフォルトサイズは0x0 – MadProgrammer

+3

* Shithead/src/cards *アプリケーションがビルドされても存在しません。また、ファイルを介して埋め込みリソースを参照する必要もありません。 – MadProgrammer

答えて

3

考えられる即時問題がHandPanelは、任意のサイズを提供していないという事実は、レイアウトマネージャがコンポーネントの最適なサイズを決定できるようにするヒント、0x0

のそれのデフォルト優先サイズにフォールバックされ、私は戻って、あなたを修正しますそれをもう少し再利用できるように少しコードを書いてください。

img = ImageIO.read(new File("/media/billy/HOME/workspace/Shithead/src/cards/" + toName(c)));は悪い考えです。

srcを含むパスは決して参照しないでください。srcは、アプリケーションの構築後は存在しません。埋め込みリソースをFileで参照するべきではなく、少なくともアプリケーションがビルドされていない場合は、Class#getResourceを使用する必要があります。それは事前に設定する必要がありますので、私はCardImageクラスを変更した

public class CardImage { 

    BufferedImage img = null; 

    public CardImage(Card card) { 
     setImage(card); 
    } 

    public BufferedImage getImage() { 
     return img; 
    } 

    public BufferedImage setImage(Card c) { 
     try { 
      //img = ImageIO.read(new File("/media/billy/HOME/workspace/Shithead/src/cards/" + toName(c))); 
      img = ImageIO.read(getClass().getResource("/cards/" + toName(c))); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 

     /* 
int scale_factor = 8; 
System.out.println(img.getHeight()); 
Image dimg = img.getScaledInstance((int)img.getWidth()/scale_factor, (int)img.getHeight()/scale_factor, Image.SCALE_SMOOTH); 


Graphics g = img.createGraphics(); 
g.drawImage(dimg, 0, 0, null); 
g.dispose(); 
     */ 
     return img; 
    } 

    public String toName(Card c) { 
     String tmp = c.toString().replaceAll(" ", "_"); 
     tmp = tmp.toLowerCase(); 
     tmp = tmp + ".png"; 
     return tmp; 
    } 

} 

が、これはあなたがイメージをキャッシュし、より効率的にそれを再利用することができます。また、を渡したときにCardImageの新しいインスタンスを生成する必要があるか、または以前にキャッシュされたバージョンを再利用する必要があるかどうかを判断できるような種類のファクトリを使用することを検討します。

繰り返しますが、私はHandPanelを変更した、それは今それにCardを渡す必要があり、それはそれは私がしたいのサイジングヒント

public class HandPanel extends JPanel { 

    CardImage cardImage; 

    public HandPanel(Card card) { 
     cardImage = new CardImage(card); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     BufferedImage img = cardImage.getImage(); 
     return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight()); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     BufferedImage img = cardImage.getImage(); 
     g.drawImage(img, 0, 0, this); 
    } 

} 

を生成するために使用するどのような情報についての決定を行うためにこれを使用していますいくつかの選択肢については、Perials of getScaledInstanceJava: maintaining aspect ratio of JPanel background imageをご覧ください。

+2

質問に新しい投票または投票が適用されていないため、質問は受け入れ可能でなければなりません。これは、ダウンボートが答えに直接関係していることを意味します。私はOPの質問に答える答えはどのようにしていますか?逃したものは何ですか?質問を改善するために何ができるでしょうか?あなたは別の答えを提示することに失敗したので、あなた自身が自分自身で解決する方法を知らないと仮定することができます。この時点で、私はあなたに個人的な問題があると仮定することができます。私は質問に答えて人々を助けようとしています:( – MadProgrammer

+0

ありがとう、これはうまくいった! – Billy

+0

@Billy Glad it help;) – MadProgrammer

関連する問題